Android 實現(xiàn)數(shù)字九宮格軟鍵盤
前言
一開始大概是這種

需求
組長說 要不搞一個自定義軟鍵盤吧 數(shù)字搞大點 方便外賣員輸入數(shù)字
我設置了輸入EditText的輸入格式為Number 還是不行
那就開搞吧
先來看下實現(xiàn)的效果圖吧
實現(xiàn)效果GIF

實現(xiàn)代碼
自定義View 一個NineNumericKeyboardView
/**
* Author by Lyu
* Date on 2021/5/26-19:55
* Description:九宮格數(shù)字軟鍵盤
*/
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);// 回調點擊的數(shù)字
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;
/*
*
* 觸摸事件為了確定點擊位置的數(shù)字
*/
@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) {
// 在抬起后把狀態(tài)置為默認
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 {
// 繪制數(shù)字
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");
/**
* 填充數(shù)字
*/
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++;
}
}
}
//這里是插入一張刪除數(shù)字的圖 一般是 X
bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.keyboard_delete);
}
}
使用方法
利用android自帶的組件PopupWindow在指定頁面的下方彈出即可 完成效果
在指定的View頁面
//初始化鍵盤
private void initKeyboardView() {
// 設置不彈出系統(tǒng)鍵盤
etInputPickupCode.setInputType(InputType.TYPE_NULL);
// 自己監(jiān)聽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 實現(xiàn)數(shù)字九宮格軟鍵盤的詳細內容,更多關于Android 數(shù)字九宮格軟鍵盤的資料請關注腳本之家其它相關文章!
相關文章
Android開發(fā)實現(xiàn)瀏覽器全屏顯示功能
這篇文章主要介紹了Android開發(fā)實現(xiàn)瀏覽器全屏顯示功能,涉及Android布局修改及相關屬性動態(tài)設置操作技巧,需要的朋友可以參考下2017-09-09
Android工具類ImgUtil選擇相機和系統(tǒng)相冊
這篇文章主要為大家詳細介紹了Android工具類ImgUtil選擇相機和系統(tǒng)相冊,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-10-10
Android中Service與Activity之間通信的幾種方式
本篇文章主要介紹了Android中Service與Activity之間通信的幾種方式,Activity主要負責前臺頁面的展示,Service主要負責需要長期運行的任務,具有一定的參考價值,有興趣的可以了解一下。2017-02-02
Android開發(fā)實現(xiàn)的Intent跳轉工具類實例
這篇文章主要介紹了Android開發(fā)實現(xiàn)的Intent跳轉工具類,簡單描述了Intent組件的功能并結合實例形式給出了頁面跳轉、拍照、圖片調用等相關操作技巧,需要的朋友可以參考下2017-11-11
Android應用開發(fā)中數(shù)據(jù)的保存方式總結
這篇文章主要介紹了Android應用開發(fā)中數(shù)據(jù)的保存方式總結,包括對ROM、SD卡、SharedPreference這三種方式實現(xiàn)的核心代碼的精選,需要的朋友可以參考下2016-02-02

