Created
March 14, 2013 07:08
-
-
Save dingzhihu/5159425 to your computer and use it in GitHub Desktop.
WordGridView not a ViewGroup
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.meituan.android.widget; | |
import android.content.Context; | |
import android.content.res.Resources; | |
import android.content.res.TypedArray; | |
import android.graphics.Canvas; | |
import android.graphics.Paint; | |
import android.util.AttributeSet; | |
import android.view.View; | |
/** | |
* Created with IntelliJ IDEA. | |
* User: dingzhihu | |
* Date: 13-3-13 | |
* Time: 下午5:58 | |
*/ | |
public class WordGridView extends View { | |
private String[] mWords; | |
private OnWordClickListener mListener; | |
private int mNumRows, mNumColumns; | |
private float mCellPadding; | |
private int mLineWidth; | |
private Paint mPaintText; | |
private Paint mPaintLine; | |
private boolean mIsTouching; | |
private float mTouchX, mTouchY; | |
public WordGridView(Context context) { | |
this(context, null); | |
} | |
public WordGridView(Context context, AttributeSet attrs) { | |
this(context, attrs, R.attr.mtWordGridViewStyle); | |
} | |
public WordGridView(Context context, AttributeSet attrs, int defStyle) { | |
super(context, attrs, defStyle); | |
final Resources res = context.getResources(); | |
final int defaultNumRows = res.getInteger(R.integer.default_word_grid_view_num_rows); | |
final int defaultNumColumns = res.getColor(R.integer.default_word_grid_view_num_columns); | |
final float defaultCellPadding = res.getDimension(R.dimen.default_word_grid_view_cell_padding); | |
final int defaultLineColor = res.getColor(R.color.default_word_grid_view_line_color); | |
final int defaultTextColor = res.getColor(R.color.default_word_grid_view_text_color); | |
final float defaultTextSize = res.getDimension(R.dimen.default_word_grid_view_text_size); | |
final int defaultLineWidth = res.getInteger(R.integer.default_word_grid_view_line_width); | |
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.WordGridView, defStyle, 0); | |
mNumRows = a.getInteger(R.styleable.WordGridView_numRows, defaultNumRows); | |
mNumColumns = a.getInteger(R.styleable.WordGridView_numColumns, defaultNumColumns); | |
mCellPadding = a.getDimension(R.styleable.WordGridView_cellPadding, defaultCellPadding); | |
mPaintText = new Paint(); | |
mPaintText.setAntiAlias(true); | |
mPaintText.setTextSize(a.getDimension(R.styleable.WordGridView_android_textSize, | |
defaultTextSize)); | |
mPaintText.setColor(a.getColor(R.styleable.WordGridView_android_textColor, | |
defaultTextColor)); | |
mPaintLine = new Paint(); | |
mLineWidth = a.getInteger(R.styleable.WordGridView_lineWidth, defaultLineWidth); | |
mPaintLine.setStrokeWidth(mLineWidth); | |
mPaintLine.setColor(a.getColor(R.styleable.WordGridView_lineColor, defaultLineColor)); | |
a.recycle(); | |
} | |
public void setNumRows(int rows) { | |
if (mNumRows != rows) { | |
mNumRows = rows; | |
requestLayout(); | |
invalidate(); | |
} | |
} | |
public void setNumColumns(int columns) { | |
if (mNumColumns != columns) { | |
mNumColumns = columns; | |
invalidate(); | |
} | |
} | |
public void setOnWordClickListener(OnWordClickListener listener) { | |
mListener = listener; | |
} | |
public void setWords(String[] words) { | |
if (words == null) { | |
clearWords(); | |
return; | |
} | |
//remove useless words | |
final int cells = mNumRows * mNumColumns; | |
if (words.length > cells) { | |
mWords = new String[cells]; | |
System.arraycopy(words, 0, mWords, 0, cells); | |
} else { | |
mWords = words; | |
} | |
invalidate(); | |
} | |
public void clearWords() { | |
mWords = null; | |
invalidate(); | |
} | |
@Override | |
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { | |
final int measuredWidth = MeasureSpec.getSize(widthMeasureSpec); | |
final float textHeight = getTextHeight(); | |
float height = getPaddingTop(); | |
height += mLineWidth; //line | |
for (int i = 0; i < mNumRows; i++) { | |
height += textHeight; | |
height += mCellPadding * 2; | |
height += mLineWidth; //row line | |
} | |
height += getPaddingBottom(); | |
final int measuredHeight = (int) height; | |
setMeasuredDimension(measuredWidth, measuredHeight); | |
} | |
private float getTextHeight() { | |
final Paint.FontMetrics metrics = mPaintText.getFontMetrics(); | |
return metrics.descent - metrics.ascent; | |
} | |
@Override | |
protected void onDraw(Canvas canvas) { | |
final int measuredWidth = getMeasuredWidth(); | |
final int measuredHeight = getMeasuredHeight(); | |
final int paddingLeft = getPaddingLeft(); | |
final int paddingTop = getPaddingTop(); | |
final int paddingRight = getPaddingRight(); | |
final int paddingBottom = getPaddingBottom(); | |
// draw horizontal lines | |
final int horizontalLines = mNumRows + 1; | |
final float cellHeight = (measuredHeight - paddingTop - paddingBottom - horizontalLines * mLineWidth) / (mNumRows * 1.0f); | |
canvas.drawLine(paddingLeft, paddingTop, measuredWidth - paddingRight, paddingTop, mPaintLine); | |
float h = paddingTop; | |
h += mLineWidth; | |
for (int i = 0; i < mNumRows; i++) { | |
h += mCellPadding * 2; | |
h += getTextHeight(); | |
canvas.drawLine(paddingLeft, h, measuredWidth - paddingRight, h, mPaintLine); | |
h += mLineWidth; | |
} | |
// draw vertical lines | |
final int verticalLines = mNumColumns - 1; | |
final float cellWidth = (measuredWidth - paddingLeft - paddingRight - verticalLines * mLineWidth) / (mNumColumns * 1.0f); | |
float w = paddingLeft; | |
for (int i = 1; i <= verticalLines; i++) { | |
w += cellWidth; | |
canvas.drawLine(w, paddingTop, w, measuredHeight - paddingBottom, mPaintLine); | |
w += mLineWidth; | |
} | |
if (mWords == null) { | |
return; | |
} | |
// draw texts | |
for (int i = 0; i < mWords.length; i++) { | |
final String word = mWords[i]; | |
Paint.FontMetrics metrics = mPaintText.getFontMetrics(); | |
final float wordWidth = mPaintText.measureText(word); | |
int cellX = i % mNumColumns; | |
int cellY = i / mNumColumns; | |
float restrictedWordWidth = wordWidth; | |
if (wordWidth > cellWidth) { | |
restrictedWordWidth = cellWidth; | |
} | |
float x = paddingLeft + cellX * mLineWidth + cellX * cellWidth + (cellWidth - restrictedWordWidth) / 2; | |
float y = paddingTop + (1 + cellY) * mLineWidth + cellY * cellHeight + mCellPadding - metrics.ascent; | |
canvas.drawText(word, x, y, mPaintText); | |
} | |
} | |
public static interface OnWordClickListener { | |
void onClick(String word); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment