
前言自定义 身份证键盘 Activity 版 其余未做兼容一、IdCardUtil 工具类/** * 自定义身份证键盘工具类 */ public class IdCardUtil { private final Context context; private final EditText editText; private final PopupWindow popupWindow; private final View keyboardView; private static final int MAX_LENGTH 18; public IdCardUtil(Context context, EditText editText) { this.context context; this.editText editText; // 彻底禁用系统键盘 editText.setShowSoftInputOnFocus(false); editText.setInputType(InputType.TYPE_CLASS_TEXT); editText.setLongClickable(false); editText.setCursorVisible(false); keyboardView View.inflate(context, R.layout.view_id_card_keyboard, null); popupWindow new PopupWindow( keyboardView, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT ); popupWindow.setFocusable(false); popupWindow.setBackgroundDrawable(null); popupWindow.setOutsideTouchable(true); popupWindow.setTouchable(true); // 返回键关闭 keyboardView.setOnKeyListener((v, keyCode, event) - { if (keyCode KeyEvent.KEYCODE_BACK event.getAction() KeyEvent.ACTION_UP) { hideKeyboard(); return true; } return false; }); initListener(); initButtons(); } private void initListener() { // 触摸移动光标 → 键盘不消失 editText.setOnTouchListener((v, event) - { editText.setCursorVisible(true); if (!popupWindow.isShowing()) { closeAllOtherKeyboards(); showAtBottom(); } return false; }); // 焦点切换 editText.setOnFocusChangeListener((v, hasFocus) - { if (hasFocus) { closeAllOtherKeyboards(); editText.setCursorVisible(true); if (!popupWindow.isShowing()) { showAtBottom(); } } else { hideKeyboard(); editText.setCursorVisible(false); } }); } // 关闭其他所有键盘 private void closeAllOtherKeyboards() { try { InputMethodManager imm (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(editText.getWindowToken(), 0); View decorView ((android.app.Activity) context).getWindow().getDecorView(); clearFocus(decorView); } catch (Exception ignored) { } } private void clearFocus(View view) { if (view instanceof ViewGroup) { for (int i 0; i ((ViewGroup) view).getChildCount(); i) { clearFocus(((ViewGroup) view).getChildAt(i)); } } else if (view instanceof EditText view ! editText) { view.clearFocus(); } } private void initButtons() { int[] ids { R.id.btn_0, R.id.btn_1, R.id.btn_2, R.id.btn_3, R.id.btn_4, R.id.btn_5, R.id.btn_6, R.id.btn_7, R.id.btn_8, R.id.btn_9 }; for (int id : ids) { keyboardView.findViewById(id).setOnClickListener(v - { String num ((Button) v).getText().toString(); input(num); }); } keyboardView.findViewById(R.id.btn_x).setOnClickListener(v - input(X)); keyboardView.findViewById(R.id.btn_delete).setOnClickListener(v - delete()); } private void input(String text) { String current editText.getText().toString(); if (current.length() MAX_LENGTH) return; if (X.equals(text) current.length() ! 17) return; int start editText.getSelectionStart(); editText.getText().insert(start, text); } private void delete() { Editable ed editText.getText(); int start editText.getSelectionStart(); if (start 0) { ed.delete(start - 1, start); } } //不遮挡输入框 public void showAtBottom() { View decorView ((android.app.Activity) context).getWindow().getDecorView(); FrameLayout contentView ((android.app.Activity) context).findViewById(android.R.id.content); View rootView contentView.getChildAt(0); int[] location new int[2]; editText.getLocationInWindow(location); int screenHeight context.getResources().getDisplayMetrics().heightPixels; int keyboardHeight dp2px(220); // 自动滚动界面保证输入框完全露出不被键盘遮挡 int scrollY rootView.getScrollY(); int needScroll (location[1] editText.getHeight() keyboardHeight dp2px(20)) - screenHeight; if (needScroll 0) { rootView.scrollTo(0, scrollY needScroll); } popupWindow.showAtLocation(decorView, Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, 0); } public void hideKeyboard() { if (popupWindow.isShowing()) { popupWindow.dismiss(); } // 关闭时页面回滚 try { FrameLayout contentView ((android.app.Activity) context).findViewById(android.R.id.content); View rootView contentView.getChildAt(0); rootView.scrollTo(0, 0); } catch (Exception ignored) { } } public boolean isShowing() { return popupWindow.isShowing(); } private int dp2px(float dpValue) { final float scale context.getResources().getDisplayMetrics().density; return (int) (dpValue * scale 0.5f); } }二、布局文件view_id_card_keyboard?xml version1.0 encodingutf-8? LinearLayout xmlns:androidhttp://schemas.android.com/apk/res/android android:layout_widthmatch_parent android:layout_heightwrap_content android:backgrounddrawable/shape_bg_dialog android:orientationvertical android:padding5dp LinearLayout android:layout_widthmatch_parent android:layout_heightwrap_content android:orientationhorizontal Button android:idid/btn_1 android:layout_width0dp android:layout_height50dp android:layout_margindimen/dimen_5 android:layout_weight1 android:backgrounddrawable/shape_white_8 android:text1 android:textSize18sp / Button android:idid/btn_2 android:layout_width0dp android:layout_height50dp android:layout_margindimen/dimen_5 android:layout_weight1 android:backgrounddrawable/shape_white_8 android:text2 android:textSize18sp / Button android:idid/btn_3 android:layout_width0dp android:layout_height50dp android:layout_margindimen/dimen_5 android:layout_weight1 android:backgrounddrawable/shape_white_8 android:text3 android:textSize18sp / /LinearLayout LinearLayout android:layout_widthmatch_parent android:layout_heightwrap_content android:orientationhorizontal Button android:idid/btn_4 android:layout_width0dp android:layout_height50dp android:layout_margindimen/dimen_5 android:layout_weight1 android:backgrounddrawable/shape_white_8 android:text4 android:textSize18sp / Button android:idid/btn_5 android:layout_width0dp android:layout_height50dp android:layout_margindimen/dimen_5 android:layout_weight1 android:backgrounddrawable/shape_white_8 android:text5 android:textSize18sp / Button android:idid/btn_6 android:layout_width0dp android:layout_height50dp android:layout_margindimen/dimen_5 android:layout_weight1 android:backgrounddrawable/shape_white_8 android:text6 android:textSize18sp / /LinearLayout LinearLayout android:layout_widthmatch_parent android:layout_heightwrap_content android:orientationhorizontal Button android:idid/btn_7 android:layout_width0dp android:layout_height50dp android:layout_margindimen/dimen_5 android:layout_weight1 android:backgrounddrawable/shape_white_8 android:text7 android:textSize18sp / Button android:idid/btn_8 android:layout_width0dp android:layout_height50dp android:layout_margindimen/dimen_5 android:layout_weight1 android:backgrounddrawable/shape_white_8 android:text8 android:textSize18sp / Button android:idid/btn_9 android:layout_width0dp android:layout_height50dp android:layout_margindimen/dimen_5 android:layout_weight1 android:backgrounddrawable/shape_white_8 android:text9 android:textSize18sp / /LinearLayout LinearLayout android:layout_widthmatch_parent android:layout_heightwrap_content android:orientationhorizontal Button android:idid/btn_x android:layout_width0dp android:layout_height50dp android:layout_margindimen/dimen_5 android:layout_weight1 android:backgrounddrawable/shape_white_8 android:textX android:textSize18sp / Button android:idid/btn_0 android:layout_width0dp android:layout_height50dp android:layout_margindimen/dimen_5 android:layout_weight1 android:backgrounddrawable/shape_white_8 android:text0 android:textSize18sp / Button android:idid/btn_delete android:layout_width0dp android:layout_height50dp android:layout_margindimen/dimen_5 android:layout_weight1 android:backgrounddrawable/shape_white_8 android:text删除 android:textSize16sp / /LinearLayout /LinearLayout圆角shape_white_8?xml version1.0 encodingutf-8? shape xmlns:androidhttp://schemas.android.com/apk/res/android solid android:colorcolor/white / !-- 圆角 -- corners android:radiusdimen/dimen_8/ /shape半圆角 shape_bg_dialog?xml version1.0 encodingutf-8? shape xmlns:androidhttp://schemas.android.com/apk/res/android !-- solid实心就是填充的意思 -- solid android:colorcolor/c_f5f6f7 / !-- 圆角 -- corners android:topLeftRadiusdimen/dimen_10 android:topRightRadiusdimen/dimen_10/ /shape三、使用步骤EditText zjHmEdt findViewById(R.id.lq_zjhm_edt); IdCardUtil idCardKeyboardManager new IdCardUtil(this, zjHmEdt);// 返回键优先关闭身份证键盘 Override public void onBackPressed() { if (idCardKeyboardManager ! null idCardKeyboardManager.isShowing()) { idCardKeyboardManager.hideKeyboard(); return; } super.onBackPressed(); }