android开发自定义键盘,Android 总结:自定义键盘实现原理和三种实例详解

1、实现原理

实现软键盘主要用到了系统的两个类 Keyboard 和 KeyboardView .html

1. Keyboard

用于监听虚拟键盘:java

Loads an XML description of a keyboard and stores the attributes of the keys. A keyboard consists of rows of keys . The layout file for a keyboard contains XML that looks like the following snippet :

android:keyWidth="%10p"

android:keyHeight="50px"

android:horizontalGap="2px"

android:verticalGap="2px" >

...

...

1

2

3

4

5

6

7

8

9

10

11

1

2

3

4

5

6

7

8

9

10

11

咱们自定义的每个按键都将会有一个 codes 值,好比回退咱们就写成:android

android:keyIcon="@drawable/sym_keyboard_delete"/>

1

2

1

2

再监听就是:git

if (primaryCode == Keyboard.KEYCODE_DELETE){}

1

1

这就表示,监听 delete 事件了!

定义  标签时经常使用到的 codes / KEYCODE 有:github

public static final int KEYCODE_SHIFT = -1;

public static final int KEYCODE_MODE_CHANGE = -2;

public static final int KEYCODE_CANCEL = -3;

public static final int KEYCODE_DONE = -4;

public static final int KEYCODE_DELETE = -5;

public static final int KEYCODE_ALT = -6;

1

2

3

4

5

6

1

2

3

4

5

6

2. KeyboardView

处理绘制,检测按键,触摸动做:markdown

A view that renders a virtual Keyboard. It handles rendering of keys and detecting key presses and touch movements.

咱们会在Activity的xml文件中这样定义:dom

android:id="@+id/keyboard_view"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:layout_alignParentBottom="true"

android:background="@color/gray"

android:focusable="true"

android:focusableInTouchMode="true"

android:keyBackground="@drawable/bg_keyboard_selector"

android:keyTextColor="@color/keyTextColor"

android:visibility="gone"

android:keyPreviewLayout="@layout/key_preview_layout"

/>

1

2

3

4

5

6

7

8

9

10

11

12

13

1

2

3

4

5

6

7

8

9

10

11

12

13

其中 android:keyPreviewLayout 指的是每当咱们点击键盘上的某个键时,短暂弹出的布局。

属性名

描述

android:keyBackground

Image for the key.

android:keyPreviewLayout

Layout resource for key press feedback.

android:keyPreviewOffset

Vertical offset of the key press feedback from the key.

android:keyTextColor

Color to use for the label in a key.

android:keyTextSize

Size of the text for character keys.

android:labelTextSize

Size of the text for custom keys with some text and no icon.

android:popupLayout

Layout resource for popup keyboards.

android:verticalCorrection

Amount to offset the touch Y coordinate by, for bias correction.

咱们须要建一个xml文件,来布局咱们的视图,

通常是在res文件夹中建一个名为xml的文件夹,在里面新创建一个xml布局文件。ide

每个按键的属性主要包括

Android:codes=" " 和 android:keyLabel=""

Activity 就是根据 codes 的值来监听的。

一些能够自定义设置,一些须要是 keyboard 中设置好的,要保持一致。布局

2、实例解析:在xml文件中定义

1. 效果图:

9860bf19d4a37e0d20371170c56e84ad.png 

建一个类,用于处理软键盘事件,文件名为 KeyboardUtil.Java动画

2. 定义键盘的键

键盘上键的细节和它的位置咱们指定在一个xml文件中,每个键都有以下的属性,

keyLabel 这个属性是指每一个键显示的文本

codes 这个属性是指这个键表明的字符的unicode

例如,咱们定义了一个字母A,

codes 属性的值是97,keyLabel属性的值就是A

若是一个code对应多个key,这个key表明的字符取决于这个key接受到的点击数taps,例如,一个键具备63,33,58编码:

一次点击就是 ?

两次点击就是 !

三次点击就是 :

一个 key 还能够有一些可选的属性:

keyEdgeFlags 这个属性的值能够是left或者right

这个属性一般加在一行中最左边和最右边的键上。

keyWidth 这个属性定义了键的宽度,一般是一个百分比的值。

isRepeatable 这个属性若是设置为true,那么当长按该键时就会

重复接受到该键上的动做,在 删除键键 和 空格键 上一般设为true。

键盘上的键都是按行分组,一般状况下咱们每行上的键限制到10个之内

英文键盘建议每一个键占整个键盘宽度的10%,咱们将键的高度设置为60dp,这个值能够调整,可是不建议设置低于48dp .

有些键的code是负数,负数等于在Keyboard类

中预约义的常量,例如,-5等于Keyboard.KEYCODE_DELETE

3. 定义按键声音

建立一个方法,这个方法的做用就是当咱们按下某个键时发出一个声音,咱们使用 AudioManager 来播放这个声音,Android SDK给咱们提供了一些键盘的声效,咱们在本身定义的playClick()方法中使用。

private void playClick(int keyCode){

AudioManager am = (AudioManager)getSystemService(AUDIO_SERVICE);

switch(keyCode){

case 32:

am.playSoundEffect(AudioManager.FX_KEYPRESS_SPACEBAR);

break;

case Keyboard.KEYCODE_DONE:

case 10:

am.playSoundEffect(AudioManager.FX_KEYPRESS_RETURN);

break;

case Keyboard.KEYCODE_DELETE:

am.playSoundEffect(AudioManager.FX_KEYPRESS_DELETE);

break;

default:

am.playSoundEffect(AudioManager.FX_KEYPRESS_STANDARD);

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

4. 处理按键输入

当用户按下键盘上的一个键时,onKey()方法 会被调用,而且发送这个 键的unicode值,基于这个值,键盘能够执行如下动做:

若是code是 KEYCODE_DELETE,使用deleteSurroundingText()方法删除光标左边的字符。

若是code是 KEYCODE_DONE , KEYCODE_ENTER 事件会被发送。

若是code是 KEYCODE_SHIFT,boolean类型的caps的值会被改变,而且使用 setShifted() 方法改变键盘的换档状态(shift state),当状态改变时,键盘须要重绘,因此的键的label被更新了,invalidateAllKeys() 方法用来重绘全部的键。

对于 其余全部的codes,只是 简单的将unicode转化为字符而且发送到输入框里,若是这个code表明了字母表里的一个字母,而且caps变量为true,那么咱们须要将字母转化为大写。

修改onKey的代码(这里的功能实现方法跟实例中有误差):

@Override

public void onKey(int primaryCode, int[] keyCodes) {

InputConnection ic = getCurrentInputConnection();

playClick(primaryCode);

switch(primaryCode){

case Keyboard.KEYCODE_DELETE :

ic.deleteSurroundingText(1, 0);

break;

case Keyboard.KEYCODE_SHIFT:

caps = !caps;

keyboard.setShifted(caps);

kv.invalidateAllKeys();

break;

case Keyboard.KEYCODE_DONE:

ic.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENTER));

break;

default:

char code = (char)primaryCode;

if(Character.isLetter(code) && caps){

code = Character.toUpperCase(code);

}

ic.commitText(String.valueOf(code),1);

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

3、实例解析:继承EditText自定义view来实现

保证不遮挡输入框,界面漂亮有动画。数字键盘可随机,支持纯色绘制按键。

1. 效果图

7c1f8df1bdee370ded2bd143f698681f.png 

这个程序有点Bug,点击输入法最底部的三个键时,虚拟按键也触发到了。

想解这个Bug的话自行再仔细研究下代码。

1. 功能特色

在输入时,保证键盘不会挡住输入框。

能够直接经过 Edittext 的属性来配置要显示的键盘布局 xml 文件。点击 Edittext 输入框便可弹出键盘。

支持属性配置 已经写好的键盘 xml 。支持属性配置 是否随机数字。

支持纯色绘制按键。默认的 keyboardview 在android2.3等低版本下不能正常显示纯色的按键背景。本示范工程经过重写原有的 keyboardview 来解决这个bug。

注:资源里面只有两种键盘样式:数字0-9+"000"、0-9+. 。你能够经过本身写键盘布局xml,而后经过属性引用来显示本身的键盘。具体能够参考附件的示范工程。

2. 逻辑分析

1) 生成随机数的key

先for循环生成0-9的KeyModel,存储到LinkedList中

LinkedList tempList = new LinkedList();

for (int i = 0; i < count; i++) {

tempList.add(new KeyModel(48 + i, i + ""));

}

1

2

3

4

1

2

3

4

后面经过随机数,从 LinkedList 中取出KeyModel放入新的 List 中(这里的代码是 resultList), 而后这里的 List 就是随机的了。

Random rand = new SecureRandom();

rand.setSeed(SystemClock.currentThreadTimeMillis());

for (int i = 0; i < count; i++) {

int num = rand.nextInt(count - i);

// Log.d(TAG, " rand num"+num);

KeyModel model = tempList.get(num);

// Log.d(TAG, model.toString());

resultList.add(new KeyModel(model.getCode(), model.getLabel()));

tempList.remove(num);

}

1

2

3

4

5

6

7

8

9

10

11

1

2

3

4

5

6

7

8

9

10

11

4、实例解析:以Dialog的形式来实现

1. 效果图

093ab362546080b615b409d1e94ef918.png

2. 技术分析略。

5、源码下载地址:

上面三种“自定义键盘”方式并不是严格区分。

本博文转载自  http://blog.csdn.net/u014136472/article/details/50257245

原本想本身写的可是无心中发现这篇博客,感受写的很好,因此就转载了。

若是须要对每个例子的源码进行说明的话,可在评论出说明,我再本身写一些博文进行分析

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值