Android 自定义软键盘实现 数字九宫格

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

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

那就开搞吧

先来看下实现的效果图吧

实现效果GIF

g

实现代码

自定义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);

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
img

最后

文章不易,如果大家喜欢这篇文章,或者对你有帮助希望大家多多点赞转发关注哦。文章会持续更新的。绝对干货!!!

  • Android进阶学习全套手册
    关于实战,我想每一个做开发的都有话要说,对于小白而言,缺乏实战经验是通病,那么除了在实际工作过程当中,我们如何去更了解实战方面的内容呢?实际上,我们很有必要去看一些实战相关的电子书。目前,我手头上整理到的电子书还算比较全面,HTTP、自定义view、c++、MVP、Android源码设计模式、Android开发艺术探索、Java并发编程的艺术、Android基于Glide的二次封装、Android内存优化——常见内存泄露及优化方案、.Java编程思想 (第4版)等高级技术都囊括其中。

  • Android高级架构师进阶知识体系图
    关于视频这块,我也是自己搜集了一些,都按照Android学习路线做了一个分类。按照Android学习路线一共有八个模块,其中视频都有对应,就是为了帮助大家系统的学习。接下来看一下导图和对应系统视频吧!!!

  • Android对标阿里P7学习视频

  • BATJ大厂Android高频面试题
    这个题库内容是比较多的,除了一些流行的热门技术面试题,如Kotlin,数据库,Java虚拟机面试题,数组,Framework ,混合跨平台开发,等

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
img
ATJ大厂Android高频面试题**
这个题库内容是比较多的,除了一些流行的热门技术面试题,如Kotlin,数据库,Java虚拟机面试题,数组,Framework ,混合跨平台开发,等
[外链图片转存中…(img-BgM4rcX7-1712825247470)]

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
[外链图片转存中…(img-TKEaZlc8-1712825247470)]

  • 21
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值