常见的安全键盘,随机排列数字,点击状态的回调。
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import router.future.com.testrouter.R;
/**
* @author luchao
* @time 18/1/26 上午10:30
*/
public class SafeKeyboard extends View {
private ItemClickListener itemClickListener;
private Paint numberPaint;
private Paint mBgPaint;
private Paint mLinePaint;
private int mTextSize;
private List<String> numberData = new ArrayList<String>() {{
add("1");
add("2");
add("3");
add("4");
add("5");
add("6");
add("7");
add("8");
add("9");
add("0");
}};
private List<RectF> squareList = new ArrayList<>();
private static final String SPACE = "q";
private static final String BACK = "d";
private float squareWidth;
private float squareHeight;
private int columnCount = 3;
private int rowCount;
private int pressIndex = -1;
public SafeKeyboard(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray mTypedArray = context.obtainStyledAttributes(attrs, R.styleable.RulerWheel);
try {
mTextSize = mTypedArray.getDimensionPixelSize(R.styleable.RulerWheel_text_Size, 80);
} finally {
mTypedArray.recycle();
}
init();
}
private void init() {
numberPaint = new Paint();
numberPaint.setColor(Color.BLACK);
numberPaint.setTextSize(mTextSize);
mBgPaint = new Paint();
mBgPaint.setColor(Color.RED);
mBgPaint.setStyle(Paint.Style.FILL);
mBgPaint.setAntiAlias(true);
mLinePaint = new Paint();
mLinePaint.setColor(Color.BLACK);
shuffleData();
}
/**
* 组装数据,这里用到一些小技巧.
*/
public void shuffleData() {
Collections.shuffle(numberData);
numberData.add(9, SPACE);
numberData.add(11, BACK);
rowCount = getRowCount();
}
/**
* 控制点击背景并返回数据
* @param event
* @return
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
for(int i = 0; i < squareList.size(); i++) {
RectF rectF = squareList.get(i);
if(rectF.contains(x, y)) {
pressIndex = i;
postInvalidate();
break;
}
}
break;
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
//返回点击后的数据
if(itemClickListener != null) {
itemClickListener.click(numberData.get(pressIndex));
}
pressIndex = -1;
postInvalidate();
break;
}
return true;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
squareWidth = (float) MeasureSpec.getSize(widthMeasureSpec) / 3f;
squareHeight = (float) MeasureSpec.getSize(heightMeasureSpec) / 4f;
}
/**
* @param canvas
*/
@Override
protected void onDraw(Canvas canvas) {
squareList.clear();
//画按钮的背景和文字
float topMargin = 0;
float leftMargin = 0;
for (int i = 0; i < numberData.size(); i++) {
if (isNewline(i)) {
topMargin += squareHeight;
leftMargin = 0;
}
if(i == pressIndex) {
mBgPaint.setColor(Color.GREEN);
} else {
mBgPaint.setColor(Color.RED);
}
String str = numberData.get(i);
RectF rectF = new RectF(leftMargin, topMargin, leftMargin + squareWidth, topMargin + squareHeight);
squareList.add(rectF);
canvas.drawRect(rectF, mBgPaint);
//这段代码根据现实情况修改
if(str.equals("q")) {
str = "";
} else if(str.equals("d")) {
str = "delete";
}
canvas.drawText(str, rectF.left + (squareWidth - getTextWidth(numberPaint, str)) / 2, getBaseLineY(numberPaint, rectF), numberPaint);
leftMargin += squareWidth;
}
//画分割线横着的
int lineTopMargin = 0;
for (int i = 0; i < rowCount - 1; i++) {
canvas.drawLine(0, lineTopMargin + squareHeight, getMeasuredWidth(), lineTopMargin + squareHeight, mLinePaint);
lineTopMargin += squareHeight;
}
//画分割线竖着的
int lineLeftMargin = 0;
for (int i = 0; i < rowCount - 1; i++) {
canvas.drawLine(lineLeftMargin + squareWidth, 0, lineLeftMargin + squareWidth, getMeasuredHeight(), mLinePaint);
lineLeftMargin += squareWidth;
}
}
private boolean isNewline(int index) {
if (index != 0 && index % columnCount == 0) {
return true;
}
return false;
}
private int getRowCount() {
int num = numberData.size() / columnCount;
if (squareList.size() % columnCount > 0) {
return num + 1;
}
return num;
}
private int getBaseLineY(Paint textPaint, RectF rectF) {
Paint.FontMetrics fontMetrics = textPaint.getFontMetrics();
float top = fontMetrics.top;//为基线到字体上边框的距离,即上图中的top
float bottom = fontMetrics.bottom;//为基线到字体下边框的距离,即上图中的bottom
int baseLineY = (int) (rectF.centerY() - top/2 - bottom/2);//基线中间点的y轴计算公式
return baseLineY;
}
private int getTextHeight(Paint paint) {
Paint.FontMetrics fm = paint.getFontMetrics();
return (int) Math.ceil(fm.descent - fm.ascent);
}
public int getTextWidth(Paint paint, String str) {
int iRet = 0;
if (str != null && str.length() > 0) {
int len = str.length();
float[] widths = new float[len];
paint.getTextWidths(str, widths);
for (int j = 0; j < len; j++) {
iRet += (int) Math.ceil(widths[j]);
}
}
return iRet;
}
public void setItemClickListener(ItemClickListener itemClickListener) {
this.itemClickListener = itemClickListener;
}
public interface ItemClickListener {
void click(String str);
}
}
网友评论