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"/>


需要代码参考的朋友可以点击这里打开链接下载,不足之处,还请指正。谢谢大家!


1 0
原创粉丝点击