标签:
以前知道有个KeyboardView这个东西可以自定义键盘,但因为一直没涉及到,所以没研究过,今天看到工商银行密码输入的键盘觉得挺好看,就来研究一下。
先看一下工商银行的图
下边是我的效果图
参考了:http://blog.csdn.net/hfsu0419/article/details/7924673
http://www.cnblogs.com/jason-star/archive/2012/12/15/2819174.html
两篇博客。
现在做一下笔记。
在需要显示键盘的布局中,插入这部分代码
android:keyBackground代表按键的背景
android:keyPreviewHeight按下后预览字符的高度
android:keyPreviewLayout按下后预览字符的布局(有默认的)
android:keyPreviewOffset偏移量,调整预览时显示的位置
<RelativeLayout
android:id="@+id/rl_keyboard"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:visibility="gone">
<!--
没有这两个属性,按键上文字会发虚模糊
android:shadowColor="#FFFFFF"
android:shadowRadius="0.0"-->
<android.inputmethodservice.KeyboardView
android:id="@+id/keyboard_view"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="#ECECEC"
android:focusable="true"
android:focusableInTouchMode="true"
android:keyBackground="@drawable/btn_keyboard_key"
android:keyPreviewHeight="100dp"
android:keyPreviewLayout="@layout/key_preview_layout"
android:keyPreviewOffset="50dp"
android:keyTextColor="#4F4F4F"
android:paddingBottom="5dp"
android:paddingTop="5dp"
android:shadowColor="#FFFFFF"
android:shadowRadius="0.0" />
</RelativeLayout>
通过Keyboard说明是一个软键盘定义文件,Row元素说明这是一行按键的定义,Key元素说明这是一个按键的定义。Key元素通过一些属性来定义每个按键,下面是一些常用的属性介绍:
Codes:代表按键对应的输出值,可以为unicode值或则逗号(,)分割的多个值,也可以为一个字 符串。在字符串中通过“\”来转义特殊字符,例如 ‘\n’ 或则 ‘\uxxxx’ 。Codes通常用来定义该键的键码,例如上图中的数字按键1对应的为49;如果提供的是逗号分割的多个值则和普通手机输入键盘一样在多个值之间切换。
keyLabel:代表按键显示的文本内容。
keyIcon:代表按键显示的图标内容,如果指定了该值则在显示的时候显示为图片不显示文本。
keyWidth:代表按键的宽度,可以为精确值或则相对值,对于精确值支持多种单位,例如:像素,英寸 等;相对值为相对于基础取值的百分比,为以% 或则%p 结尾,其中%p表示相对于父容器。
keyHeight:代表按键的高度,取值同上。
horizontalGap:代表按键前的间隙(水平方向),取值同上。
isSticky:指定按键是否为sticky的。例如Shift大小写切换按键,具有两种状态,按下状态和正常状态,取值为true或则false。
isModifier:指定按键是否为功能键( modifier key ) ,例如 Alt 或则 Shift 。取值为true或则false。
keyOutputText:指定按键输出的文本内容,取值为字符串。
isRepeatable:指定按键是否是可重复的,如果长按该键可以触发重复按键事件则为true,否则为false。
keyEdgeFlags:指定按键的对齐指令,取值为left或则right。
首先在res下建xml文件夹,在文件夹下建字母,数字,符号三个xml文件。
字母键盘qwerty.xml
<?xml version="1.0" encoding="UTF-8"?>
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
android:horizontalGap="0.0px"
android:keyHeight="@dimen/key_height"
android:keyWidth="10.000002%p"
android:verticalGap="0.0px">
<Row>
<Key
android:codes="113"
android:keyEdgeFlags="left"
android:keyLabel="q" />
<Key
android:codes="119"
android:keyLabel="w" />
<Key
android:codes="101"
android:keyLabel="e" />
<Key
android:codes="114"
android:keyLabel="r" />
<Key
android:codes="116"
android:keyLabel="t" />
<Key
android:codes="121"
android:keyLabel="y" />
<Key
android:codes="117"
android:keyLabel="u" />
<Key
android:codes="105"
android:keyLabel="i" />
<Key
android:codes="111"
android:keyLabel="o" />
<Key
android:codes="112"
android:keyEdgeFlags="right"
android:keyLabel="p" />
</Row>
<Row>
<Key
android:codes="97"
android:horizontalGap="4.999995%p"
android:keyEdgeFlags="left"
android:keyLabel="a" />
<Key
android:codes="115"
android:keyLabel="s" />
<Key
android:codes="100"
android:keyLabel="d" />
<Key
android:codes="102"
android:keyLabel="f" />
<Key
android:codes="103"
android:keyLabel="g" />
<Key
android:codes="104"
android:keyLabel="h" />
<Key
android:codes="106"
android:keyLabel="j" />
<Key
android:codes="107"
android:keyLabel="k" />
<Key
android:codes="108"
android:keyEdgeFlags="right"
android:keyLabel="l" />
</Row>
<Row>
<Key
android:codes="-1"
android:isModifier="true"
android:isSticky="true"
android:keyEdgeFlags="left"
android:keyIcon="@drawable/sym_keyboard_shift_normal"
android:keyWidth="14.999998%p" />
<Key
android:codes="122"
android:keyLabel="z" />
<Key
android:codes="120"
android:keyLabel="x" />
<Key
android:codes="99"
android:keyLabel="c" />
<Key
android:codes="118"
android:keyLabel="v" />
<Key
android:codes="98"
android:keyLabel="b" />
<Key
android:codes="110"
android:keyLabel="n" />
<Key
android:codes="109"
android:keyLabel="m" />
<Key
android:codes="-5"
android:isRepeatable="true"
android:keyEdgeFlags="right"
android:keyIcon="@drawable/sym_keyboard_delete"
android:keyWidth="14.999998%p" />
</Row>
<Row android:rowEdgeFlags="bottom">
<!--
isSticky:指定按键是否为sticky的。例如Shift大小写切换按键,具有两种状态,按下状态和正常状态,取值为true或则false。
isModifier:指定按键是否为功能键( modifier key ) ,例如 Alt 或则 Shift 。取值为true或则false。-->
<Key
android:codes="32"
android:isModifier="true"
android:isRepeatable="true"
android:keyEdgeFlags="left"
android:keyLabel="小侯子安全键盘"
android:keyWidth="74.999996%p" />
<Key
android:codes="-4"
android:keyEdgeFlags="right"
android:keyLabel="完成"
android:keyWidth="25.000004%p" />
</Row>
</Keyboard>
数字键盘digit.xml
<?xml version="1.0" encoding="utf-8"?>
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
android:horizontalGap="0px"
android:keyHeight="@dimen/key_height"
android:keyWidth="33%p"
android:verticalGap="0px">
<Row>
<Key
android:codes="49"
android:keyLabel="1" />
<Key
android:codes="50"
android:keyLabel="2" />
<Key
android:codes="51"
android:keyLabel="3" />
</Row>
<Row>
<Key
android:codes="52"
android:keyLabel="4" />
<Key
android:codes="53"
android:keyLabel="5" />
<Key
android:codes="54"
android:keyLabel="6" />
</Row>
<Row>
<Key
android:codes="55"
android:keyLabel="7" />
<Key
android:codes="56"
android:keyLabel="8" />
<Key
android:codes="-5"
android:keyIcon="@drawable/sym_keyboard_delete" />
</Row>
<Row>
<Key
android:codes="57"
android:keyLabel="9" />
<Key
android:codes="48"
android:keyLabel="0" />
<Key
android:codes="-4"
android:isRepeatable="true"
android:keyEdgeFlags="right"
android:keyLabel="完成" />
</Row>
</Keyboard>
符号键盘symbol.xml
<?xml version="1.0" encoding="UTF-8"?>
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
android:horizontalGap="0.0px"
android:keyHeight="@dimen/key_height"
android:keyWidth="10.000002%p"
android:verticalGap="0.0px">
<Row>
<Key
android:codes="91"
android:keyEdgeFlags="left"
android:keyLabel="[" />
<Key
android:codes="93"
android:keyLabel="]" />
<Key
android:codes="123"
android:keyLabel="{" />
<Key
android:codes="125"
android:keyLabel="}" />
<Key
android:codes="35"
android:keyLabel="#" />
<Key
android:codes="37"
android:keyLabel="%" />
<Key
android:codes="94"
android:keyLabel="^" />
<Key
android:codes="42"
android:keyLabel="*" />
<Key
android:codes="43"
android:keyLabel="+" />
<Key
android:codes="61"
android:keyEdgeFlags="right"
android:keyLabel="=" />
</Row>
<Row>
<Key
android:codes="95"
android:keyEdgeFlags="left"
android:keyLabel="_" />
<Key
android:codes="45"
android:keyLabel="-" />
<Key
android:codes="47"
android:keyLabel="/" />
<Key
android:codes="58"
android:keyLabel=":" />
<Key
android:codes="59"
android:keyLabel=";" />
<Key
android:codes="40"
android:keyLabel="(" />
<Key
android:codes="41"
android:keyLabel=")" />
<Key
android:codes="36"
android:keyLabel="$" />
<!--&-->
<Key
android:codes="38"
android:keyLabel="&" />
<Key
android:codes="64"
android:keyLabel="\@" />
</Row>
<Row>
<Key
android:codes="46"
android:keyEdgeFlags="left"
android:keyLabel="." />
<Key
android:codes="44"
android:keyEdgeFlags="right"
android:keyLabel="," />
<Key
android:codes="63"
android:keyLabel="\?" />
<Key
android:codes="33"
android:keyLabel="!" />
<Key
android:codes="39"
android:keyLabel="‘" />
<!--\-->
<Key
android:codes="92"
android:keyLabel="\\" />
<Key
android:codes="124"
android:keyLabel="|" />
<Key
android:codes="126"
android:keyLabel="~" />
<Key
android:codes="-5"
android:isRepeatable="true"
android:keyEdgeFlags="right"
android:keyIcon="@drawable/sym_keyboard_delete"
android:keyWidth="20.000004%p" />
</Row>
<Row android:rowEdgeFlags="bottom">
<Key
android:codes="96"
android:keyLabel="`" />
<!--<-->
<Key
android:codes="60"
android:keyLabel="<" />
<!-->-->
<Key
android:codes="62"
android:keyLabel=">" />
<Key
android:codes="8364"
android:keyLabel="€" />
<Key
android:codes="163"
android:keyLabel="£" />
<Key
android:codes="165"
android:keyLabel="¥" />
<!--"-->
<Key
android:codes="34"
android:keyLabel=""" />
<Key
android:codes="-4"
android:keyEdgeFlags="right"
android:keyLabel="完成"
android:keyWidth="30.000006%p" />
</Row>
</Keyboard>
有的符号在xml中不能直接写,可以用ASCII编码代替
k1 = new Keyboard(ctx, R.xml.qwerty);
k2 = new Keyboard(ctx, R.xml.digit);
k3 = new Keyboard(ctx, R.xml.symbol);
keyboardView = (KeyboardView) act.findViewById(R.id.keyboard_view);
rlKeyboard = (RelativeLayout) act.findViewById(R.id.rl_keyboard);
keyboardView.setKeyboard(k1);//显示那个就set哪个
keyboardView.setEnabled(true);
keyboardView.setPreviewEnabled(true);//可预览
keyboardView.setOnKeyboardActionListener(listener);
在onKey方法中做处理
private OnKeyboardActionListener listener = new OnKeyboardActionListener() {
...
@Override
public void onKey(int primaryCode, int[] keyCodes) {
Editable editable = ed.getText();
int start = ed.getSelectionStart();
if (primaryCode == Keyboard.KEYCODE_DONE) {// 完成
hideKeyboard();
} 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;
randomdigkey();//数字做了随机,每次位置不同
keyboardView.setKeyboard(k2);
}
} else if (primaryCode == 57419) { // go left
if (start > 0) {
ed.setSelection(start - 1);
}
} else if (primaryCode == 57421) { // go right
if (start < ed.length()) {
ed.setSelection(start + 1);
}
} else {
editable.insert(start, Character.toString((char) primaryCode));
}
}
};
KeyboardUtil.java完整代码
package com.juxin.common.utils;
import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.inputmethodservice.Keyboard;
import android.inputmethodservice.Keyboard.Key;
import android.inputmethodservice.KeyboardView;
import android.inputmethodservice.KeyboardView.OnKeyboardActionListener;
import android.media.AudioAttributes;
import android.os.Vibrator;
import android.provider.Settings;
import android.text.Editable;
import android.view.View;
import android.view.animation.AnimationUtils;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.juxin.common.R;
import com.juxin.common.widget.SafeEditText;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
public class KeyboardUtil {
private Context ctx;
private Activity act;
private KeyboardView keyboardView;
private Keyboard k1;// 字母键盘
private Keyboard k2;// 数字键盘
private Keyboard k3;// 符号键盘
public boolean isnun = false;// 是否数据键盘
public boolean isupper = false;// 是否大写
private Resources resources;
private EditText ed;
private RelativeLayout rlKeyboard;
private TextView tvSystemKeyboard;
private RadioGroup rgChangeKeyboard;
private RadioButton rbDigit, rbLetter, rbSymbol;
public KeyboardUtil(Activity act, Context ctx, EditText edit) {
this.act = act;
this.ctx = ctx;
this.ed = edit;
resources = ctx.getResources();
k1 = new Keyboard(ctx, R.xml.qwerty);
k2 = new Keyboard(ctx, R.xml.digit);
k3 = new Keyboard(ctx, R.xml.symbol);
keyboardView = (KeyboardView) act.findViewById(R.id.keyboard_view);
rlKeyboard = (RelativeLayout) act.findViewById(R.id.rl_keyboard);
keyboardView.setKeyboard(k1);
keyboardView.setEnabled(true);
keyboardView.setPreviewEnabled(true);
keyboardView.setOnKeyboardActionListener(listener);
rgChangeKeyboard = (RadioGroup) act.findViewById(R.id.rgChangeKeyboard);
tvSystemKeyboard = (TextView) act.findViewById(R.id.tvSystemKeyboard);
rbDigit = (RadioButton) act.findViewById(R.id.rb_digit);
rbLetter = (RadioButton) act.findViewById(R.id.rb_letter);
rbSymbol = (RadioButton) act.findViewById(R.id.rb_symbol);
tvSystemKeyboard.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
openKeyBoard();
}
});
rgChangeKeyboard.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
if (checkedId == R.id.rb_digit) {
isnun = true;
randomdigkey();
keyboardView.setKeyboard(k2);
} else if (checkedId == R.id.rb_letter) {
isnun = false;
keyboardView.setKeyboard(k1);
} else if (checkedId == R.id.rb_symbol) {
keyboardView.setKeyboard(k3);
}
}
});
}
private OnKeyboardActionListener listener = new OnKeyboardActionListener() {
@Override
public void swipeUp() {
}
@Override
public void swipeRight() {
}
@Override
public void swipeLeft() {
}
@Override
public void swipeDown() {
}
@Override
public void onText(CharSequence text) {
}
@Override
public void onRelease(int primaryCode) {
}
@Override
public void onPress(int primaryCode) {
vibrate(20);
if (primaryCode == Keyboard.KEYCODE_SHIFT || primaryCode == Keyboard.KEYCODE_DELETE
|| primaryCode == Keyboard.KEYCODE_DONE || primaryCode == 32 || primaryCode == Keyboard.KEYCODE_MODE_CHANGE
|| (primaryCode >= 48 && primaryCode <= 57)) {
keyboardView.setPreviewEnabled(false);
} else {
keyboardView.setPreviewEnabled(true);
}
}
@Override
public void onKey(int primaryCode, int[] keyCodes) {
Editable editable = ed.getText();
int start = ed.getSelectionStart();
if (primaryCode == Keyboard.KEYCODE_DONE) {// 完成
hideKeyboard();
} 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;
randomdigkey();
keyboardView.setKeyboard(k2);
}
} else if (primaryCode == 57419) { // go left
if (start > 0) {
ed.setSelection(start - 1);
}
} else if (primaryCode == 57421) { // go right
if (start < ed.length()) {
ed.setSelection(start + 1);
}
} else {
editable.insert(start, Character.toString((char) primaryCode));
}
}
};
private void randomdigkey() {
List<Key> keyList = k2.getKeys();
// 查找出0-9的数字键
List<Key> newkeyList = new ArrayList<Key>();
for (int i = 0; i < keyList.size(); i++) {
if (keyList.get(i).label != null
&& isNumber(keyList.get(i).label.toString())) {
newkeyList.add(keyList.get(i));
}
}
// 数组长度
int count = newkeyList.size();
// 结果集
List<KeyModel> resultList = new ArrayList<KeyModel>();
// 用一个LinkedList作为中介
LinkedList<KeyModel> temp = new LinkedList<KeyModel>();
// 初始化temp
for (int i = 0; i < count; i++) {
temp.add(new KeyModel(48 + i, i + ""));
}
// 取数
Random rand = new Random();
for (int i = 0; i < count; i++) {
int num = rand.nextInt(count - i);
resultList.add(new KeyModel(temp.get(num).getCode(), temp.get(num)
.getLable()));
temp.remove(num);
}
for (int i = 0; i < newkeyList.size(); i++) {
newkeyList.get(i).label = resultList.get(i).getLable();
newkeyList.get(i).codes[0] = resultList.get(i).getCode();
}
keyboardView.setKeyboard(k2);
}
private boolean isNumber(String str) {
String wordstr = "0123456789.,";
if (wordstr.indexOf(str) > -1) {
return true;
}
return false;
}
/**
* 键盘大小写切换
*/
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 if (key.sticky && key.codes[0] == Keyboard.KEYCODE_SHIFT) {
key.icon = resources.getDrawable(R.drawable.sym_keyboard_shift_normal);
}
}
} 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;
} else if (key.sticky && key.codes[0] == Keyboard.KEYCODE_SHIFT) {
key.icon = resources.getDrawable(R.drawable.sym_keyboard_shift_press);
}
}
}
}
public void showKeyboard() {
hideKeyBoard();
if (this.ed instanceof SafeEditText) {
Settings.System.putInt(this.act.getContentResolver(), Settings.System.TEXT_SHOW_PASSWORD, 0);
} else {
Settings.System.putInt(this.act.getContentResolver(), Settings.System.TEXT_SHOW_PASSWORD, 1);
}
rbLetter.setChecked(true);
int visibility = rlKeyboard.getVisibility();
if (visibility == View.GONE || visibility == View.INVISIBLE) {
rlKeyboard.setVisibility(View.VISIBLE);
rlKeyboard.startAnimation(AnimationUtils.loadAnimation(this.act, R.anim.show_keyboard));
}
}
public void hideKeyboard() {
Settings.System.putInt(this.act.getContentResolver(), Settings.System.TEXT_SHOW_PASSWORD, 1);
int visibility = rlKeyboard.getVisibility();
if (visibility == View.VISIBLE) {
rlKeyboard.setVisibility(View.INVISIBLE);
rlKeyboard.startAnimation(AnimationUtils.loadAnimation(this.act, R.anim.hide_keyboard));
}
}
private boolean isword(String str) {
String wordstr = "abcdefghijklmnopqrstuvwxyz";
if (wordstr.indexOf(str.toLowerCase()) > -1) {
return true;
}
return false;
}
/**
* 打开软键盘
*/
protected void openKeyBoard() {
hideKeyboard();
InputMethodManager imm = (InputMethodManager) this.ctx.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);
}
/**
* 关闭软键盘
*/
protected void hideKeyBoard() {
InputMethodManager inputMsg = (InputMethodManager) this.ctx.getSystemService(Context.INPUT_METHOD_SERVICE);
if (inputMsg.isActive()) { // 隐藏软键盘
View curView = this.act.getCurrentFocus();
if (curView != null) {
inputMsg.hideSoftInputFromWindow(curView.getWindowToken(), 0);
}
}
}
/**
* 震动
*
* @param duration
*/
protected void vibrate(long duration) {
Vibrator vibrator = (Vibrator) this.act.getSystemService(Context.VIBRATOR_SERVICE);
long[] pattern = {
0, duration
};
vibrator.vibrate(pattern, -1);
}
}
在activity中的使用:
edit = (EditText) this.findViewById(R.id.edit);
edit.setInputType(InputType.TYPE_NULL);
edit1 =(SafeEditText)this.findViewById(R.id.edit1);
edit.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
int inputback = edit.getInputType();
new KeyboardUtil(act, ctx, edit).showKeyboard();
edit.setInputType(inputback);
return false;
}
});
edit1.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
edit1.setText("");
int inputback = edit1.getInputType();
edit1.setInputType(InputType.TYPE_NULL);
new KeyboardUtil(act, ctx, edit1).showKeyboard();
edit1.setInputType(inputback);
return false;
}
});
最后还剩下一个问题,空格键有效点击部分只有中间一块,两边点击无效,还没找到方法,找到后更新
标签:
原文地址:http://blog.csdn.net/xiaoguiyixue/article/details/51556763