Skip to content

Instantly share code, notes, and snippets.

@dingzhihu
Created March 14, 2013 07:08
Show Gist options
  • Save dingzhihu/5159425 to your computer and use it in GitHub Desktop.
Save dingzhihu/5159425 to your computer and use it in GitHub Desktop.
WordGridView not a ViewGroup
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