Android 实现数字九宫格软键盘

前言

一开始大概是这种

需求

组长说 要不搞一个自定义软键盘吧 数字搞大点 方便外卖员输入数字

我设置了输入EditText的输入格式为Number 还是不行

那就开搞吧

先来看下实现的效果图吧

实现效果GIF

实现代码

自定义View 一个NineNumericKeyboardView

/**

* Author by Lyu

* Date on 2021/5/26-19:55

* Description:九宫格数字软键盘

*/

public class NineNumericKeyboardView extends View {

/**

* 列

*/

private static final int TOTAL_COL = 3;

/**

* 行

*/

private static final int TOTAL_ROW = 4;

private Paint HuiseBgPaint, linePaint;

private Paint mTextPaint;

private int mViewWidth; // 键盘宽度

private int mViewHight; // 键盘高度

private float mCellWidth, mCellHight; // 单元格宽度、高度

private Row rows[] = new Row[TOTAL_ROW];

private Bitmap bitmap; // 删除按钮图片

private Paint mCutTextPaint;

//回调方法

public interface CallBack {

void clickNum(String num);// 回调点击的数字

void deleteNum();// 回调删除

}

private CallBack mCallBack;// 回调

public void setOnCallBack(CallBack callBack) {

mCallBack = callBack;

}

public NineNumericKeyboardView(Context context, AttributeSet attrs, int defStyle) {

super(context, attrs, defStyle);

init(context);

}

public NineNumericKeyboardView(Context context, AttributeSet attrs) {

super(context, attrs);

init(context);

}

public NineNumericKeyboardView(Context context) {

super(context);

init(context);

}

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

drawLine(canvas);

for (int i = 0; i < TOTAL_ROW; i++) {

if (rows[i] != null)

rows[i].drawCells(canvas);

}

}

/**

* 画6条直线

*

* @param canvas

*/

private void drawLine(Canvas canvas) {

canvas.drawLine(0, 0, mViewWidth, 0, linePaint);

canvas.drawLine(0, mCellHight, mViewWidth, mCellHight, linePaint);

canvas.drawLine(0, mCellHight * 2, mViewWidth, mCellHight * 2, linePaint);

canvas.drawLine(0, mCellHight * 3, mViewWidth, mCellHight * 3, linePaint);

canvas.drawLine(mCellWidth, 0, mCellWidth, mViewHight, linePaint);

canvas.drawLine(mCellWidth * 2, 0, mCellWidth * 2, mViewHight, linePaint);

}

/**

* 初始化画笔

*

* @param context

*/

private void init(Context context) {

mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

mCutTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

linePaint = new Paint(Paint.ANTI_ALIAS_FLAG);

linePaint.setTextSize(1.0f);

linePaint.setColor(0x90000000);

HuiseBgPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

HuiseBgPaint.setStyle(Paint.Style.FILL);

HuiseBgPaint.setColor(Color.parseColor("#e9e9e9"));

initDate();

}

private void initDate() {

fillDate();

}

@Override

protected void onSizeChanged(int w, int h, int oldw, int oldh) {

super.onSizeChanged(w, h, oldw, oldh);

mViewWidth = w;

mViewHight = h;

mCellWidth = mViewWidth / TOTAL_COL;

mCellHight = mViewHight / TOTAL_ROW;

mTextPaint.setTextSize(mCellHight / 3);

}

private Cell mClickCell = null;

private float mDownX;

private float mDownY;

/*

*

* 触摸事件为了确定点击位置的数字

*/

@Override

public boolean onTouchEvent(MotionEvent event) {

switch (event.getAction()) {

case MotionEvent.ACTION_DOWN:

mDownX = event.getX();

mDownY = event.getY();

int col = (int) (mDownX / mCellWidth);

int row = (int) (mDownY / mCellHight);

measureClickCell(col, row);

break;

case MotionEvent.ACTION_UP:

if (mClickCell != null) {

// 在抬起后把状态置为默认

rows[mClickCell.i].cells[mClickCell.j].state = State.DEFAULT_NUM;

mClickCell = null;

invalidate();

}

break;

}

return true;

}

/**

* 测量点击单元格

*

* @param col 列

* @param row 行

*/

private void measureClickCell(int col, int row) {

if (col >= TOTAL_COL || row >= TOTAL_ROW)

return;

if (rows[row] != null) {

mClickCell = new Cell(rows[row].cells[col].num, rows[row].cells[col].state, rows[row].cells[col].i,

rows[row].cells[col].j);

rows[row].cells[col].state = State.CLICK_NUM;

if ("-5".equals(rows[row].cells[col].num)) {

mCallBack.deleteNum();

} else {

mCallBack.clickNum(rows[row].cells[col].num);

}

invalidate();

}

}

/**

* 组 以一行为一组

*/

private class Row {

public int j;

Row(int j) {

this.j = j;

}

// 一行3个单元格

public Cell[] cells = new Cell[TOTAL_COL];

public void drawCells(Canvas canvas) {

for (int i = 0; i < cells.length; i++) {

if (cells[i] != null)

cells[i].drawSelf(canvas);

}

}

}

// 单元格

private class Cell {

public String num;

public State state;

/**

* i = 行 j = 列

*/

public int i;

public int j;

public Cell(String num, State state, int i, int j) {

super();

this.num = num;

this.state = state;

this.i = i;

this.j = j;

}

// 绘制一个单元格 如果颜色需要自定义可以修改

public void drawSelf(Canvas canvas) {

switch (state) {

case CLICK_NUM:

// 绘制点击效果灰色背景

canvas.drawRect((mCellWidth * j), (mCellHight * i),

(mCellWidth * (j + 1)), (mCellHight * (i + 1)), HuiseBgPaint);

break;

}

if ("-5".equals(num)) {

// 绘制删除图片

canvas.drawBitmap(bitmap, (float) (mCellWidth * 2.5 - bitmap.getWidth() / 2), (float) (mCellHight * 3.5 - bitmap.getHeight() / 2), HuiseBgPaint);

} else {

// 绘制数字

canvas.drawText(num, (float) ((j + 0.5) * mCellWidth - mTextPaint.measureText(num) / 2),

(float) ((i + 0.5) * mCellHight + mTextPaint.measureText(num, 0, 1) / 2),

mTextPaint);

}

}

}

/**

* cell的state

*/

private enum State {

DEFAULT_NUM, CLICK_NUM;

}

private List<String> numKeys = Arrays.asList("1", "2", "3", "4", "5", "6", "7", "8", "9", "0");

/**

* 填充数字

*/

private void fillDate() {

int postion = 0;

for (int i = 0; i < TOTAL_ROW; i++) {

rows[i] = new Row(i);

for (int j = 0; j < TOTAL_COL; j++) {

if (i == 3 && j == 0) {

rows[i].cells[j] = new Cell(".", State.DEFAULT_NUM, i, j);

continue;

} else if (i == 3 && j == 2) {

rows[i].cells[j] = new Cell("-5", State.DEFAULT_NUM, i, j);

continue;

} else {

rows[i].cells[j] = new Cell(numKeys.get(postion), State.DEFAULT_NUM, i, j);

postion++;

}

}

}

//这里是插入一张删除数字的图 一般是 X

bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.keyboard_delete);

}

}

使用方法

利用android自带的组件PopupWindow在指定页面的下方弹出即可 完成效果

在指定的View页面

//初始化键盘

private void initKeyboardView() {

// 设置不弹出系统键盘

etInputPickupCode.setInputType(InputType.TYPE_NULL);

// 自己监听EditText的点击事件弹出我们自定义的键盘

etInputPickupCode.setOnClickListener(view -> mPop.showAtLocation(llKey, Gravity.BOTTOM, 0, 0));

mPop = new PopupWindow();

mPopView = LayoutInflater.from(getApplicationContext()).inflate(R.layout.custom_keyboardview, null);

mPop.setContentView(mPopView);

mPop.setTouchable(true);

mPop.setFocusable(true);

mPop.setBackgroundDrawable(new ColorDrawable());

mPop.setWidth(ViewGroup.LayoutParams.MATCH_PARENT);

mPop.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);

mCustomKeyView = mPopView.findViewById(R.id.key_view);

// 设置回调,并进行文本的插入与删除

mCustomKeyView.setOnCallBack(this);

}

@Override

public void clickNum(String num) {

if (etInputPickupCode.getText().length() < 8) {

etInputPickupCode.append(num);

}

}

@Override

public void deleteNum() {

int last = etInputPickupCode.getText().length();

if (last > 0) {

//删除最后一位

etInputPickupCode.getText().delete(last - 1, last);

}

}

以上就是Android 实现数字九宫格软键盘的详细内容,更多关于Android 数字九宫格软键盘的资料请关注其它相关文章!

以上是 Android 实现数字九宫格软键盘 的全部内容, 来源链接: utcz.com/p/243607.html

回到顶部