美文网首页简化开发程序员Android知识
Android:最快实现一个自定义键盘

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

作者: 展翅而飞 | 来源:发表于2017-07-26 15:07 被阅读0次

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

自定义键盘

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

Keyboard

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

<?xml version="1.0" encoding="utf-8"?>
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
    android:horizontalGap="1dp"
    android:verticalGap="1dp"
    android:keyWidth="20%p"
    android:keyHeight="50dp">
    <Row>
        <Key android:codes="-10" android:keyLabel="清空"
            android:keyEdgeFlags="left"/>
        <Key android:codes="49" android:keyLabel="1"/>
        <Key android:codes="50" android:keyLabel="2"/>
        <Key android:codes="51" android:keyLabel="3"/>
        <Key android:codes="-3" android:keyLabel="收起"
            android:keyEdgeFlags="right"/>
    </Row>
    <Row>
        <Key android:codes="-11" android:keyLabel="上一项"
            android:keyEdgeFlags="left"
            android:keyHeight="100.5dp"/>
        <Key android:codes="52" android:keyLabel="4"/>
        <Key android:codes="53" android:keyLabel="5"/>
        <Key android:codes="54" android:keyLabel="6"/>
        <Key android:codes="-12" android:keyLabel="下一项"
            android:keyEdgeFlags="right"
            android:keyHeight="100.5dp"/>
    </Row>
    <Row>
        <Key android:codes="-99" android:keyHeight="0dp" android:keyEdgeFlags="left"/>
        <Key android:codes="55" android:keyLabel="7"/>
        <Key android:codes="56" android:keyLabel="8"/>
        <Key android:codes="57" android:keyLabel="9"/>
        <Key android:codes="-99" android:keyHeight="0dp" android:keyEdgeFlags="right"/>
    </Row>
    <Row>
        <Key android:codes="-99" android:keyEdgeFlags="left"/>
        <Key android:codes="45" android:keyLabel="-"/>
        <Key android:codes="48" android:keyLabel="0"/>
        <Key android:codes="46" android:keyLabel="."/>
        <Key android:codes="-5" android:keyLabel="删除"
            android:keyEdgeFlags="right"
            android:isRepeatable="true"/>
    </Row>
</Keyboard>

要注意的地方是:

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

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

KeyboardView

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

<android.inputmethodservice.KeyboardView
            android:id="@+id/custom_keyboard"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:focusable="true"
            android:focusableInTouchMode="true"
            android:background="@color/lightgray"
            android:keyBackground="@drawable/btn_keyboard_key"
            android:keyTextColor="@color/black"
            android:keyTextSize="20dp"
            android:paddingTop="1px"
            android:shadowRadius="0"
            android:visibility="gone"/>

具体属性参考官方文档,到这里,自定义键盘的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:最快实现一个自定义键盘

    本文链接:https://www.haomeiwen.com/subject/dzknkxtx.html