Android绑定EditText自动弹出自定义软键盘不同按键设置不同背景的实现(自动向上顶适应布局)
来源:互联网 发布:兰黛丽莎香水知乎 编辑:程序博客网 时间:2024/05/16 12:31
最近公司项目有个需求,就是所有需要输入密码的EditText需要弹出自定义软键盘来代替系统键盘,于是就在网上找了些相关demo来学习借鉴一下。下面是我的实现大概思路,涉及主要功能模块三个类:
1、CustomKeyboardView一个自定义keyboradview,通过重新KeyboardView来实现自己的需求业务,主要重写onDraw()方法来给不同按键设置不同的背景;
public class CustomKeyboardView extends KeyboardView { private int paddingTop; private Paint paint; private float shift_startx, shift_endx, shift_starty, shift_endy; private float del_startx, del_endx, del_starty, del_endy; private float p_startx, p_endy; private float q_startx, q_endx, q_starty, q_endy; private int keyWidth; private int keyHeight; private Context context; private int keyboardView_height; private PopupWindow mPreviewPopup; public CustomKeyboardView(Context context, AttributeSet attrs) { super(context, attrs); paddingTop = getPaddingTop(); this.context = context; } @Override public void onDraw(Canvas canvas) { super.onDraw(canvas); post(new Runnable() { @Override public void run() { getWidth(); // 获取宽度 keyboardView_height = getHeight();// 获取高度 MyLog.e(toString(), "keyboardViewHeight=" + keyboardView_height); } }); List<Keyboard.Key> keys = getKeyboard().getKeys(); paint = new Paint(); paint.setTextSize(UiUtils.dip2px(30)); Rect lRect = new Rect(); Paint.FontMetrics fontMetrics = paint.getFontMetrics(); float fontTotalHeight = fontMetrics.bottom - fontMetrics.top; float offY = fontTotalHeight / 2 - fontMetrics.bottom; //对不同按键设置不同背景图片 for (final Keyboard.Key key : keys) { switch (key.codes[0]) { case 0: //顶部标题 Drawable dr_icon = getResources().getDrawable(R.drawable.safe_icon); //宽高比例3:4 dr_icon.setBounds(UiUtils.dip2px(18), UiUtils.dip2px(7), UiUtils.dip2px(30), UiUtils.dip2px(23)); dr_icon.draw(canvas); Paint paint_title = new Paint(); paint_title.setTextSize(UiUtils.dip2px(13)); paint_title.setColor(getResources().getColor(R.color.bg_deep_orange)); String str_title = "XXX安全键盘"; paint_title.getTextBounds(str_title, 0, str_title.length(), lRect); canvas.drawText(str_title, key.x + UiUtils.dip2px(33), key.height - UiUtils.dip2px(5), paint_title); break; case -10: //顶部完成键 Paint paint_complete = new Paint(); paint_complete.setTextSize(UiUtils.dip2px(18)); paint_complete.setColor(getResources().getColor(R.color.txt_blue)); String str_com = "完成"; paint_complete.getTextBounds(str_com, 0, str_com.length(), lRect); canvas.drawText(str_com, key.x - UiUtils.dip2px(5), key.height - UiUtils.dip2px(3), paint_complete); break; case 112: //p p_startx = key.x; p_endy = key.y + key.height + paddingTop; break; case -1: shift_startx = key.x; shift_endx = key.x + key.width; shift_starty = key.y; shift_endy = key.y + key.height + paddingTop;// MyLog.e("xx_shift","key.width="+key.width+";key.height="+key.height); //Shift Drawable dr_press_shift = getResources().getDrawable(R.drawable.bg_shift_press); Drawable dr_shift = getResources().getDrawable(R.drawable.bg_shift); dr_press_shift.setBounds(key.x, key.y + paddingTop, key.x + key.width, key.y + key.height + paddingTop); dr_shift.setBounds(key.x, key.y + paddingTop, key.x + key.width, key.y + key.height + paddingTop); if (KeyboardUtil.shiftPressed) { dr_press_shift.draw(canvas); } else { dr_shift.draw(canvas); } break; case -5: del_startx = key.x; del_endx = key.x + key.width; del_starty = key.y; del_endy = key.y + key.height + paddingTop; //Del if (isNormal) { Drawable dr_press_del = getResources().getDrawable(R.drawable.bg_del_press); Drawable dr_del = getResources().getDrawable(R.drawable.bg_del); drawKeyBackground(canvas, key, dr_press_del, dr_del); } else { Drawable dr_press_del = getResources().getDrawable(R.drawable.bg_num_del_press); Drawable dr_del = getResources().getDrawable(R.drawable.bg_num_del); drawKeyBackground(canvas, key, dr_press_del, dr_del); } break; case 32: //Space Drawable dr_press_space = getResources().getDrawable(R.drawable.bg_space_press); Drawable dr_space = getResources().getDrawable(R.drawable.bg_space); drawKeyBackground(canvas, key, dr_press_space, dr_space); break; case -3: //complete Drawable dr_complete = getResources().getDrawable(R.drawable.bg_complete); dr_complete.setBounds(key.x, key.y + paddingTop, key.x + key.width, key.y + key.height + paddingTop); dr_complete.draw(canvas); break; case -2: //123/ABC if (isNormal) { Drawable dr_switch = getResources().getDrawable(R.drawable.bg_num); dr_switch.setBounds(key.x, key.y + paddingTop, key.x + key.width, key.y + key.height + paddingTop); dr_switch.draw(canvas); Paint paint = new Paint(); paint.setTextSize(UiUtils.dip2px(20)); paint.getTextBounds("123", 0, "123".length(), lRect); float baseLineX = key.width / 2 - lRect.width() / 2 - key.gap / 2; float baseLineY = key.y + key.height / 2 + offY - paddingTop / 2; canvas.drawText("123", baseLineX, baseLineY, paint); } else { Paint paint = new Paint(); paint.setTextSize(UiUtils.dip2px(25)); paint.getTextBounds("ABC", 0, "ABC".length(), lRect); float baseLineX_ABC = key.width / 2 - lRect.width() / 2; float baseLineY_ABC = key.y + key.height / 2 + offY; Drawable dr_pres = getResources().getDrawable(R.drawable.bg_num_press); Drawable dr = getResources().getDrawable(R.drawable.bg_num_nor); dr_pres.setBounds(key.x, key.y + paddingTop, key.x + key.width, key.y + key.height + paddingTop); dr.setBounds(key.x, key.y + paddingTop, key.x + key.width, key.y + key.height + paddingTop); if (key.pressed) { dr_pres.draw(canvas); } else { dr.draw(canvas); } canvas.drawText("ABC", baseLineX_ABC - key.gap / 2, baseLineY_ABC + paddingTop / 2, paint); } break; case 48: //0 paint.getTextBounds("0", 0, "0".length(), lRect); float baseLineX_0 = key.width / 2 + key.width - lRect.width() / 2; float baseLineY_0 = key.y + key.height / 2 + offY; drawNumKeyBackground(canvas, key, "0", baseLineX_0, baseLineY_0); break; case 49: //1 paint.getTextBounds("1", 0, "1".length(), lRect); float baseLineX_1 = key.width / 2 - lRect.width() / 2 - key.gap; float baseLineY_1 = key.y + key.height / 2 + offY; drawNumKeyBackground(canvas, key, "1", baseLineX_1, baseLineY_1); break; case 50: //2 paint.getTextBounds("2", 0, "2".length(), lRect); float baseLineX_2 = key.width / 2 + key.width - lRect.width() / 2; float baseLineY_2 = key.y + key.height / 2 + offY; drawNumKeyBackground(canvas, key, "2", baseLineX_2, baseLineY_2); break; case 51: //3 paint.getTextBounds("3", 0, "3".length(), lRect); float baseLineX_3 = key.width / 2 + key.width * 2 - lRect.width() / 2; float baseLineY_3 = key.y + key.height / 2 + offY; drawNumKeyBackground(canvas, key, "3", baseLineX_3, baseLineY_3); break; case 52: //4 paint.getTextBounds("4", 0, "4".length(), lRect); float baseLineX_4 = key.width / 2 - lRect.width() / 2; float baseLineY_4 = key.y + key.height / 2 + offY; drawNumKeyBackground(canvas, key, "4", baseLineX_4, baseLineY_4); break; case 53: //5 paint.getTextBounds("5", 0, "5".length(), lRect); float baseLineX_5 = key.width / 2 + key.width - lRect.width() / 2; float baseLineY_5 = key.y + key.height / 2 + offY; drawNumKeyBackground(canvas, key, "5", baseLineX_5, baseLineY_5); break; case 54: //6 paint.getTextBounds("6", 0, "6".length(), lRect); float baseLineX_6 = key.width / 2 + key.width * 2 - lRect.width() / 2; float baseLineY_6 = key.y + key.height / 2 + offY; drawNumKeyBackground(canvas, key, "6", baseLineX_6, baseLineY_6); break; case 55: //7 paint.getTextBounds("7", 0, "7".length(), lRect); float baseLineX_7 = key.width / 2 - lRect.width() / 2; float baseLineY_7 = key.y + key.height / 2 + offY; drawNumKeyBackground(canvas, key, "7", baseLineX_7, baseLineY_7); break; case 56: //8 paint.getTextBounds("8", 0, "8".length(), lRect); float baseLineX_8 = key.width / 2 + key.width - lRect.width() / 2; float baseLineY_8 = key.y + key.height / 2 + offY; drawNumKeyBackground(canvas, key, "8", baseLineX_8, baseLineY_8); break; case 57: //9 paint.getTextBounds("9", 0, "9".length(), lRect); float baseLineX_9 = key.width / 2 + key.width * 2 - lRect.width() / 2; float baseLineY_9 = key.y + key.height / 2 + offY; drawNumKeyBackground(canvas, key, "9", baseLineX_9, baseLineY_9); break; default: break; } } } @Override public boolean onTouchEvent(MotionEvent event) { float x = event.getX(); float y = event.getY(); if (event.getAction() == MotionEvent.ACTION_MOVE) { if (isNormal) { //屏蔽相关按键的move事件 if (x <= shift_endx && y >= shift_starty || x >= del_startx && y >= del_starty || y >= del_endy) {// closePreviewPopup(); return true; } else if (y < p_endy * 2 / 3) { return true; } else { setPreviewEnabled(true); return super.onTouchEvent(event); } } else { return super.onTouchEvent(event); } } else if (event.getAction() == MotionEvent.ACTION_UP) { closePreviewPopup(); return super.onTouchEvent(event); } else { return super.onTouchEvent(event); } } /** * @param canvas * @param key 对应的按键 * @param press_dr 按下背景图 * @param nor_dr 默认背景图 * 字母键盘背景绘制 */ private void drawKeyBackground(Canvas canvas, Keyboard.Key key, Drawable press_dr, Drawable nor_dr) { press_dr.setBounds(key.x, key.y + paddingTop, key.x + key.width, key.y + key.height + paddingTop); nor_dr.setBounds(key.x, key.y + paddingTop, key.x + key.width, key.y + key.height + paddingTop); if (key.pressed) { press_dr.draw(canvas); } else { nor_dr.draw(canvas); } } /** * @param canvas * @param key * @param str 背景文字 * @param x 起始x坐标 * @param y 起始y坐标 * 数字键盘背景绘制 */ private void drawNumKeyBackground(Canvas canvas, Keyboard.Key key, String str, float x, float y) { Drawable dr_pres = getResources().getDrawable(R.drawable.bg_num_press); Drawable dr = getResources().getDrawable(R.drawable.bg_num_nor); dr_pres.setBounds(key.x, key.y + paddingTop, key.x + key.width, key.y + key.height + paddingTop); dr.setBounds(key.x, key.y + paddingTop, key.x + key.width, key.y + key.height + paddingTop); if (key.pressed) { dr_pres.draw(canvas); } else { dr.draw(canvas); } canvas.drawText(str, x - key.gap / 2, y + paddingTop / 2, paint); } /** * 关闭系统提供的预览窗 */ private void closePreviewPopup() { Class<KeyboardView> cls = KeyboardView.class; Method closing; try { closing = cls.getMethod("closing"); closing.invoke(this); } catch (Exception e) { e.printStackTrace(); } }}
2、KeyboardUtil,这个类主要是用来控制键盘的一些功能的管理工具类
(例如:大小写切换、中英文切换、预览弹框、显示/隐藏、动画效果等):
public class KeyboardUtil { private Context ctx; private Activity act; private CustomKeyboardView keyboardView; private Keyboard k1;// 字母键盘 private Keyboard k2;// 数字键盘 public boolean isnun = false;// 是否数据键盘 public static boolean shiftPressed=false;//监听shfit键是否onRelease public boolean isupper = false;// 是否大写 public static boolean isNormal=true;//是否显示的初始键盘 private CustomKeyboardStatus customKeyboardStatus;//监听键盘弹出隐藏回调滑动接口 private EditText edit;// private TextView preview; public KeyboardUtil(Activity act, Context ctx, EditText edit,CustomKeyboardStatus customKeyboardStatus) { this.act = act; this.ctx = ctx; this.edit = edit; this.customKeyboardStatus=customKeyboardStatus; k1 = new Keyboard(ctx, R.xml.qwerty); k2 = new Keyboard(ctx, R.xml.symbols); keyboardView = (CustomKeyboardView) act.findViewById(R.id.keyboard_view); keyboardView.setKeyboard(k1); keyboardView.setEnabled(true); keyboardView.setPreviewEnabled(true); keyboardView.setPopupOffset(UiUtils.dip2px(-15),UiUtils.dip2px(60)); keyboardView.setOnKeyboardActionListener(listener); isNormal=true; shiftPressed=false; } private KeyboardView.OnKeyboardActionListener listener = new KeyboardView.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) { if(primaryCode== -1){ if(shiftPressed){ shiftPressed=false; }else { shiftPressed=true; } } } @Override public void onPress(int primaryCode) { //屏蔽数字键和字母键盘部分按键的预览效果 if (primaryCode == 32 ||primaryCode == Keyboard.KEYCODE_CANCEL ||primaryCode == Keyboard.KEYCODE_DELETE ||primaryCode ==Keyboard.KEYCODE_SHIFT ||primaryCode == Keyboard.KEYCODE_MODE_CHANGE ||primaryCode == 57419 ||primaryCode == 57421 ||primaryCode == 48 ||primaryCode == 49 ||primaryCode == 50 ||primaryCode == 51 ||primaryCode == 52 ||primaryCode == 53 ||primaryCode == 54 ||primaryCode == 55 ||primaryCode == 56 ||primaryCode == 57 ||primaryCode == 0 ||primaryCode ==-10// ||primaryCode == 112// ||primaryCode == 113 ) { keyboardView.setPreviewEnabled(false); }else { keyboardView.setPreviewEnabled(true); } } @Override public void onKey(int primaryCode, int[] keyCodes) { Editable editable = edit.getText(); int start = edit.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(); keyboardView.setKeyboard(k1); } else if (primaryCode == Keyboard.KEYCODE_MODE_CHANGE) {// 数字键盘切换 if (isnun) { isnun = false; keyboardView.setKeyboard(k1); isNormal=true; } else { isnun = true; keyboardView.setKeyboard(k2); isNormal=false; } } else if (primaryCode == 57419) { // go left if (start > 0) { edit.setSelection(start - 1); } } else if (primaryCode == 57421) { // go right if (start < edit.length()) { edit.setSelection(start + 1); } } else if(primaryCode == -10){ hideKeyboard(); } else { editable.insert(start, Character.toString((char) primaryCode)); } } }; /** * 键盘大小写切换 */ private void changeKey() { List<Keyboard.Key> keylist = k1.getKeys(); if (isupper) {//大写切换小写 isupper = false; for (Keyboard.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 (Keyboard.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() { customKeyboardStatus.scrollUp(); int visibility = keyboardView.getVisibility(); if (visibility == View.GONE || visibility == View.INVISIBLE) { keyboardView.setVisibility(View.VISIBLE);// AnimationSet set=new AnimationSet(true);// TranslateAnimation trananimation=new TranslateAnimation(0, 0,keyboardView.getMeasuredHeight(),0);// trananimation.setDuration(2000);// set.addAnimation(trananimation);// AlphaAnimation alphaAnimation = new AlphaAnimation(0, 1);// alphaAnimation.setDuration(500);// set.addAnimation(alphaAnimation);// keyboardView.startAnimation(set); } } public void hideKeyboard() { customKeyboardStatus.scrollDown(); int visibility = keyboardView.getVisibility(); if (visibility == View.VISIBLE) {// AnimationSet set=new AnimationSet(true);// TranslateAnimation trananimation=new TranslateAnimation(0, 0,0,keyboardView.getMeasuredHeight());// trananimation.setDuration(2000);// set.addAnimation(trananimation);// AlphaAnimation alphaAnimation = new AlphaAnimation(1, 0);// alphaAnimation.setDuration(500);// set.addAnimation(alphaAnimation);// keyboardView.startAnimation(set); keyboardView.setVisibility(View.INVISIBLE); } } private boolean isword(String str) { String wordstr = "abcdefghijklmnopqrstuvwxyz"; if (wordstr.indexOf(str.toLowerCase()) > -1) { return true; } return false; }}
3、PwdEditText,这个是自定义EidtText,只要是密码输入框就用这个可以自定弹出自定义键盘的PwdEditText,
通过复写实现自定监听Touch事件来显示/隐藏键盘;通过反射机制屏蔽系统键盘的弹出;通过获取键盘的高度来判断
是否需要对当前根布局进行上滚避免EditText被键盘遮挡。
public class PwdEditText extends EditText implements CustomKeyboardStatus { private Context context; private KeyboardUtil keyboardUtil = null; private boolean isFocusable; private Window mWindow; private View mDecorView; private View mContentView; private int scrolldis = 0; //输入框在键盘被弹出时,要被推上去的距离 private View keyboard_layout; 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; private int screen_height; private int bottom; @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1) public PwdEditText(Context context, AttributeSet attrs) { super(context, attrs); this.context = context; setTouchListener(); initScreenParams(context); if (!EventBus.getDefault().isRegistered(this)) { EventBus.getDefault().register(this); } DisplayMetrics metrics = new DisplayMetrics(); ((Activity) context).getWindowManager().getDefaultDisplay().getRealMetrics(metrics); int width = metrics.widthPixels; screen_height = metrics.heightPixels;// MyLog.e(toString(), "screenHeight=" + screen_height); } @Subscribe public void onEventMainThread(KeyboardEvent event) { bottom = event.getBottom(); if(keyboard_layout!=null&&Build.VERSION.SDK_INT >= 24){ keyboard_layout.scrollTo(0, 0); if (bottom < screen_height) { keyboard_layout.scrollBy(0, getBottomStatusHeight(context)); } else { keyboard_layout.scrollTo(0, 0); } } } 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); } 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(); } public void onDetachedFromWindow() { super.onDetachedFromWindow(); mDecorView = null; mContentView = null; mWindow = null; EventBus.getDefault().unregister(this); } private void hideSysInput() { if (this.getWindowToken() != null) { InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(this.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); } } private void setTouchListener() { setOnFocusChangeListener(new OnFocusChangeListener() { @Override public void onFocusChange(View view, boolean b) { isFocusable = b; controlKeyboard(isFocusable); } }); setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View view, MotionEvent motionEvent) { if (motionEvent.getAction() == MotionEvent.ACTION_UP) { if (isFocusable) { ShowKeyBoard(); } } return false; } }); } /** * @param isFocusable 根据是否获取焦点控制键盘显示或隐藏 */ private void controlKeyboard(boolean isFocusable) { if (!isFocusable && keyboardUtil != null) { keyboardUtil.hideKeyboard(); } if (isFocusable) { ShowKeyBoard(); } } /** * 显示键盘 */ private void ShowKeyBoard() { if (keyboard_layout == null) { keyboard_layout = ((Activity) context).getLayoutInflater().inflate(R.layout.popuwindow_pwd_keyboard, null, false); ViewGroup childAt = (ViewGroup) getRootView(); childAt.addView(keyboard_layout); } if(Build.VERSION.SDK_INT >= 24){ keyboard_layout.scrollTo(0, 0); if (bottom < screen_height) { keyboard_layout.scrollBy(0, getBottomStatusHeight(context)); } else { keyboard_layout.scrollTo(0, 0); } } InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(getWindowToken(), 0); if (android.os.Build.VERSION.SDK_INT > 10) { ((Activity) context).getWindow().setSoftInputMode( WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); try { Class<EditText> cls = EditText.class; Method setShowSoftInputOnFocus; setShowSoftInputOnFocus = cls.getMethod( "setShowSoftInputOnFocus", boolean.class); setShowSoftInputOnFocus.setAccessible(true); setShowSoftInputOnFocus.invoke(this, false); } catch (Exception e) { e.printStackTrace(); } } else { setInputType(InputType.TYPE_NULL); } int inputType = this.getInputType(); keyboardUtil = new KeyboardUtil((Activity) context, context, this, this); keyboardUtil.showKeyboard(); setInputType(inputType); } /** * 当键盘挡住EditText时候屏幕往上滑动 */ @Override public void scrollUp() { if (null != mDecorView && null != mContentView) { int[] pos = new int[2]; getLocationOnScreen(pos); //201 + 15 float height = UiUtils.dip2px(201+15);//602或者646 Rect outRect = new Rect(); mDecorView.getWindowVisibleDisplayFrame(outRect); int screen = real_scontenth; scrolldis = (int) ((pos[1] + getMeasuredHeight() - outRect.top) - (screen - height)); if (scrolldis > 0) { mContentView.scrollBy(0, scrolldis); } } } /** * 当隐藏键盘时候回到起始位置 */ @Override public void scrollDown() { mContentView.scrollTo(0, 0); } /** * @param context * @return 获取状态栏高度 */ public static int getStatusBarHeight(Context context) { int result = 0; try { int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android"); if (resourceId > 0) { result = context.getResources().getDimensionPixelSize(resourceId); } } catch (Resources.NotFoundException e) { e.printStackTrace(); } return result; } /** * @param context * @return 获取底部虚拟键盘高度 */ public int getBottomStatusHeight(Context context) { int totlaHeight = getScreenDPI(context); int contentHeight = getScreenHeight(context); return totlaHeight - contentHeight; } /** * @param context * @return 屏幕总高度 */ public static int getScreenDPI(Context context) { int dpi = 0; WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); Display display = windowManager.getDefaultDisplay(); DisplayMetrics displayMetrics = new DisplayMetrics(); Class c; try { c = Class.forName("android.view.Display"); Method method = c.getMethod("getRealMetrics", DisplayMetrics.class); method.invoke(display, displayMetrics); dpi = displayMetrics.heightPixels; } catch (Exception e) { e.printStackTrace(); } return dpi; } /** * @param context * @return 内容区高度 */ private static int getScreenHeight(Context context) { WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); DisplayMetrics out = new DisplayMetrics(); wm.getDefaultDisplay().getMetrics(out); return out.heightPixels; }
在这里针对一些7.0以上版本,并且带底部虚拟键盘的机器(如华为手机)上,会出现一个问题,就是底部的虚拟键盘显示透明状态,
而且会遮挡我们的底部的布局模块,导致底部键盘的点击功能失效。所以我在这加了判定做特殊处理,如果是运行在此类
机型并是7.0以上系统的话,如果显示了虚拟键盘,就把自定义的键盘上滚一个底部键盘高度,如果隐藏,则恢复显示位置,
具体实现代码全部在以上这个类中。代码中用到一个回调接口CustomKeyboardStatus,就2个方法:scrollUp()和scrollDown();
主要是通过监听自定义键盘显示/隐藏状态改变屏幕滑动坐标值。
以上就是我写的自定义键盘中的核心代码,如果需要调用只需要把EditText改为自定义的PwdEditText就可以了,
最后我把弹出的键盘相关xml布局也贴出来:
kpopuwindow_pwd_keyboard:
<RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" xmlns:android="http://schemas.android.com/apk/res/android"> <com...customkeyboard.CustomKeyboardView android:id="@+id/keyboard_view" android:layout_width="fill_parent" android:layout_height="wrap_content" android:shadowColor="@color/bg_gray" android:shadowRadius="0.0" android:paddingBottom="3dp" android:paddingTop="3dp" android:layout_alignParentBottom="true" android:keyPreviewLayout="@layout/key_preview_layout" android:keyPreviewHeight="105dp" android:keyBackground="@drawable/bg_keyboard_selector" android:focusableInTouchMode="true" android:background="#d8dbdf" android:keyTextColor="@color/black" /></RelativeLayout>
预览框布局:key_preview_layout<TextView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="35sp" android:textColor="@android:color/black" android:gravity="top|center" android:background="@drawable/bg_key_preview"/>
需要代码参考的朋友可以点击这里打开链接下载,不足之处,还请指正。谢谢大家!
- Android绑定EditText自动弹出自定义软键盘不同按键设置不同背景的实现(自动向上顶适应布局)
- android 软键盘弹出,布局没有整体向上顶问题
- Android AlertDiaog自定义EditText自动弹出软键盘
- 软键盘弹出自动适应
- android防止EditText自动弹出软键盘
- android防止EditText自动弹出软键盘
- android EditText不自动弹出软键盘
- Android EditText不自动弹出软键盘
- Android editText自动弹出软键盘
- android editText自动弹出软键盘(输入键盘)
- android 软键盘弹出 自动调整布局
- Android 软键盘弹出自动移动布局
- android 自动弹出软键盘,EditText自动获取焦点
- android中的activity布局内含有webview,弹出软键盘如何自动适应屏幕,自动调整
- 软键盘弹出后重新布局(把布局向上顶)
- android 开发中进入一个activity界面软键盘自动弹出解决(布局中有edittext)
- android设置自动弹出软键盘
- 自定义dialog及布局(含EditText、Spinner)的输入设置和软键盘弹出设置
- RabbitMQ(六)
- 数据结构 二叉搜索树
- ASP.Net MVC + Data Table 实现分页+排序
- linux nginx启动,重启,关闭命令
- java死锁
- Android绑定EditText自动弹出自定义软键盘不同按键设置不同背景的实现(自动向上顶适应布局)
- 队列练习1 : HDOJ1276
- 贪心——HDU 4415
- 链表面试指南
- Oracle体系结构详解(转)
- arm开发板运行应用程序出现:-/bin/sh:xxx:not found 解决办法
- 和为S的两个数字
- 链表9:环形链表插值
- python zip函数基础