android自定义金额输入键盘_android自定义view(自定义数字键盘)

本文详细介绍了如何在Android中实现一个自定义的金额输入键盘,包括布局设计、用户交互处理以及宫格和数字的绘制。通过计算每个宫格的位置并用canvas画出,实现了数字和删除键的功能。在onTouch事件中处理用户按下、弹起和取消操作,以回调数字或删除键信息。最后展示了实现效果,并提供了进一步优化的按压反馈效果。
摘要由CSDN通过智能技术生成

序言:在上周的项目中,需要做一个密码锁的功能,然后密码下面还得有键盘,就类似支付宝支付的时候那样:

AAffA0nNPuCLAAAAAElFTkSuQmCC

当然了,我们项目的需求简单点,纯数字的就可以了,然后上周就百度了自定义键盘,随便找了一个修改修改就用到项目中去了。

今天自己抽空写了一个自定义View的键盘控件,下面跟大家分享一下:思路:

1、布局:(1)、宫格:我们可以将这个布局看成是宫格布局,然后需要计算出每个小宫格在屏幕中的位置(坐标),然后再用canvas画出相应的矩形即可。

(2)、数字:我们需要计算出每个小宫格中的中心点位置(坐标),然后用canvas画数字上去,当然,我们知道最后一个是删除键,并不是数字,我们可以准备一张图片,将图片画到相应的位置。2、用户动作:(1)、按下:用户每一次按下的时候就表示这一次动作的开始,所以首先要将各种标识位(自定义所需要的标识位)设置成初始状态,然后需要记录按下的坐标,然后计算出用户按下的坐标与宫格中哪个点相对应,在记录相应数字。最后刷新布局

(2)、抬起:用户抬起的时候需要刷新布局,然后将按下过程中记录下的数字或者删除键信息通过接口的形式回调给用户,最后恢复标识位

(3)、取消:将所有的标识位恢复成初始状态。

好了,思路就讲到这里,我们来看看onDraw方法:protected void onDraw(Canvas canvas) {    if (!isInit) {

initData();

}

mPaint.setColor(Color.WHITE);    //画宫格

//第一排

canvas.drawRoundRect(10, mHeight / 2 + 10, 10 + mRectWidth, mHeight / 2 + 10 + mRectHeight, 10, 10, mPaint);

canvas.drawRoundRect(20 + mRectWidth, mHeight / 2 + 10, 20 + 2 * mRectWidth, mHeight / 2 + 10 + mRectHeight, 10, 10, mPaint);

canvas.drawRoundRect(30 + 2 * mRectWidth, mHeight / 2 + 10, 30 + 3 * mRectWidth, mHeight / 2 + 10 + mRectHeight, 10, 10, mPaint);    //第二排

canvas.drawRoundRect(10, mHeight / 2 + 20 + mRectHeight, 10 + mRectWidth, mHeight / 2 + 20 + 2 * mRectHeight, 10, 10, mPaint);

canvas.drawRoundRect(20 + mRectWidth, mHeight / 2 + 20 + mRectHeight, 20 + 2 * mRectWidth, mHeight / 2 + 20 + 2 * mRectHeight, 10, 10, mPaint);

canvas.drawRoundRect(30 + 2 * mRectWidth, mHeight / 2 + 20 + mRectHeight, 30 + 3 * mRectWidth, mHeight / 2 + 20 + 2 * mRectHeight, 10, 10, mPaint);    //第三排

canvas.drawRoundRect(10, mHeight / 2 + 30 + 2 * mRectHeight, 10 + mRectWidth, mHeight / 2 + 30 + 3 * mRectHeight, 10, 10, mPaint);

canvas.drawRoundRect(20 + mRectWidth, mHeight / 2 + 30 + 2 * mRectHeight, 20 + 2 * mRectWidth, mHeight / 2 + 30 + 3 * mRectHeight, 10, 10, mPaint);

canvas.drawRoundRect(30 + 2 * mRectWidth, mHeight / 2 + 30 + 2 * mRectHeight, 30 + 3 * mRectWidth, mHeight / 2 + 30 + 3 * mRectHeight, 10, 10, mPaint);    //第四排

mPaint.setColor(Color.GRAY);

canvas.drawRoundRect(10, mHeight / 2 + 40 + 3 * mRectHeight, 10 + mRectWidth, mHeight / 2 + 40 + 4 * mRectHeight, 10, 10, mPaint);

mPaint.setColor(Color.WHITE);

canvas.drawRoundRect(20 + mRectWidth, mHeight / 2 + 40 + 3 * mRectHeight, 20 + 2 * mRectWidth, mHeight / 2 + 40 + 4 * mRectHeight, 10, 10, mPaint);

mPaint.setColor(Color.GRAY);

canvas.drawRoundRect(30 + 2 * mRectWidth, mHeight / 2 + 40 + 3 * mRectHeight, 30 + 3 * mRectWidth, mHeight / 2 + 40 + 4 * mRectHeight, 10, 10, mPaint);

mPaint.setColor(Color.BLACK);

mPaint.setTextSize(60);// 设置字体大小

mPaint.setStrokeWidth(2);    //画数字

//第一排

canvas.drawText("1", xs[0], ys[0], mPaint);

canvas.drawText("2", xs[1], ys[0], mPaint);

canvas.drawText("3", xs[2], ys[0], mPaint);    //第二排

canvas.drawText("4", xs[0], ys[1], mPaint);

canvas.drawText("5", xs[1], ys[1], mPaint);

canvas.drawText("6", xs[2], ys[1], mPaint);    //第三排

canvas.drawText("7", xs[0], ys[2], mPaint);

canvas.drawText("8", xs[1], ys[2], mPaint);

canvas.drawText("9", xs[2], ys[2], mPaint);    //第四排

canvas.drawText(".", xs[0], ys[3], mPaint);

canvas.drawText("0", xs[1], ys[3], mPaint);

canvas.drawBitmap(mBpDelete, xs[2] - mWidthOfBp / 2 + 10, ys[3] - mHeightOfBp / 2 - 10, mPaint);

}注:上面的坐标需要我们自己算出,耐心一点,很容易算的,你只需要搞清楚在Android中屏幕是怎样的坐标系就可以了。坐标算出来之后,我们先画宫格,然后再画数字和删除键,这里有人要问了,我可以先画数字吗,NO,因为当你画完数字之后再画宫格你会发现数字不见了,为什么呢?被你的宫格挡住了 >_

好了,画好之后,我们来看看效果怎么样:

AAffA0nNPuCLAAAAAElFTkSuQmCC

样式出来了哈!但是设计的没那么好看,大家将就看一看哈>_<

然后我们需要重写onTouch事件,在里面判断用户的一些行为:switch (event.getAction()) {        case MotionEvent.ACTION_DOWN: //按下

//恢复默认值

setDefault();            /**

*判断按下的点在哪个宫格中

*/

invalidate();//刷新界面

return true;        case MotionEvent.ACTION_UP: //弹起

invalidate();//刷新界面

/**

*一次按下结束,返回点击的数字

*/

//恢复默认

setDefault();            return true;        case MotionEvent.ACTION_CANCEL:  //取消

//恢复默认值

setDefault();            return true;

}

如上面伪代码所示,我写了一个方法来判断按下的点在哪个宫格中:private void handleDown(float x, float y) {

if (y 

}    if (x >= 10 && x <= 10 + mRectWidth) {   //第一列        clickX = xs[0];

if (y >= mHeight / 2 + 10 && y <= mHeight / 2 + 10 + mRectHeight) {  //第一排(1)            clickY = ys[0];

x1 = 10;

y1 = mHeight / 2 + 10;            x2 = 10 + mRectWidth;            y2 = mHeight / 2 + 10 + mRectHeight;            number = "1";

} else if (y >= mHeight / 2 + 20 + mRectHeight && y <= mHeight / 2 + 20 + 2 * mRectHeight) {  //第二排(4)            x1 = 10;

y1 = mHeight / 2 + 20 + mRectHeight;            x2 = 10 + mRectWidth;            y2 = mHeight / 2 + 20 + 2 * mRectHeight;            clickY = ys[1];

number = "4";

} else if (y >= mHeight / 2 + 30 + 2 * mRectHeight && y <= mHeight / 2 + 30 + 3 * mRectHeight) {  //第三排(7)            x1 = 10;

y1 = mHeight / 2 + 30 + 2 * mRectHeight;            x2 = 10 + mRectWidth;            y2 = mHeight / 2 + 30 + 3 * mRectHeight;            clickY = ys[2];

number = "7";

} else if (y >= mHeight / 2 + 40 + 3 * mRectHeight && y <= mHeight / 2 + 40 + 4 * mRectHeight) { //第四排(0)            x1 = 10;

y1 = mHeight / 2 + 40 + 3 * mRectHeight;            x2 = 10 + mRectWidth;            y2 = mHeight / 2 + 40 + 4 * mRectHeight;            clickY = ys[3];

number = ".";

}

} else if (x >= 20 + mRectWidth && x <= 20 + 2 * mRectWidth) {  //第二列        clickX = xs[1];

if (y >= mHeight / 2 + 10 && y <= mHeight / 2 + 10 + mRectHeight) {  //第一排(2)            x1 = 20 + mRectWidth;            y1 = mHeight / 2 + 10;            x2 = 20 + 2 * mRectWidth;            y2 = mHeight / 2 + 10 + mRectHeight;            clickY = ys[0];

number = "2";

} else if (y >= mHeight / 2 + 20 + mRectHeight && y <= mHeight / 2 + 20 + 2 * mRectHeight) {  //第二排(5)            x1 = 20 + mRectWidth;            y1 = mHeight / 2 + 20 + mRectHeight;            x2 = 20 + 2 * mRectWidth;            y2 = mHeight / 2 + 20 + 2 * mRectHeight;            clickY = ys[1];

number = "5";

} else if (y >= mHeight / 2 + 30 + 2 * mRectHeight && y <= mHeight / 2 + 30 + 3 * mRectHeight) {  //第三排(8)            x1 = 20 + mRectWidth;            y1 = mHeight / 2 + 30 + 2 * mRectHeight;            x2 = 20 + 2 * mRectWidth;            y2 = mHeight / 2 + 30 + 3 * mRectHeight;            clickY = ys[2];

number = "8";

} else if (y >= mHeight / 2 + 40 + 3 * mRectHeight && y <= mHeight / 2 + 40 + 4 * mRectHeight) { //第四排(0)            x1 = 20 + mRectWidth;            y1 = mHeight / 2 + 40 + 3 * mRectHeight;            x2 = 20 + 2 * mRectWidth;            y2 = mHeight / 2 + 40 + 4 * mRectHeight;            clickY = ys[3];

number = "0";

}

} else if (x >= 30 + 2 * mRectWidth && x <= 30 + 3 * mRectWidth) {   //第三列        clickX = xs[2];

if (y >= mHeight / 2 + 10 && y <= mHeight / 2 + 10 + mRectHeight) {  //第一排(3)            x1 = 30 + 2 * mRectWidth;            y1 = mHeight / 2 + 10;            x2 = 30 + 3 * mRectWidth;            y2 = mHeight / 2 + 10 + mRectHeight;            clickY = ys[0];

number = "3";

} else if (y >= mHeight / 2 + 20 + mRectHeight && y <= mHeight / 2 + 20 + 2 * mRectHeight) {  //第二排(6)            x1 = 30 + 2 * mRectWidth;            y1 = mHeight / 2 + 20 + mRectHeight;            x2 = 30 + 3 * mRectWidth;            y2 = mHeight / 2 + 20 + 2 * mRectHeight;            clickY = ys[1];

number = "6";

} else if (y >= mHeight / 2 + 30 + 2 * mRectHeight && y <= mHeight / 2 + 30 + 3 * mRectHeight) {  //第三排(9)            x1 = 30 + 2 * mRectWidth;            y1 = mHeight / 2 + 30 + 2 * mRectHeight;            x2 = 30 + 3 * mRectWidth;            y2 = mHeight / 2 + 30 + 3 * mRectHeight;            clickY = ys[2];

number = "9";

} else if (y >= mHeight / 2 + 40 + 3 * mRectHeight && y <= mHeight / 2 + 40 + 4 * mRectHeight) { //第四排(删除键)            x1 = 30 + 2 * mRectWidth;            y1 = mHeight / 2 + 40 + 3 * mRectHeight;            x2 = 30 + 3 * mRectWidth;            y2 = mHeight / 2 + 40 + 4 * mRectHeight;            clickY = ys[3];

number = "delete";

}

}

}注:这个方法跟你之前计算出的宫格坐标有关系,所以一定不要计算错误

至此,我们写的差不多了,然后就是要提供一个接口,对外开放,方便用的时候调用,获取到数字或者其他信息:public interface OnNumberClickListener {    //回调点击的数字

public void onNumberReturn(String number);    //删除键的回调

public void onNumberDelete();

}

在onTouch事件中使用:case MotionEvent.ACTION_UP: //弹起

invalidate();//刷新界面

//一次按下结束,返回点击的数字

if (onNumberClickListener != null) {                if (number != null) {                    if (number.equals("delete")) {

onNumberClickListener.onNumberDelete();

} else {

onNumberClickListener.onNumberReturn(number);

}

}

}            //恢复默认

setDefault();            return true;

然后我们来看一下效果怎么样吧!

AAffA0nNPuCLAAAAAElFTkSuQmCC

功能也实现了,可是强迫症很强的我看着很不舒服,不知道你们有没有,好歹这也是一个键盘吧!按下弹起的效果都没有(没有改变按下的背景),在这里我们设置一个标志位,按下弹起刷新界面就可以了。在onTouch事件中改变该标识位的值,然后在onDraw方法中判断该标识位即可:

onTouch方法中增加:case MotionEvent.ACTION_DOWN: //按下    type=0;case MotionEvent.ACTION_UP: //弹起    type=1;

onDraw方法增加:if (clickX > 0 && clickY > 0) {        if (type == 0) {  //按下刷新

if (number.equals("delete")) {

mPaint.setColor(Color.WHITE);

canvas.drawRoundRect(x1, y1, x2, y2, 10, 10, mPaint);

canvas.drawBitmap(mBpDelete, xs[2] - mWidthOfBp / 2 + 10, ys[3] - mHeightOfBp / 2 - 10, mPaint);

} else {                if (number.equals(".")) {

mPaint.setColor(Color.WHITE);

} else {

mPaint.setColor(Color.GRAY);

}

canvas.drawRoundRect(x1, y1, x2, y2, 10, 10, mPaint);

mPaint.setColor(Color.BLACK);

mPaint.setTextSize(60);// 设置字体大小

mPaint.setStrokeWidth(2);

canvas.drawText(number, clickX, clickY, mPaint);

}

} else if (type == 1) {  //抬起刷新

if (number.equals("delete")) {

mPaint.setColor(Color.GRAY);

canvas.drawRoundRect(x1, y1, x2, y2, 10, 10, mPaint);

canvas.drawBitmap(mBpDelete, xs[2] - mWidthOfBp / 2 + 10, ys[3] - mHeightOfBp / 2 - 10, mPaint);

} else {                if (number.equals(".")) {

mPaint.setColor(Color.GRAY);

} else {

mPaint.setColor(Color.WHITE);

}

canvas.drawRoundRect(x1, y1, x2, y2, 10, 10, mPaint);

mPaint.setColor(Color.BLACK);

mPaint.setTextSize(60);// 设置字体大小

mPaint.setStrokeWidth(2);

canvas.drawText(number, clickX, clickY, mPaint);

}            //绘制完成后,重置

clickX = 0;

clickY = 0;

}

}

接下来再来看看效果吧:

AAffA0nNPuCLAAAAAElFTkSuQmCC

现在看起来舒服多了,_

代码我已经上传到Github传送门,

作者:24K纯帅豆

链接:https://www.jianshu.com/p/eb7b946a20f8

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值