系统自带的键盘,键值太多,不符合客户的需求,需要自定义键盘,如下图:
分别是字母和数字的键盘,感谢很多前辈提供的例子,朋友们可以到这个链接下载资源:前辈android 自定义键盘详解讲的非常清楚,我下了他的代码,在这基础上进行修改,遇到的第一个问题就是第一个图上的: “ .?&” ,如何在键盘上显示这样的文本,假设采用楼主设置文本的形式进行设置的时候,会遇到如下错误:
<Key android:codes="-2" android:keyLabel=".?&" />
The entity name must immediately follow the ‘&’ in the entity reference
这个错误的解决方案是:
主要是xml无法解析 && 这样一个逻辑符号。所以要将他写出
<Key android:codes="-2" android:keyLabel=".?&" />这样就可以了。。
2.好,接着第二个问题:其他特殊符合如“,”之类的都可以使用转义字符,但遇到“@”,你就不能好好的使用转义字符来解决了:
<Key android:codes="64" android:keyLabel="@" />
上述代码同样会报一个这样的错误:error: Error: No resource type
specified (at 'keyLabel' with value '@').万能的百度也没有搜到解决方
案,我就很奇怪,不是已经转义了吗?怎么还是识别不了呢,后来想想是不是xml
文件会不会认为@后面还得跟个什么东西,所以这样写就是有错的,那好我就再用
如下语句:“\”来进行转义,应该就可以了,我修改成如下的代码,保存,运行
没有出错了。
<Key android:codes="64" android:keyLabel="\@" />
<Key android:codes="-5" android:keyEdgeFlags="right" android:isRepeatable="true"android:keyIcon="@drawable/sym_keyboard_delete" />
注意:如果你使用到图片的话,@drawable/delete这样的时候,也需要将@进行转义,这个问题的确很奇怪,我在另外一个xml文件直接使用是没有问题的,不知道是什么原因,大神如果知道的话,麻烦告诉一声。
3.第三个问题:遇到键盘上要显示反斜杠,也就是“\”的时候,因为\是起转义
字符的作用,所以要显示\,需要再进行转义一次,也就是如下语句:
<Key android:codes="92" android:keyLabel="\\" />
4.在设置了edittext之后,要隐藏系统的软键盘,这时候就会遇到奇怪的问
题,光标消失了并且没有闪烁,所以百度了一下,将edittext传入到函数里面
,然后就可以使用如下方法,就可以使光标出现:
edit = (EditText) this.findViewById(R.id.edit); // edit.setInputType(InputType.TYPE_NULL); hideSoftInputMethod(edit);
// 隐藏系统键盘 public void hideSoftInputMethod(EditText ed) { getWindow().setSoftInputMode( WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); int currentVersion = android.os.Build.VERSION.SDK_INT; String methodName = null; if (currentVersion >= 16) { // 4.2 methodName = "setShowSoftInputOnFocus"; } else if (currentVersion >= 14) { // 4.0 methodName = "setSoftInputShownOnFocus"; } if (methodName == null) { ed.setInputType(InputType.TYPE_NULL); } else { Class<EditText> cls = EditText.class; Method setShowSoftInputOnFocus; try { setShowSoftInputOnFocus = cls.getMethod(methodName, boolean.class); setShowSoftInputOnFocus.setAccessible(true); setShowSoftInputOnFocus.invoke(ed, false); } catch (NoSuchMethodException e) { ed.setInputType(InputType.TYPE_NULL); e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
5.如果你有如下的需求:在点击界面上任何一个edittext,弹出自定义键盘还
有一个按钮,用来隐藏自定义键盘,如下图:
也就是点击隐藏的图标,隐藏掉自定义键盘,这个需求其实蛮简单的:就是需要
给显示键盘的布局一个id,当点击隐藏按钮之后,将布局Visibility的属性设置
为Gone或者InVisibility,其中gone表示不占空间和内存。示例如下(部分代
码:
private RelativeLayout relakey; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); ctx = this; act = this; relakey = (RelativeLayout) this.findViewById(R.id.relakey); hideshow = (TextView) this.findViewById(R.id.hideshow); hideshow.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { relakey.setVisibility(View.GONE); } }); edit = (EditText) this.findViewById(R.id.edit); // edit.setInputType(InputType.TYPE_NULL); hideSoftInputMethod(edit); edit.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { relakey.setVisibility(View.VISIBLE); hideshow.setVisibility(View.VISIBLE); new KeyboardUtil(act, ctx, edit).showKeyboard(); return false; } });</span>
<?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" android:orientation="vertical" > <EditText android:id="@+id/edit" android:layout_width="fill_parent" android:layout_height="wrap_content" /> <EditText android:id="@+id/edit1" android:layout_width="fill_parent" android:layout_height="wrap_content" /> <View android:layout_width="wrap_content" android:layout_height="270dp" /> <span style="color:#ff0000;"><strong> <RelativeLayout android:id="@+id/relakey" android:layout_width="fill_parent" android:layout_height="wrap_content" android:padding="3dp" android:visibility="invisible"> <!-- 这个其实就是需要隐藏的布局,用来控制键盘是否显示与隐藏--> <TextView android:id="@+id/hideshow" android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="@drawable/ret" android:visibility="invisible" /> <android.inputmethodservice.KeyboardView android:id="@+id/keyboard_view" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:background="@color/white" android:focusable="true" android:focusableInTouchMode="true" android:keyBackground="@drawable/d" android:keyTextColor="@color/white" android:keyTextSize="20sp" android:labelTextSize="15sp" android:padding="3dp" android:visibility="invisible" /></span> </RelativeLayout> </LinearLayout>
6.其他的问题如给key按键设置自己的图片,我会遇到莫名其妙的问题,就是图片太大,把键盘挤出去了,而我使用系统默认的比如删除、切换大小写之类的图片就不会出现这样的问题,期待大神给予帮助,目前为止还未解决。
7.最后一个问题,如果看过这篇博文的人,android 自定义键盘(前辈)应该都知道如果要自定义键盘的话,需要重写里面的键盘布局xml文件,其实是很简单,就是一行一行的进行配置即可,下面对于一些属性我加上自己的使用经验和理解,希望给菜鸟一些帮助。
<?xml version="1.0" encoding="UTF-8"?> <Keyboard android:keyWidth="9.55%p" android:keyHeight="@dimen/key_height2" android:horizontalGap="1px" android:verticalGap="3px" xmlns:android="http://schemas.android.com/apk/res/android"> <Row> <Key android:codes="49" android:keyEdgeFlags="left" android:keyLabel="1" /> <Key android:codes="50" android:keyLabel="2" /> <Key android:codes="51" android:keyLabel="3" /> <Key android:codes="52" android:keyLabel="4" /> <Key android:codes="53" android:keyLabel="5" /> <Key android:codes="54" android:keyLabel="6" /> <Key android:codes="55" android:keyLabel="7" /> <Key android:codes="56" android:keyLabel="8" /> <Key android:codes="57" android:keyLabel="9" /> <Key android:codes="48" android:keyLabel="0" android:keyEdgeFlags="right" /> </Row> </Keyboard>下面是各个属性的解释:
(1)android:keyWidth="9.55%p":该属性表示每个键盘上的单个按键占据的宽度百分比,举个例子是:键盘总共有3行,每行有10个的话,那么每个按键就是
10%。
(2)android:keyHeight="@dimen/key_height2":该属性用来设置每个单个按键所占的高度,具体的就不细说了,可以用dimen进行灵活配置。
(3)android:horizontalGap="1px" android:verticalGap="3px":这两个属性表示:每个按键之间在水平和竖直方向的间距,为了美观,该属性是必须设置的否则你会发现你的键盘丑死了,都挤到一块去了。
(4)android:keyEdgeFlags="left":表示对于整个键盘这一行来说,这个按键是居于最左边的,也可以设置成最右边,这个属性我发现如果不设置的话,也不影响键盘的正常显示。
(5android:keyLabel="3":该属性表示按键显示的文本,可以随意填,但如果碰到一些xml文件中不能直接显示的字符如&、@、‘等需要转义,如何转义可以参考上面的第一条建议。
(6)android:codes="48":这个对于该自定义键盘来说是非常重要的一个属表示对于一些数字、字母、标点符号等所有能在键盘找到的,必须用ascii码来对应,对于这些char字符对应的ascii的对应关系,好吧,我就告诉你们,链接如下:ascii码转换表ascii转换对应表当然了,如果想输入一些奇怪的东西,建议你的codes值不要与ascii码相同,可以取得很大,就不会有冲突了。
(7)android:keyIcon="@drawable/sym_keyboard_shift":该属性表示对于该按键,你可以自定义自己的图片放上去。
(8)android:isRepeatable="true":表示对于该按键长按是否会连续输入,这个属性对于删除键来说极其有效。
如果你用心的阅读完上述的内容,你肯定也可以设计出自己的自定义键盘,有问题随时与我交流,可以在下方评论,我会及时给与解答。
真的要放大福利了,我的android 自定义键盘(包含字母、标点符号)的完善版本已经上传到csdn,链接如下:android 自定义键盘 (nihaoqiulinhe所有)
==================================分割线,更新日期2015年12月21日11:13:55==========================================
当输入自定义的键盘上的数字时,比如说如果是300000,有这样一个需求,当点击300000时,要清除掉之前的数据,切换时也需要清除掉,如下键盘代码:
package client.verbank.mtp.allone.util; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.security.SecureRandom; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import java.util.Random; import android.annotation.TargetApi; import android.app.Activity; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Rect; import android.inputmethodservice.Keyboard; import android.inputmethodservice.Keyboard.Key; import android.inputmethodservice.KeyboardView; import android.inputmethodservice.KeyboardView.OnKeyboardActionListener; import android.os.Build; import android.os.SystemClock; import android.text.Editable; import android.util.AttributeSet; import android.util.DisplayMetrics; import android.view.ActionMode; import android.view.Display; import android.view.Gravity; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.Window; import android.view.WindowManager; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputMethodManager; import android.widget.EditText; import android.widget.PopupWindow; import android.widget.PopupWindow.OnDismissListener; import client.verbank.mtp.allone.R; import client.verbank.mtp.allone.consts.ISystemCommData; /** * 数字键盘:专门针对金额的键盘,不能输入小数位 * * @Project: FEIB_AndroidStation * @Title: MyKeyboardDigital.java * @Package client.verbank.mtp.allone.util * @Description: TODO * @author qiulinhe [email protected] * @date 2015年10月14日 上午11:04:48 * @Copyright: 2015 www.allone.cn Inc. All rights reserved. * @version V3.0.0 */ public class MyKeyboardDigitalAmount extends EditText implements OnKeyboardActionListener, ISystemCommData { private Keyboard k1;// 字母键盘 private Keyboard k2;// 标点符号键盘 private Keyboard k3;// 数字键盘 public boolean isnun = false;// 是否标点符号键盘 public boolean isupper = false;// 是否大写 private KeyboardView mKeyboardView; private Keyboard mKeyboard; private Window mWindow; private View mDecorView; private View mContentView; private PopupWindow mKeyboardWindow; private boolean needcustomkeyboard = true; // 是否启用自定义键盘 private boolean randomkeys = false; // 数字按键是否随机 private int scrolldis = 100; // 输入框在键盘被弹出时,要被推上去的距离 public static int screenw = -1;// 未知宽高 public static int screenh = -1; public static int screenh_nonavbar = -1; // 不包含导航栏的高度 public static int real_scontenth = -1; // 实际内容高度, 计算公式:屏幕高度-导航栏高度-电量栏高度 public static float density = 1.0f; public static int densityDpi = 160; // 接收用户在系统设定界面的自定义金额 String selfdig20 = "200,000"; String orgindi20 = "200,000"; // 接收用户在系统设定界面的自定义金额 String selfdig50 = "500,000"; String orgindi50 = "500,000"; // 接收用户在系统设定界面的自定义金额 String selfdig100 = "1,000,000"; String orgindi100 = "1,000,000"; /** * @param context * * @param attrs */ public MyKeyboardDigitalAmount(Context context, AttributeSet attrs) { super(context, attrs); initAttributes(context); initKeyboard(context, attrs); // TODO Auto-generated constructor stub } /** * @param context * @param attrs * @param defStyle */ public MyKeyboardDigitalAmount(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); selfdig20 = SharepreferencesUtilSystemSettings.getValue(getContext(), System_key_SelfAmout2, "200,000"); selfdig50 = SharepreferencesUtilSystemSettings.getValue(getContext(), System_key_SelfAmout5, "500,000"); selfdig100 = SharepreferencesUtilSystemSettings.getValue(getContext(), System_key_SelfAmout10, "1,000,000"); initAttributes(context); initKeyboard(context, attrs); // TODO Auto-generated constructor stub } private void initKeyboard(Context context, AttributeSet attrs) { selfdig20 = SharepreferencesUtilSystemSettings.getValue(getContext(), System_key_SelfAmout2, "200,000"); selfdig50 = SharepreferencesUtilSystemSettings.getValue(getContext(), System_key_SelfAmout5, "500,000"); selfdig100 = SharepreferencesUtilSystemSettings.getValue(getContext(), System_key_SelfAmout10, "1,000,000"); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.keyboard); if (a.hasValue(R.styleable.keyboard_xml)) { needcustomkeyboard = true; int xmlid = a.getResourceId(R.styleable.keyboard_xml, 0); mKeyboard = new Keyboard(context, xmlid); mKeyboardView = (KeyboardView) LayoutInflater.from(context) .inflate(R.layout.mykeyboardviewdigit, null); if (a.hasValue(R.styleable.keyboard_randomkeys)) { boolean random = a.getBoolean(R.styleable.keyboard_randomkeys, false); randomkeys = random; if (random) { randomdigkey(mKeyboard); } } selfdig20 = SharepreferencesUtilSystemSettings.getValue( getContext(), System_key_SelfAmout2, "200,000"); selfdig50 = SharepreferencesUtilSystemSettings.getValue( getContext(), System_key_SelfAmout5, "500,000"); selfdig100 = SharepreferencesUtilSystemSettings.getValue( getContext(), System_key_SelfAmout10, "1,000,000"); selfdigkey(); // mKeyboardView.setKeyboard(mKeyboard); mKeyboardView.setEnabled(true); mKeyboardView.setPreviewEnabled(false); mKeyboardView.setOnKeyboardActionListener(this); mKeyboardWindow = new PopupWindow(mKeyboardView, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); mKeyboardWindow.setAnimationStyle(R.style.AnimationFade); // mKeyboardWindow.setBackgroundDrawable(new BitmapDrawable()); // mKeyboardWindow.setOutsideTouchable(true); mKeyboardWindow.setOnDismissListener(new OnDismissListener() { @Override public void onDismiss() { // TODO Auto-generated method stub if (scrolldis > 0) { int temp = scrolldis; // scrolldis = 0; if (null != mContentView) { mContentView.scrollBy(0, -temp); } } } }); } else { needcustomkeyboard = false; } a.recycle(); } private void showKeyboard() { if (null != mKeyboardWindow) { if (!mKeyboardWindow.isShowing()) { if (randomkeys) { randomdigkey(mKeyboard); } selfdig20 = SharepreferencesUtilSystemSettings.getValue( getContext(), System_key_SelfAmout2, "200,000"); selfdig50 = SharepreferencesUtilSystemSettings.getValue( getContext(), System_key_SelfAmout5, "500,000"); selfdig100 = SharepreferencesUtilSystemSettings.getValue( getContext(), System_key_SelfAmout10, "1,000,000"); selfdigkey(); // mKeyboardView.setKeyboard(mKeyboard); mKeyboardWindow.setAnimationStyle(R.style.AnimBottom); mKeyboardWindow.showAtLocation(this.mDecorView, Gravity.RIGHT | Gravity.BOTTOM, 0, 0); mKeyboardWindow.update(); if (null != mDecorView && null != mContentView) { int[] pos = new int[2]; // 计算弹出的键盘的尺寸 getLocationOnScreen(pos); float height = dpToPx(getContext(), 240); // int []hsmlpos=new int[2]; // mDecorView.getLocationOnScreen(hsmlpos); Rect outRect = new Rect(); // 然后该View有个getWindowVisibleDisplayFrame()方法可以获取到程序显示的区域, // * 包括标题栏,但不包括状态栏。 mDecorView.getWindowVisibleDisplayFrame(outRect);// 获得view空间,也就是除掉标题栏 // outRect.top表示状态栏(通知栏) int screen = real_scontenth; // scrolldis = (int) ((pos[1] + getMeasuredHeight() - // outRect.top) // - (screen - height) + 500); if (scrolldis > 0) { mContentView.scrollBy(0, scrolldis); } } } } } private void hideKeyboard() { if (null != mKeyboardWindow) { if (mKeyboardWindow.isShowing()) { mKeyboardWindow.dismiss(); } } } private void hideSysInput() { if (this.getWindowToken() != null) { InputMethodManager imm = (InputMethodManager) getContext() .getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(this.getWindowToken(), 0); } } @Override public boolean onTouchEvent(MotionEvent event) { super.onTouchEvent(event); requestFocus(); requestFocusFromTouch(); if (needcustomkeyboard) { hideSysInput(); showKeyboard(); } return true; } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { if (null != mKeyboardWindow) { if (mKeyboardWindow.isShowing()) { mKeyboardWindow.dismiss(); return true; } } } return super.onKeyDown(keyCode, event); } @Override public void onAttachedToWindow() { super.onAttachedToWindow(); this.mWindow = ((Activity) getContext()).getWindow(); this.mDecorView = this.mWindow.getDecorView(); this.mContentView = this.mWindow .findViewById(Window.ID_ANDROID_CONTENT); hideSysInput(); } @Override public void onDetachedFromWindow() { super.onDetachedFromWindow(); hideKeyboard(); mKeyboardWindow = null; mKeyboardView = null; mKeyboard = null; mDecorView = null; mContentView = null; mWindow = null; } @Override public void onPress(int primaryCode) { // TODO Auto-generated method stub } @Override public void onRelease(int primaryCode) { // TODO Auto-generated method stub } @Override public void onKey(int primaryCode, int[] keyCodes) { // TODO Auto-generated method stub Editable editable = this.getText(); int start = this.getSelectionStart(); if (primaryCode == Keyboard.KEYCODE_CANCEL) {// 隐藏键盘 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(); mKeyboardView.setKeyboard(k1); } else if (primaryCode == Keyboard.KEYCODE_DONE) {// 标点符号键盘切换 if (isnun) { isnun = false; mKeyboardView.setKeyboard(k1); } else { isnun = true; mKeyboardView.setKeyboard(k2); } } // else if (primaryCode == 46) { // // // 当用户输入.3的时候自动转换为0.3 // if (editable != null && editable.length() > 0) { // if (start > 0) { // editable.insert(start, "."); // } // } else { // editable.insert(start, "0."); // } // // } else if (primaryCode == -110) { editable.insert(start, "00"); } else if (primaryCode == -20000) { editable.clear(); editable.insert(0, selfdig20); } else if (primaryCode == -50000) { editable.clear(); editable.insert(0, selfdig50); } else if (primaryCode == -10000) { editable.clear(); editable.insert(0, selfdig100); } else if (0x0 <= primaryCode && primaryCode <= 0x7f) { // 可以直接输入的字符(如0-9,.),他们在键盘映射xml中的keycode值必须配置为该字符的ASCII码 editable.insert(start, Character.toString((char) primaryCode)); } else if (primaryCode > 0x7f) { Key mkey = getKeyByKeyCode(primaryCode); // 可以直接输入的字符(如0-9,.),他们在键盘映射xml中的keycode值必须配置为该字符的ASCII码 editable.insert(start, mkey.label); } else { // 其他一些暂未开放的键指令,如next到下一个输入框等指令 } } // 数字键盘测试是否改变200,000和500,000让用户自定义 private void selfdigkey() { if (mKeyboard == null) { return; } List<Key> keyList = k3.getKeys(); // 查找出0-9的数字键 for (int i = 0, size = keyList.size(); i < size; i++) { Key key = keyList.get(i); CharSequence label = key.label; // if (label != null && label.toString().equals(orgindi20)) { // keyList.get(i).label = selfdig; // orgindi20 = selfdig; // } if (label != null && label.toString().equals(orgindi20)) { keyList.get(i).label = selfdig20; keyList.get(i).codes[0] = -20000; orgindi20 = selfdig20; } if (label != null && label.toString().equals(orgindi50)) { keyList.get(i).label = selfdig50; keyList.get(i).codes[0] = -50000; orgindi50 = selfdig50; } if (label != null && label.toString().equals(orgindi100)) { keyList.get(i).label = selfdig100; keyList.get(i).codes[0] = -10000; orgindi100 = selfdig100; } } mKeyboardView.setKeyboard(k3); } /** * 键盘大小写切换 */ 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; } } } } private boolean isword(String str) { String wordstr = "abcdefghijklmnopqrstuvwxyz"; if (wordstr.indexOf(str.toLowerCase()) > -1) { return true; } return false; } @Override public void onText(CharSequence text) { // TODO Auto-generated method stub } @Override public void swipeLeft() { // TODO Auto-generated method stub } @Override public void swipeRight() { // TODO Auto-generated method stub } @Override public void swipeDown() { // TODO Auto-generated method stub } @Override public void swipeUp() { // TODO Auto-generated method stub } private Key getKeyByKeyCode(int keyCode) { if (null != mKeyboard) { List<Key> mKeys = mKeyboard.getKeys(); for (int i = 0, size = mKeys.size(); i < size; i++) { Key mKey = mKeys.get(i); int codes[] = mKey.codes; if (codes[0] == keyCode) { return mKey; } } } return null; } private void initAttributes(Context context) { k1 = new Keyboard(context, R.xml.qwerty); k2 = new Keyboard(context, R.xml.qwerty2); k3 = new Keyboard(context, R.xml.amountinputkeyboard); initScreenParams(context); this.setLongClickable(false); this.setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI); removeCopyAbility(); if (this.getText() != null) { this.setSelection(this.getText().length()); } this.setOnFocusChangeListener(new OnFocusChangeListener() { @Override public void onFocusChange(View v, boolean hasFocus) { // TODO Auto-generated method stub if (!hasFocus) { hideKeyboard(); } } }); } @TargetApi(11) private void removeCopyAbility() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { this.setCustomSelectionActionModeCallback(new ActionMode.Callback() { @Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { return false; } @Override public boolean onPrepareActionMode(ActionMode mode, Menu menu) { return false; } @Override public void onDestroyActionMode(ActionMode mode) { } @Override public boolean onActionItemClicked(ActionMode mode, MenuItem item) { return false; } }); } } private boolean isNumber(String str) { String wordstr = "0123456789"; if (wordstr.indexOf(str) > -1) { return true; } return false; } private void randomdigkey(Keyboard mKeyboard) { if (mKeyboard == null) { return; } List<Key> keyList = mKeyboard.getKeys(); // 查找出0-9的数字键 List<Key> newkeyList = new ArrayList<Key>(); for (int i = 0, size = keyList.size(); i < size; i++) { Key key = keyList.get(i); CharSequence label = key.label; if (label != null && isNumber(label.toString())) { newkeyList.add(key); } } int count = newkeyList.size(); List<KeyModel> resultList = new ArrayList<KeyModel>(); LinkedList<KeyModel> temp = new LinkedList<KeyModel>(); for (int i = 0; i < count; i++) { temp.add(new KeyModel(48 + i, i + "")); } Random rand = new SecureRandom(); rand.setSeed(SystemClock.currentThreadTimeMillis()); for (int i = 0; i < count; i++) { int num = rand.nextInt(count - i); KeyModel model = temp.get(num); resultList.add(new KeyModel(model.getCode(), model.getLable())); temp.remove(num); } for (int i = 0, size = newkeyList.size(); i < size; i++) { Key newKey = newkeyList.get(i); KeyModel resultmodle = resultList.get(i); newKey.label = resultmodle.getLable(); newKey.codes[0] = resultmodle.getCode(); } } class KeyModel { private Integer code; private String label; public KeyModel(Integer code, String lable) { this.code = code; this.label = lable; } public Integer getCode() { return code; } public void setCode(Integer code) { this.code = code; } public String getLable() { return label; } public void setLabel(String lable) { this.label = lable; } } /** * 密度转换为像素值 * * @param dp * @return */ public static int dpToPx(Context context, float dp) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (dp * scale + 0.5f); } private void initScreenParams(Context context) { DisplayMetrics dMetrics = new DisplayMetrics(); WindowManager windowManager = (WindowManager) context .getSystemService(Context.WINDOW_SERVICE); Display display = windowManager.getDefaultDisplay(); display.getMetrics(dMetrics); screenw = dMetrics.widthPixels; screenh = dMetrics.heightPixels; density = dMetrics.density; densityDpi = dMetrics.densityDpi; screenh_nonavbar = screenh; int ver = Build.VERSION.SDK_INT; // 新版本的android 系统有导航栏,造成无法正确获取高度 if (ver == 13) { try { Method mt = display.getClass().getMethod("getRealHeight"); screenh_nonavbar = (Integer) mt.invoke(display); } catch (Exception e) { } } else if (ver > 13) { try { Method mt = display.getClass().getMethod("getRawHeight"); screenh_nonavbar = (Integer) mt.invoke(display); } catch (Exception e) { } } real_scontenth = screenh_nonavbar - getStatusBarHeight(context); } /** * 电量栏高度 * * @return */ public static int getStatusBarHeight(Context context) { Class<?> c = null; Object obj = null; Field field = null; int x = 0, sbar = 0; try { c = Class.forName("com.android.internal.R$dimen"); obj = c.newInstance(); field = c.getField("status_bar_height"); x = Integer.parseInt(field.get(obj).toString()); sbar = context.getResources().getDimensionPixelSize(x); } catch (Exception e1) { e1.printStackTrace(); } return sbar; } }