Android:最快实现一个自定义键盘

现在很多场景需要使用自定义键盘,比如银行app的乱序密码键盘。现在做个demo,用最快的速度、最少的代码做出一个数字键盘,有基本的操作按键,效果如下图:

Android:最快实现一个自定义键盘_第1张图片
自定义键盘

自定义键盘的实现,需要用到系统Keyboard和KeybaordView两个类。

Keyboard

Keybard类可以加载一个描述键盘按键的xml文件,demo里的按键布局如下:



    
        
        
        
        
        
    
    
        
        
        
        
        
    
    
        
        
        
        
        
    
    
        
        
        
        
        
    

要注意的地方是:

  • 键盘布局放在/res/xml
  • 输出字符按键的android:codes需要是对应的ASCII码
  • 有预定义常用操作,比如取消、完成、删除,可以直接用

比较折腾的是不知道如何让按键跨行跨列,文档里没有找到任何span方法。跨列容易解决,单独修改keyWidth就可以。跨行的话,现在的实现是让上一行key的height双倍,下一行的height为0,最终实现demo的效果,求更好的方法。

KeyboardView

KeyboardView处理了键盘的绘制、触摸、滑动等动作,加进Activity的布局里。


具体属性参考官方文档,到这里,自定义键盘的ui已经定义好,下面看怎样跑起来。

键盘初始化

private void initKeyboard() {
        Keyboard keyboard = new Keyboard(this, R.xml.number_input_keyboard);

        mBinding.customKeyboard.setKeyboard(keyboard);
        mBinding.customKeyboard.setEnabled(true);
        mBinding.customKeyboard.setPreviewEnabled(false);
        mBinding.customKeyboard.setOnKeyboardActionListener(new KeyboardView.OnKeyboardActionListener() {
            @Override
            public void onPress(int primaryCode) {
            }

            @Override
            public void onRelease(int primaryCode) {
            }

            @Override
            public void onKey(int primaryCode, int[] keyCodes) {
                doCustomKeyboardKey(primaryCode, keyCodes);
            }

            @Override
            public void onText(CharSequence text) {
            }

            @Override
            public void swipeLeft() {
            }

            @Override
            public void swipeRight() {
            }

            @Override
            public void swipeDown() {
            }

            @Override
            public void swipeUp() {
            }
        });
    }

Keyboard和KeyboardView的初始化很简单,最重要的是实现OnKeyboardActionListener,提供了多个动作的回调,demo简单实现按键点击的处理。

    private void doCustomKeyboardKey(int primaryCode, int[] keyCodes) {
        Editable editable;
        int selectionStart;
        if (mBinding.et1.isFocused()) {
            editable = mBinding.et1.getText();
            selectionStart = mBinding.et1.getSelectionStart();
        } else {
            editable = mBinding.et2.getText();
            selectionStart = mBinding.et2.getSelectionStart();
        }

        if (primaryCode == Keyboard.KEYCODE_CANCEL) {
            hideKeyboard();
        } else if (primaryCode == Keyboard.KEYCODE_DELETE) {
            if (editable.length() > 0 && selectionStart > 0) {
                editable.delete(selectionStart - 1, selectionStart);
            }
        } else if (primaryCode == -10) {
            if (editable.length() > 0) {
                editable.clear();
            }
        } else if (primaryCode == -11) {
            mBinding.et1.requestFocus();
        } else if (primaryCode == -12) {
            mBinding.et2.requestFocus();
        } else if (primaryCode == -99) {
            //do nothing
        } else {
            editable.insert(selectionStart, Character.toString((char) primaryCode));
        }
    }

根据xml文件里预定好的primaryCode,根据实际情况处理各个按键的效果。

自定义EditText

使用自定义键盘的EditText需要增加处理系统键盘,最简单的方法就是直接隐藏。

@Override
public boolean onTouchEvent(MotionEvent event) {
    super.onTouchEvent(event);
    requestFocus();
    requestFocusFromTouch();

    hideSysInput();

    return true;
}

自定义键盘的打开

mBinding.et1.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        mBinding.customKeyboard.setVisibility(View.VISIBLE);
    }
});

EditText增加监听onClick事件,直接让键盘显示。为什么不用OnFocusChangeListener呢,因为主动收起键盘,EditText的焦点没有改变,只有onClick才能再触发键盘打开。

几段代码就实现了一个自定义键盘,挺简单的。在此基础上,根据实际业务,我们可以扩展做出更复杂的效果。最后附上demo地址,谢谢观看。

你可能感兴趣的:(Android:最快实现一个自定义键盘)