android自定义金额输入键盘_Android 自定义控件 - 仿支付宝数字键盘

原标题:Android 自定义控件 - 仿支付宝数字键盘

简介

在一些带有支付功能的 App 中,输入的密码一般只能是纯数字,虽然我们可以指定 EditText 输入框只能输入数字,但是为了提供用户的使用体验,我们往往更倾向于使用自定义的纯数字键盘。

本文效果:

187514dbaa9f41bbddb95821febc5af0.gif

实现步骤:

集成系统的 KeyBoardView 类,在初始化时初始化键盘布局,设置 KeyBoard 对象。

实现 OnKeyboardActionListener 接口,处理按键交互事件。

根据需求绘制按键背景和按键图标。

设置监听器,将输入的内容回调给调用方。

键盘布局

在 res/xml/ 目录下创建 xml 文件:key_password_number.xml

android:horizontalGap="1dp"

android:keyHeight="9%p"

android:keyWidth="33.3333%p"

android:verticalGap="1dp">

android:codes="49"

android:keyLabel="1"/>

android:codes="50"

android:keyLabel="2"/>

android:codes="51"

android:keyLabel="3"/>

android:codes="52"

android:keyLabel="4"/>

android:codes="53"

android:keyLabel="5"/>

android:codes="54"

android:keyLabel="6"/>

android:codes="55"

android:keyLabel="7"/>

android:codes="56"

android:keyLabel="8"/>

android:codes="57"

android:keyLabel="9"/>

android:codes="-10"

android:keyLabel=""/>

android:codes="48"

android:keyLabel="0"/>

android:codes="-5"

android:keyLabel=""/>

继承 KeyBoardView

publicclassPwdKeyboardViewextendsKeyboardViewimplementsKeyboardView.OnKeyboardActionListener{

privatestaticfinalString TAG = "PwdKeyboardView";

privatestaticfinalintKEY_EMPTY = - 10;

privateintdelKeyBackgroundColor = 0xffcccccc;

privateRect keyIconRect;

publicPwdKeyboardView(Context context, AttributeSet attrs){

super(context, attrs);

Log.d(TAG, "PwdKeyboardView: two params");

init(context);

}

publicPwdKeyboardView(Context context, AttributeSet attrs, intdefStyleAttr){

super(context, attrs, defStyleAttr);

Log.d(TAG, "PwdKeyboardView: three params");

init(context);

}

privatevoidinit(Context context){

Keyboard keyboard = newKeyboard(context, R.xml.key_password_number); // 初始化 keyboard

setKeyboard(keyboard);

setEnabled( true);

setFocusable( true);

setPreviewEnabled( false); // 设置点击按键不显示预览气泡

setOnKeyboardActionListener( this);

}

/**

* 重新绘制删除按键和空白键

*

* @paramcanvas

*/

@Override

publicvoidonDraw(Canvas canvas){

super.onDraw(canvas);

List keys = getKeyboard().getKeys();

for(Keyboard.Key key : keys) {

if(key.codes[ 0] == KEY_EMPTY) {

// 绘制空白键背景

drawKeyBackground(key, canvas, delKeyBackgroundColor);

}

if(key.codes[ 0] == Keyboard.KEYCODE_DELETE) {

// 删除删除按键背景

drawKeyBackground(key, canvas, delKeyBackgroundColor);

// 绘制删除按键图标

drawKeyIcon(key, canvas, getResources().getDrawable(R.drawable.ic_delete));

}

}

}

/**

* 绘制按键的背景

*

* @paramkey

* @paramcanvas

* @paramcolor

*/

privatevoiddrawKeyBackground(Keyboard.Key key, Canvas canvas, intcolor){

ColorDrawable drawable = newColorDrawable(color);

drawable.setBounds(key.x, key.y, key.x + key.width, key.y + key.height);

drawable.draw(canvas);

}

/**

* 绘制按键的 icon

*

* @paramkey

* @paramcanvas

* @paramiconDrawable

*/

privatevoiddrawKeyIcon(Keyboard.Key key, Canvas canvas, Drawable iconDrawable){

if(iconDrawable == null) {

return;

}

// 计算按键icon 的rect 范围

if(keyIconRect == null|| keyIconRect.isEmpty()) {

// 得到 keyicon 的显示大小,因为图片放在不同的drawable-dpi目录下,显示大小也不一样

intintrinsicWidth = iconDrawable.getIntrinsicWidth();

intintrinsicHeight = iconDrawable.getIntrinsicHeight();

intdrawWidth = intrinsicWidth;

intdrawHeight = intrinsicHeight;

// 限制图片的大小,防止图片按键范围

if(drawWidth > key.width) {

drawWidth = key.width;

// 此时高就按照比例缩放

drawHeight = ( int) (drawWidth * 1.0f/ intrinsicWidth * intrinsicHeight);

} elseif(drawHeight > key.height) {

drawHeight = key.height;

drawWidth = ( int) (drawHeight * 1.0f/ intrinsicHeight * intrinsicWidth);

}

// 获取图片的 x,y 坐标,图片在按键的正中间

intleft = key.x + key.width / 2- drawWidth / 2;

inttop = key.y + key.height / 2- drawHeight / 2;

keyIconRect = newRect(left, top, left + drawWidth, top + drawHeight);

}

if(keyIconRect != null&& !keyIconRect.isEmpty()) {

iconDrawable.setBounds(keyIconRect);

iconDrawable.draw(canvas);

}

}

@Override

publicvoidonPress(intprimaryCode){

}

@Override

publicvoidonRelease(intprimaryCode){

}

/**

* 处理按键的点击事件

*/

@Override

publicvoidonKey(intprimaryCode, int[] keyCodes){

Log.d(TAG, "onKey: primaryCode = "+ primaryCode + ", keyCodes = "+ Arrays.toString(keyCodes));

if(primaryCode == KEY_EMPTY) {

return;

}

if(listener != null) {

if(primaryCode == Keyboard.KEYCODE_DELETE) {

listener.onDelete();

} else{

listener.onInput(String.valueOf(( char) primaryCode));

}

}

}

@Override

publicvoidonText(CharSequence charSequence){

}

@Override

publicvoidswipeLeft(){

}

@Override

publicvoidswipeRight(){

}

@Override

publicvoidswipeDown(){

}

@Override

publicvoidswipeUp(){

}

publicinterfaceOnKeyListener{

// 输入回调

voidonInput(String text);

// 删除回调

voidonDelete();

}

privateOnKeyListener listener;

publicvoidsetOnKeyListener(OnKeyListener listener){

this.listener = listener;

}

}

使用 PwdKeyboardView

android:id= "@+id/key_board"

android:layout_width= "match_parent"

android:layout_height= "wrap_content"

android:background= "#919191"

android:keepScreenOn= "true"

android:keyBackground= "@drawable/selector_key_board"

android:keyTextColor= "@android:color/black"

android:keyTextSize= "26sp"

android:shadowRadius= "0"/>

显示结果为:

c4123a6ba2206c554d942bbe09cf7380.png

完整代码:https://github.com/xing16/PwdKeyboardView返回搜狐,查看更多

责任编辑:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/453674.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

博客目录(python相关)

python 相关 文件格式相关系列 Python 第三方模块之 beautifulsoup(bs4)- 解析 HTML Python 第三方模块之 ElementTree(ET)- 解析XML文件 Python 第三方模块之 lxml - 解析 HTML 和 XML 文件 python 第三方模块 yaml - 处理 …

项目主体思索

1:分布式定义; 2:SSO集成方式 3:menu动态菜单的添加 4:tag页面展示; 5:tiles的jsp复用; 暂时就想到这些了,以后继续补充。转载于:https://www.cnblogs.com/siyan/p/8286738.html

centos mysql pid_centos7 mysql The server quit without updating PID file(错误解决)

1 问题[rootlocalhost mysql]# /etc/rc.d/init.d/mysql statusMySQL is not running, but lock file (/var/lock/subsys/mysql[FAILED][rootlocalhost mysql]# /etc/rc.d/init.d/mysql startStarting MySQL...The server quit without updating PID file (/usr/local/mysql/dat…

tfs文件系统之NS配置管理

NameServer简称NS 充当着客户与DS的交互桥梁 1.NS配置文件修改: [public] #log file size default 1GB log_size1073741824 #log file num default 64 log_num 64 #log file level default debug log_leveldebug #main queue size default 10240 task_max_queue_…

插件式架构设计实践:插件式系统架构设计简介

本系列博文将使用微软RIA技术解决方案Silverlight以及扩展性管理框架Managed Extensibility Framework(MEF),以插件式架构设计为导线,分享本人在从事基于微软Silverlight技术构建的RIA系统中实施插件式系统架构设计的相关技术和经…

第十章 动态选路协议

RIP 缺陷: Routing Information Protocol RIP没有子网的概念在路由器或链路发生故障后,需要很长的一段时间才能稳定下来采用跳数作为路由度量忽略了其他一些应该考虑的因素度量最大值为15则限制了可以使用RIP的网络的大小OSPF Open Shortest Path First …

五种方式让你在java中读取properties文件内容不再是难题

2019独角兽企业重金招聘Python工程师标准>>> 方式1.通过context:property-placeholder加载配置文件jdbc.properties中的内容 <context:property-placeholder location"classpath:jdbc.properties" ignore-unresolvable"true"/> 上面的配置…

hive metastore mysql_Hive MetaStore的结构

本篇主要是介绍Hive在MySQL中存储的源数据的表结构。Hive MetaStore 数据库表结构图test.pngTBLS记录数据表的信息字段解释TBL_ID在hive中创建表的时候自动生成的一个id&#xff0c;用来表示&#xff0c;主键CREATE_TIME创建的数据表的时间&#xff0c;使用的是时间戳DBS_ID这个…

修炼一名程序员的职业水准

程序就是一系列按步骤进行的操作序列&#xff0c;它有好多种级别&#xff0c;比如最低级的微程序、次低级的汇编程序、高级的各种编程语言程序、最高级的脚本语言程序&#xff0c;也许我列的不对&#xff0c;但没关系&#xff0c;我要说的是不管是那个级别的程序&#xff0c;其…

Rails开发细节《一》

常用命令 rails new new_app cd new_app rake db:create rails server rails generate controller Blog action1 action2 rails generate scaffold Product title:string description:textrails generate model Comment commenter:string body:text post:references rake db…

latex中怎样使公式居中_LaTeX_多行公式对齐居中的同时选择性的加编号

标签: 【转载请注明出处】http://www.cnblogs.com/mashiqi 2016/10/20 一年多没写博文了。今天写一个短的,记录一下使用LaTeX的一些经验。 如何居中多行的公式呢?我试过很多种方法后,觉得下面这个最好用: 1 \begin{flalign*}2 % In this way (this arrange of &), the…

[SDOI2008]Cave 洞穴勘测

题目描述 辉辉热衷于洞穴勘测。 某天&#xff0c;他按照地图来到了一片被标记为JSZX的洞穴群地区。经过初步勘测&#xff0c;辉辉发现这片区域由n个洞穴&#xff08;分别编号为1到n&#xff09;以及若干通道组成&#xff0c;并且每条通道连接了恰好两个洞穴。假如两个洞穴可以通…

Linux指令大全

名称&#xff1a;cat 使用权限&#xff1a;所有使用者 使用方式&#xff1a;cat [-AbeEnstTuv] [--help] [--version] fileName 说明&#xff1a;把档案串连接后传到基本输出&#xff08;萤幕或加 > fileName 到另一个档案&#xff09; 参数&#xff1a; -n 或 --number 由 …

mysql宏参数_C语言带参数的宏定义

C语言允许宏带有参数。在宏定义中的参数称为“形式参数”&#xff0c;在宏调用中的参数称为“实际参数”&#xff0c;这点和函数有些类似。对带参数的宏&#xff0c;在展开过程中不仅要进行字符串替换&#xff0c;还要用实参去替换形参。带参宏定义的一般形式为&#xff1a;#de…

自定义过滤器

首先在web.xml中对过滤器的监听 1 <!-- 自定义过滤器 -->2 <filter>3 <filter-name>AscFilter</filter-name>4 <filter-class>com.llh.filter.AscFilter</filter-class>5 </filter>6 <filter-mapping>7 …

[MS Sql Server术语解释]预读,逻辑读,物理读

在MSSQL中使用 SET STATISTICS IO ON 打开IO统计功能之后&#xff0c;每次执行完一个查询就会在下面的【消息】面板中显示本次查询IO的统计信息。 (0 行受影响) 表 demo。扫描计数 1&#xff0c;逻辑读取 622 次&#xff0c;物理读取 0 次&#xff0c;预读 0 次&#xff0c;lob…

mysql 数据库查询测试_MySQL查询测试经验

测试表geoinfo,整个表超过1100万行&#xff0c;表结构&#xff1a;CREATE TABLEgeoinfo (objectidint(11) NOT NULLAUTO_INCREMENT ,latitudedouble NOT NULL,longitudedouble NOT NULL,occupancybit(1) NOT NULL,timedatetime NOT NULL,cabidvarchar(16) NOT NULL,PRIMARY KEY…

更改阿里云域名解析台里某个域名绑定的IP之后不能解析到新IP

1.由于要撤销一组负载均衡&#xff0c;所以需要更改阿里云域名解析台里某个域名由原来绑定的负载均衡公网IP换到服务器公网IP 2.在服务器上nginx指定了域名访问&#xff0c;开启nginx服务 3.暂时关闭该组负载均衡服务 4.实现通过服务器IP可以访问项目&#xff0c;域名访问不了 …

秒懂数据类型的真谛—Python基础前传(4)

一切编程语言都是人设计的&#xff0c;既然是人设计的&#xff0c;那么设计各种功能的时候就一定会有它的道理&#xff0c;那么设计数据类型的用意是什么呢&#xff1f; (一) 基本数据类型 基本数据类型&#xff1a; 数字 int字符串 str布尔值 bool列表 list元组 tuple字典 dic…

Linux 系统命令及其使用详解(大全)

Linux 系统命令及其使用详解(大全) (来源: 中国系统分析员) cat cd   chmod chown   cp cut   名称&#xff1a;cat   使用权限&#xff1a;所有使用者   使用方式&#xff1a;cat[-AbeEnstTuv] [--help] [--version] fileName   说明&#xff1a;把档案串连…