Android自定义软键盘KeyboardView 使用实例

在有些应用中会有定制软键盘的需求,往往实现起来会有些难度,或者说实现出来的效果不尽如人意。
最近在项目中有这种需求
这里写图片描述
博主也是不辱使命地完成了这个需求,效果图如下
这里写图片描述
说一下思路的和详细实现

主要是利用android自带的android.inputmethodservice.KeyboardView
对它进行自定义。


首先在res/目录下新建一个xml文件夹,新建一个xml文件

number.xml

<?xml version="1.0" encoding="utf-8"?>  
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"  android:keyWidth="33.33333%p" android:horizontalGap="1dp"  android:verticalGap="1dp" android:keyHeight="10%p">  <Row>  <Key android:codes="55" android:keyLabel="7" />  <Key android:codes="56" android:keyLabel="8" />  <Key android:codes="57" android:keyLabel="9" android:keyEdgeFlags="right"/>  </Row>  <Row><Key android:codes="52" android:keyLabel="4" />  <Key android:codes="53" android:keyLabel="5" />  <Key android:codes="54" android:keyLabel="6" android:keyEdgeFlags="right"/>  </Row>  <Row>  <Key android:codes="49" android:keyLabel="1" />  <Key android:codes="50" android:keyLabel="2" />  <Key android:codes="51" android:keyLabel="3" android:keyEdgeFlags="right"/>  </Row>  <Row>  <Key android:codes="46" android:keyLabel="." /> <Key android:codes="48" android:keyLabel="0" />  <Key android:codes="-3" android:keyEdgeFlags="right" android:keyLabel="OK"/>
<!--                 <Key android:codes="-3" android:keyEdgeFlags="right" android:keyIcon="@drawable/resale_btn_key_ok"/> --> </Row>  
</Keyboard> 

键盘工具类
KeyboardUtil.java

public class KeyboardUtil {private Context ctx;private MyKeyboardView keyboardView;private Keyboard k1;// 键盘
//  private Keyboard k2;
//  private Keyboard k3;public boolean isnun = false;// 是否数据键盘public boolean isupper = false;// 是否大写public final static int TYPE_NUMBER = 1; // 数量public final static int TYPE_PRICE = 2; // 价格private int type = -1;private KeyboardListener keyboardListener;private EditText ed;public interface KeyboardListener {void onOK();}/*** @param ctx* @param parent    包含MyKeyboardView的ViewGroup* @param edit*/public KeyboardUtil(Context ctx, View parent, EditText edit) {this.ctx = ctx;this.ed = edit;//此处可替换键盘xmlk1 = new Keyboard(ctx, R.xml.number);keyboardView = (MyKeyboardView) parent.findViewById(R.id.keyboard_view);keyboardView.setContext(ctx);keyboardView.setKeyboard(k1);keyboardView.setEnabled(true);keyboardView.setPreviewEnabled(true);keyboardView.setOnKeyboardActionListener(listener);}/*** @param ctx   必须要用Activity实例作为上下文传入* @param edit*/public KeyboardUtil(Context ctx, EditText edit) {this.ctx = ctx;this.ed = edit;//此处可替换键盘xmlk1 = new Keyboard(ctx, R.xml.number);try {keyboardView = (MyKeyboardView) ((Activity)ctx).findViewById(R.id.keyboard_view);keyboardView.setContext(ctx);keyboardView.setKeyboard(k1);keyboardView.setEnabled(true);keyboardView.setPreviewEnabled(true);keyboardView.setOnKeyboardActionListener(listener);} catch (Exception e) {Log.e("keyboardView", "keyboardView init failed!");}}public void setKeyboardListener(KeyboardListener keyboardListener) {this.keyboardListener = keyboardListener;}public void setType(int typein) {type = typein;}private OnKeyboardActionListener listener = new OnKeyboardActionListener() {@Overridepublic void swipeUp() {}@Overridepublic void swipeRight() {}@Overridepublic void swipeLeft() {}@Overridepublic void swipeDown() {}@Overridepublic void onText(CharSequence text) {}@Overridepublic void onRelease(int primaryCode) {}@Overridepublic void onPress(int primaryCode) {}@Overridepublic void onKey(int primaryCode, int[] keyCodes) {Editable editable = ed.getText();int start = ed.getSelectionStart();if (primaryCode == Keyboard.KEYCODE_CANCEL) {// 完成// hideKeyboard();keyboardListener.onOK();} else if (primaryCode == Keyboard.KEYCODE_DELETE) {// 回退if (editable != null && editable.length() > 0) {if (start > 0) {editable.delete(start - 1, start);}}} else if (primaryCode == Keyboard.KEYCODE_SHIFT) {// 大小写切换changeKey();keyboardView.setKeyboard(k1);} else if (primaryCode == Keyboard.KEYCODE_MODE_CHANGE) {// 键盘切换if (isnun) {isnun = false;keyboardView.setKeyboard(k1);} else {isnun = true;
//                  keyboardView.setKeyboard(k2);}} else if (primaryCode == 57419) { // go leftif (start > 0) {ed.setSelection(start - 1);}} else if (primaryCode == 57421) { // go rightif (start < ed.length()) {ed.setSelection(start + 1);}} else if (primaryCode == 46) {    // 小数点String text = ed.getText().toString();if (type == TYPE_PRICE) {if (!ed.getText().toString().contains(".") && text.length() <= 7) {editable.insert(start,Character.toString((char) primaryCode));}}} else {String text = ed.getText().toString();switch (type) {case TYPE_NUMBER:if (text.length() < 7) {editable.insert(start,Character.toString((char) primaryCode));}break;case TYPE_PRICE:if ((!text.contains(".") || text.length() - 1- text.indexOf(".") <= 1)&& text.length() < (text.contains(".")?10:7)) {//小数点后最长2位,接受7位整数editable.insert(start,Character.toString((char) primaryCode));}break;default:editable.insert(start,Character.toString((char) primaryCode));break;}}}};/*** 键盘大小写切换*/private void changeKey() {List<Key> keylist = k1.getKeys();if (isupper) {// 大写切换小写isupper = false;for (Key key : keylist) {if (key.label != null && isword(key.label.toString())) {key.label = key.label.toString().toLowerCase();key.codes[0] = key.codes[0] + 32;}}} else {// 小写切换大写isupper = true;for (Key key : keylist) {if (key.label != null && isword(key.label.toString())) {key.label = key.label.toString().toUpperCase();key.codes[0] = key.codes[0] - 32;}}}}public void showKeyboard() {int visibility = keyboardView.getVisibility();if (visibility == View.GONE || visibility == View.INVISIBLE) {keyboardView.setVisibility(View.VISIBLE);}}public void hideKeyboard() {int visibility = keyboardView.getVisibility();if (visibility == View.VISIBLE) {keyboardView.setVisibility(View.INVISIBLE);}}private boolean isword(String str) {String wordstr = "abcdefghijklmnopqrstuvwxyz";if (wordstr.indexOf(str.toLowerCase()) > -1) {return true;}return false;}
}

键盘界面布局

    <RelativeLayout
        android:id="@+id/rl__keyboard"android:layout_width="match_parent"android:layout_height="match_parent"android:background="@null"android:focusable="true"android:focusableInTouchMode="true"android:visibility="gone" ><com.ysdemo.keyboard.view.MyKeyboardView
            android:id="@+id/keyboard_view"android:layout_width="fill_parent"android:layout_height="wrap_content"android:layout_alignParentBottom="true"android:background="#d8d8d8"android:focusable="true"android:focusableInTouchMode="true"android:keyBackground="@drawable/bg_keyboard_btn"android:keyPreviewLayout="@layout/preview_keyboard"android:keyTextColor="#333333"android:paddingTop="1dp"android:shadowColor="#ffffff"android:shadowRadius="0.0" /><RelativeLayout
            android:id="@+id/rl_editor"android:layout_width="match_parent"android:layout_height="60dp"android:layout_above="@id/keyboard_view"android:background="#ffffff"android:gravity="center"android:padding="3dp" ><com.ysdemo.keyboard.view.XEditText
                android:id="@+id/et_amount"android:layout_width="match_parent"android:layout_height="60dp"android:layout_alignParentTop="true"android:layout_margin="2dp"android:background="#ffffff"android:drawableRight="@drawable/keboard_back"android:gravity="center"android:inputType="@null"android:padding="3dp"android:textColor="#00aeef" /></RelativeLayout></RelativeLayout>

在Activity中初始化键盘,实际使用时可以在基类Activity中做这些

public class MainActivity extends Activity {private RelativeLayout rl_keyboard;private KeyboardUtil keyboardUtil;private int change_type;private XEditText et_amount;private Button btn_showKey,btn_hideKey,btn_price,btn_number;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initTestBtn();initKeyboard();}private void initTestBtn() {btn_showKey = (Button) findViewById(R.id.btn_showKey);btn_hideKey = (Button) findViewById(R.id.btn_hideKey);btn_price = (Button) findViewById(R.id.btn_price);btn_number = (Button) findViewById(R.id.btn_number);btn_showKey.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {showKeyBoard();}});btn_hideKey.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {hideKeyBoard();}});btn_price.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {change_type = KeyboardUtil.TYPE_PRICE;showKeyBoard();}});btn_number.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {change_type = KeyboardUtil.TYPE_NUMBER;showKeyBoard();}});}private void initKeyboard() {et_amount = (XEditText) findViewById(R.id.et_amount);keyboardUtil = new KeyboardUtil(this, et_amount);rl_keyboard = (RelativeLayout) findViewById(R.id.rl__keyboard);et_amount.setInputType(InputType.TYPE_NULL);keyboardUtil.setKeyboardListener(new KeyboardListener() {@Overridepublic void onOK() {String result = et_amount.getText().toString();String msg = "";if (!TextUtils.isEmpty(result)) {switch (change_type) {case KeyboardUtil.TYPE_NUMBER:msg += "num:"+result;break;case KeyboardUtil.TYPE_PRICE:msg += "price:"+result;break;default:msg += "input:"+result;break;}Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();}hideKeyBoard();change_type = -1;}});et_amount.setDrawableRightListener(new DrawableRightListener() {@Overridepublic void onDrawableRightClick(View view) {Editable editable = ((EditText)view).getText();int start = ((EditText)view).getSelectionStart();if (editable != null && editable.length() > 0) {if (start > 0) {editable.delete(start - 1, start);}}}});}/*** 显示键盘*/protected void showKeyBoard() {rl_keyboard.setVisibility(View.VISIBLE);et_amount.setText("");switch (change_type) {case KeyboardUtil.TYPE_NUMBER:et_amount.setHint("请输入数量");break;case KeyboardUtil.TYPE_PRICE:et_amount.setHint("请输入价格");break;default:break;}keyboardUtil.setType(change_type);keyboardUtil.showKeyboard();}/*** 显示键盘*/protected void hideKeyBoard() {rl_keyboard.setVisibility(View.GONE);keyboardUtil.hideKeyboard();keyboardUtil.setType(-1);}@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) {if (keyCode == KeyEvent.KEYCODE_BACK) {if (rl_keyboard.getVisibility() != View.GONE) {hideKeyBoard();return true;}}return super.onKeyDown(keyCode, event);}
}

其他微调与细节:
1.设计给的退格键在键盘外 是单独实现的。
2.OK键的颜色不一致,由于没有直接修改键盘按键背景的方法,我重写了KeyboardView的Ondraw方法。
3.xml里code尽量使用android源码中的定义过的。
4.博文写的有些仓促,注释和说明也不怎么详细,整个封装的也不太好用,大家见谅。如有能力,欢迎申请pull、fork。

demo下载地址
csdn
github

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

IntelliJ IDEA和Android studio怎么去掉usage和作者提示

截止到目前我已经写了 600多道算法题&#xff0c;其中部分已经整理成了pdf文档&#xff0c;目前总共有1000多页&#xff08;并且还会不断的增加&#xff09;&#xff0c;大家可以免费下载 下载链接&#xff1a;https://pan.baidu.com/s/1hjwK0ZeRxYGB8lIkbKuQgQ 提取码&#xf…

iOS开发-keyboardType合集

1、UIKeyboardTypeDefault&#xff0c;常用于文本输入 2、UIKeyboardTypeASCIICapable&#xff0c;常用于密码输入 3、UIKeyboardTypeNumbersAndPunctuation&#xff0c;和上一个键盘互相切换 4、UIKeyboardTypeURL&#xff0c;适用于网址输入 5、UIKeyboardTypeNumberPad &am…

Android自定义实现漂亮的软键盘

工作中遇到了自定义软键盘的场景&#xff0c;虽然简单很快就实现了&#xff0c;但对个别的细节不太满意。 因为细节决定成败&#xff0c;所以细节之处也不能忽视。 先来张效果图吧&#xff1a; key的相关属性&#xff1a;row的相关属性&#xff1a;KeyboardView的相关属性&am…

ios键盘通知和自定义键盘

一.键盘通知 当文本View(如UITextField,UITextView, UIWebView内的输入框)进入编辑模式成为first responder时&#xff0c;系统会自动显示键盘。成为firstresponder可能由用户点击触发&#xff0c;也可向文本View发送becomeFirstResponder消息触发。当文本视图退出first respon…

android实现仿真键盘(KeyboardView适配)

原生的键盘布局声明了deprecated被废弃&#xff0c;虽然可以使用但明显不合需求。 /*** deprecated This class is deprecated because this is just a convenient UI widget class that* application developers can re-implement on top of existing public API…

C#制作软键盘

本文下载地址&#xff1a;https://pan.baidu.com/s/1ubpeTwuQvAPNlC4QLDpp8w 提取码&#xff1a;1234 c#制作软键盘&#xff0c;先来个图。 上面这个图是制作的最终结果显示。 在制作键盘的时候&#xff0c;总体来说还是比较简单的&#xff0c;只有几个地方比较复杂一点。布…

C#自定义键盘

C#自定义键盘 一、创建自定义键盘DLL文件 1、新建一个类库 2、在类库项目中添加用户控件类 3、在用户控件上添加键盘需要的控件 4、添加如下代码 using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Da…

IOS控件系列--优雅的表情键盘设计(扩展性好)

本控件效果如下图所示&#xff1a; 本控件设计的几个原则 &#xff1a; 1.扩展性好&#xff0c;代码不冗余。 2.逻辑清晰。 3.回调接口清晰。 4.移植性好。 首先来讨论下本控件的扩展性&#xff1a; 效果图给出的是3行7列。如果这个行列因子可控&#xff0c;起码可以应付…

坤音键盘(ikun专用)

坤音键位说明 &#xff08;下图第一个字母对应的是26键的键位&#xff0c;想听哪个按哪个。后面的数字代表时长&#xff0c;单位&#xff1a;秒&#xff09; 在右下角托盘里面可以右键关闭 ps&#xff1a;执行后桌面会出现一个ikun精灵&#xff0c;只要找一个能输入内容的地方…

Android自定义软键盘的实现

先看界面布局文件 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"fill_parent"android:layout_height"fill_parent"a…

Android自定义键盘(KeyboardView)

目录 1.场景&#xff1a;2.想法&#xff1a;3.开始实现&#xff1a;《一》 在res包下创建xml目录,Keyboard标签来定义键盘布局&#xff1a;《二》创建IKeyboardView类并继承KeyboardView类,设置键盘布局&#xff08;数字和字母&#xff09;《三》 处理自定义键盘按键的点击事件…

关于技术转管理角色的认知

软件质量保障&#xff1a;所寫即所思&#xff5c;一个阿里质量人对测试的所感所悟。 程序员发展的岔路口 技术人做了几年专业工作之后&#xff0c;会来到一个重要的“分岔路口”&#xff0c;一边是专业的技术路线&#xff0c;一边是技术团队的管理路线。不少人就开始犯难&…

什么是响应式设计?列举几种实现响应式设计的方法。

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 什么是响应式设计&#xff1f;⭐ 实现响应式设计的方法⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅&#xff01;这个专栏…

【雕爷学编程】Arduino动手做(12)---霍尔模块之单极性霍尔开关器件AH3144E与线性霍尔传感器AH49E

37款传感器与模块的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&#x…

超级简单方法解决秒杀超卖和重复购买问题

一、基本原则 1、SQL加库存数量判断&#xff1a;防止库存变成负数 2.、数据库加唯一索引&#xff1a;防止用户重复购买 二、举例说明 1、开启事务 2、商品表减库存&#xff0c;库存数量要大于0 update miaosha_goods set stock_count stock_count - 1 where goods.id …

金雅拓超级狗superdog

超级狗是SafeNet在圣天诺基础上为中国本土量身定制的新一代加密狗。 超级狗操作简单&#xff0c;非常安全&#xff0c;功能实用&#xff0c;助您轻松完成高强度加密。 PDF和flv, swf, mpg, dat, avi, wav, mp3等加密&#xff09; 4、文档加密&#xff0c;ppt,word,excel,pdf&am…

赛孚耐SafeNet开发狗超级狗开发入门

本文主要讲解如果使用C#语言来对超级狗进行二次开发&#xff0c;如果仅仅是做个激活的功能&#xff0c;可以参照另一篇博客&#xff0c;地址&#xff1a;http://www.cnblogs.com/dathlin/p/8487842.html 如果疑问&#xff0c;可以加QQ群&#xff1a;592132877 继续主题研究&am…

在Elasticsearch中回测超级趋势线(Supertrend)交叉交易策略

我们已经讨论了好几个单一指标交易策略&#xff0c;其中简单的相对强弱指数&#xff08;RSI&#xff09;交易策略取得的利润最高。 在本文中&#xff0c;我们将使用 Elasticsearch 实现超级趋势线&#xff08;Supertrend&#xff09;交叉交易策略&#xff0c;并比较其性能是否优…

cmake基础(1)——简单项目

本节将围绕着hello world展开介绍如何创建一个简单的项目。 一、最小项目 1.准备工作 首先&#xff0c;新建一个目录01用来存放当前项目&#xff0c;并在目录下创建main.cpp和CMakeLists.txt文件&#xff0c;两者文件内容如下&#xff1a; #include <iostream> using…

Go把Map转成对象

最近使用了Redis的Hash&#xff0c;把一个对象给存储到了hash里面&#xff0c;具体如下&#xff1a; 现在需要从RedisHash缓存里面把结果给取出来&#xff0c;同时赋值到一个对象上面 result, err : global.GVA_REDIS.HGetAll(context.Background(), key).Result() 问题是resul…