前言

最近需要做一个自定义的数字键盘,开始使用了下系统自带的KeyBoardView,但是发现UI效果不是很理想,最后还是自己画一个自定义键盘,这样在UI方面更加方便。先看效果图吧:

思路

1.键盘4行*3列的布局分为12个单元格,6条直线分隔单元格。根据单元格宽高确定数字位置。
2.点击效果根据用户按下和抬起动作做不同标记。

思路说的有点模糊,直接看代码吧,代码里的注释很详细:

实现

1:自定义view–CustomNumKeyView

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;import java.util.Arrays;
import java.util.Collections;
import java.util.List;public class CustomNumKeyView 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; // 删除按钮图片public interface CallBack {void clickNum(String num);// 回调点击的数字void deleteNum();// 回调删除}private CallBack mCallBack;// 回调public void setOnCallBack(CallBack callBack) {mCallBack = callBack;}public CustomNumKeyView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);init(context);}public CustomNumKeyView(Context context, AttributeSet attrs) {super(context, attrs);init(context);}public CustomNumKeyView(Context context) {super(context);init(context);}@Overrideprotected 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 canvas*/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();}@Overrideprotected 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;/*** 触摸事件为了确定点击位置的数字*/@Overridepublic 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((float) (mCellWidth * j), (float) (mCellHight * i),(float) (mCellWidth * (j + 1)), (float) (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++;}}}bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.icon_cancel);}/*** 随机键盘* @param isRandom*/public void setRandomKeyBoard(boolean isRandom) {if (isRandom) {Collections.shuffle(numKeys);initDate();invalidate();}}}

这里主要就是要注意单元格的绘制坐标,代码应该很好理解。

键盘已经画好,接下来就是使用了:

2.MainActivity

package net.yangming.numkeyboard;import android.graphics.drawable.ColorDrawable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.InputType;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.PopupWindow;public class MainActivity extends AppCompatActivity implements NumKeyView.OnKeyPressListener, CustomNumKeyView.CallBack {private EditText mEditText;private NumKeyView mKeyView;private CustomNumKeyView mCustomKeyView;private LinearLayout mLinearlayout;private PopupWindow mPop;private View mPopView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initView();}private void initView() {mLinearlayout = (LinearLayout) findViewById(R.id.linear);mEditText = (EditText) findViewById(R.id.edit);// 设置不弹出系统键盘mEditText.setInputType(InputType.TYPE_NULL);// 自己监听EditText的点击事件弹出我们自定义的键盘mEditText.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {mPop.showAtLocation(mLinearlayout, Gravity.BOTTOM, 0, 0);}});mPop = new PopupWindow();
//        mCustomKeyView=new CustomNumKeyView(this);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 = (CustomNumKeyView) mPopView.findViewById(R.id.keyboardview);// 设置回调,并进行文本的插入与删除mCustomKeyView.setOnCallBack(this);}public void OnButtonClick(View view) {switch (view.getId()) {case R.id.btn_default:mCustomKeyView.setRandomKeyBoard(false);break;case R.id.btn_random:// 设置随机数字键盘mCustomKeyView.setRandomKeyBoard(true);break;}}@Overridepublic void clickNum(String num) {if (mEditText.getText().length() < 6) {mEditText.append(num);//文本长度为6时隐藏键盘if (mEditText.getText().length() == 6) {mPop.dismiss();}}}@Overridepublic void deleteNum() {int last = mEditText.getText().length();if (last > 0) {//删除最后一位mEditText.getText().delete(last - 1, last);}}
}

3.custom_keyboardview

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"><net.yangming.numkeyboard.CustomNumKeyView
        android:id="@+id/keyboardview"android:layout_width="match_parent"android:layout_height="200dp" />
</LinearLayout>

好了,自定义键盘就完成了 >_<

ps:
我这里只是做了最简单的键盘,主要是讲解实现的方法和思路。你们可以根据自己的需求画出不同的UI效果和点击效果。

android自定义数字键盘相关推荐

  1. android自定义数字键盘和字母键盘,Android自定义键盘的实现(数字键盘和字母键盘)...

    Android自定义键盘的实现(数字键盘和字母键盘) 发布时间:2020-09-04 03:18:48 来源:脚本之家 阅读:100 作者:浪淘沙xud 在项目中,产品对于输入方式会有特殊的要求,需要 ...

  2. android 支付数字键盘,微信小程序自定义数字键盘|仿支付宝、微信支付数字软键盘...

    (此图片来源于网络,如有侵权,请联系删除! ) 前几天有开发过一个html5仿支付宝.微信支付数字键盘,在某些特定场景下自定义数字键盘应用还是蛮广泛的,比如 小程序商城系统 需要零钱支付 ,会员卡支付 ...

  3. vue封装自定义数字键盘组件

    最近在公司做一个项目,简单来说就是web端微信公众号上的一个申请表单页面,随便如个图 环境: vue框架 + vant组件库 + 其它(这里用不上的,不说) 具体如图: 都知道,input输入框如果不 ...

  4. Android自定义安全键盘

    Android自定义安全键盘 Demo地址 主要功能:包含功能:数字+字母组合键盘.纯数字键盘.字符键盘,防止录屏截屏 . 项目主要是通过Recyclerview来进行实现的,项目整体结构使用了建造者 ...

  5. android 自定义车牌键盘(kotlin)

    android 自定义车牌键盘(kotlin) 前言 示例图 实现需求 定义键盘文件 核心代码 视频效果 汉字转化 项目链接 前言 平时停车缴费都要填车牌号码,就想着自己能不能也做个车牌键盘demo. ...

  6. android 调用数字键盘,微信调用支付数字键盘功能实现方法(Android)

    微信调用支付数字键盘功能实现方法(Android)现在微信支付.输入密码功能,已经开始使用自定义数字键盘,这样不仅更加方便.其效果着实精致.你知道微信支付和输入密码时自定义数字键盘是如何实现的? 不知 ...

  7. 小程序自定义数字键盘|仿微信支付、支付宝支付密码键盘

    微信小程序自定义键盘插件wcKeyboard|仿微信数字软键盘|仿支付宝自定义数字键盘|小程序自定义模拟系统键盘 前段时间有开发过一个html5仿支付宝.微信支付数字键盘,在某些情况下自定义数字键盘应 ...

  8. vue 自定义键盘组件_vue 自定义 数字键盘+mint UI MessageBox的应用

    功能: 实现自定义数字键盘,输入数字超过两位时不可输入 点击清空清空输入框内的值 提交时弹出提示框,并显示所输入的数字用--mint UI实现 效果图: 9. //将变量numberval赋给valu ...

  9. java数字时钟代码,Android自定义数字时钟代码,android自定义时钟,package jp.t

    Android自定义数字时钟代码,android自定义时钟,package jp.tpackage jp.tsmsogn.digitalclock;import java.util.Calendar; ...

  10. android自定义系统键盘,Android自定义软键盘

    [实例简介] Android自定义软键盘 [实例截图] [核心代码] keydemo └── keydemo ├── AndroidManifest.xml ├── bin │   ├── class ...

最新文章

  1. 如何在Java中将String转换为int?
  2. 戴尔新鲜空气制冷的研究:在数据中心里面,让我们脱掉厚夹克换上一件夏威夷衬衫!...
  3. 命令行下安装的tensorflow怎么打开_CourseMaker微课制作教程18:录ppt一直“正在打开……”及WPS下ppt满屏放映怎么办?...
  4. 复习深入笔记02:魔法方法/cookie,session,token/异常
  5. es6 async函数实例:按顺序完成异步操作
  6. 【论文笔记】命名实体识别论文
  7. 张小龙向来痴,微信从此醉,复盘8年,2大初心驱动至今 | 2019实录
  8. 计算机组装维护与故障排除教材,电脑组装、维护与故障排除(第2版)
  9. 【仿真】Carla介绍与使用 [1] (附代码手把手讲解)
  10. leetcode第197场周赛 之 5211概率的最大路径
  11. 《灌篮高手》——一部看了n遍的动漫
  12. 幂函数展开c语言,第三章幂函数展开.pdf
  13. 打造“沉浸式体验”展厅 智能讲解机器人云帆演绎新玩法
  14. 解除网页无法选择文字_无法复制
  15. Jenkins系列之——第一章 Jenkins下载及安装
  16. 南柯服务器压力,性能测试新手误区(四):一切来自录制
  17. Oracle查询数据提示ORA-00942:表或视图不存在
  18. POI导出EXCEL附带二维码以及条形码
  19. Java系列技术之Spring5框架-钟洪发-专题视频课程
  20. 从win10(1909)中彻底卸载智能云输入法

热门文章

  1. MySQL 数据库命名规范.PDF
  2. python两个excel做匹配_python链接两张excel表格数据-如何用python从excel中同时提取两个列的数据,并生......
  3. 万能计算机在线应用,万能计算器在线使用技巧,快点学习吧
  4. 大数据存储峰会4月9日深圳开幕
  5. Jzoj 一维数组(包括排序)部分代码(共42题)
  6. 2021水利水电安全员考试每日一练单选题库
  7. 自制合成孔径雷达(2) SDR实现的对比(SDR实现测速雷达)
  8. 小米手机+MIUI系统开发版线刷到稳定版(小米8+MIUI10)
  9. npm install 设置缓存
  10. Excel模板下载(带下拉框)