安卓开发中使用自定义的键盘

最近项目中有使用到自定义的键盘,就是那种特殊的键盘,是一款输入车牌的键盘,效果图如下:
在这里插入图片描述在这里插入图片描述
完成以上效果我想到有两种实现方式:

第一种就是自定义键盘,主要用到的就是Keyboard和KeyboardView两个类.这种方式的话我觉得不好的一点就是需要edittext才能唤醒键盘.

第二种就是自定义两个pupopwindow或者dialog都行,这种就是在popupwindow中把按钮当成一个一个button摆好都添加点击事件,点击之后回调出点击的那个按钮的gettext()方法拿到值,对于删除键就是特殊的值和处理方式就好.这种方式的话给我的感觉不好之处就是太多初始化和点击的监听了.

我先说第一种实现步骤:

1.在工程的res目录下创建xml文件夹,然后创建两个文件,一个是放省份的键盘数据源和样式province_abbreviation.xml,一个是放数字和大写字母的键盘数据源和样式number_or_letters.xml.(注意根标签是Keyboard)

这里讲解一下各个标签的作用

根目录一定是Keyboard里面可以设置每个键的宽和高通过keyHeight和keyWidth来改变取值为(10%p)当每个key中设置了该值时以key中的大小为准.

往下是Row标签 一个row标签代表一行.

在往下是Key标签 里面就代表着一个一个的按键了,包裹在Row标签中,比如一行需要10个按键时就放10个key标签,keyLabel属性代表的是文本该展示什么字,codes代表的是一个assiic码表中对应的值.比如说49,50意思就是按第一下按钮时是1按第二下按钮为2.

以下贴出xml中的代码:

province_abbreviation文件中的代码:

<?xml version="1.0" encoding="UTF-8"?>
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
    android:horizontalGap="0.0px"
    android:keyHeight="8%p"
    android:keyWidth="10%p"
    android:verticalGap="0.0px">

    <Row android:verticalGap="1%p">
        <Key
            android:codes="20140"
            android:horizontalGap="1%p"
            android:keyEdgeFlags="left"
            android:keyLabel="京"
            android:keyWidth="8%p" />
        <Key
            android:codes="27818"
            android:horizontalGap="2%p"
            android:keyLabel="沪"
            android:keyWidth="8%p" />
        <Key
            android:codes="31908"
            android:horizontalGap="2%p"
            android:keyLabel="粤"
            android:keyWidth="8%p"

            />
        <Key
            android:codes="27941"
            android:horizontalGap="2%p"
            android:keyLabel="津"
            android:keyWidth="8%p"

            />
        <Key
            android:codes="20864"
            android:horizontalGap="2%p"
            android:keyLabel="冀"
            android:keyWidth="8%p"

            />
        <Key
            android:codes="26187"
            android:horizontalGap="2%p"
            android:keyLabel="晋"
            android:keyWidth="8%p"

            />
        <Key
            android:codes="33945"
            android:horizontalGap="2%p"
            android:keyLabel="蒙"
            android:keyWidth="8%p" />
        <Key
            android:codes="36797"
            android:horizontalGap="2%p"
            android:keyLabel="辽"
            android:keyWidth="8%p"

            />
        <Key
            android:codes="21513"
            android:horizontalGap="2%p"
            android:keyLabel="吉"
            android:keyWidth="8%p"

            />
        <Key

            android:codes="40657"
            android:horizontalGap="2%p"
            android:keyEdgeFlags="right"
            android:keyLabel="黑"
            android:keyWidth="8%p" />
    </Row>

    <Row android:verticalGap="1%p">
        <Key
            android:codes="33487"
            android:horizontalGap="6.5%p"
            android:keyEdgeFlags="left"
            android:keyLabel="苏"
            android:keyWidth="8%p" />
        <Key
            android:codes="27993"
            android:horizontalGap="2%p"
            android:keyLabel="浙"
            android:keyWidth="8%p" />
        <Key
            android:codes="30358"
            android:horizontalGap="2%p"
            android:keyLabel="皖"
            android:keyWidth="8%p" />
        <Key
            android:codes="38397"
            android:horizontalGap="2%p"
            android:keyLabel="闽"
            android:keyWidth="8%p" />
        <Key
            android:codes="36195"
            android:horizontalGap="2%p"
            android:keyLabel="赣"
            android:keyWidth="8%p" />
        <Key
            android:codes="40065"
            android:horizontalGap="2%p"
            android:keyLabel="鲁"
            android:keyWidth="8%p" />
        <Key
            android:codes="35947"
            android:horizontalGap="2%p"
            android:keyLabel="豫"
            android:keyWidth="8%p" />
        <Key
            android:codes="37122"
            android:horizontalGap="2%p"
            android:keyLabel="鄂"
            android:keyWidth="8%p" />
        <Key
            android:codes="28248"
            android:horizontalGap="2%p"
            android:keyLabel="湘"
            android:keyWidth="8%p" />

    </Row>

    <Row android:verticalGap="1%p">
        <Key
            android:codes="26690"
            android:horizontalGap="11%p"
            android:keyEdgeFlags="right"
            android:keyLabel="桂"
            android:keyWidth="8%p" />
        <Key
            android:codes="29756"
            android:horizontalGap="2%p"
            android:keyLabel="琼"
            android:keyWidth="8%p" />
        <Key
            android:codes="28189"
            android:horizontalGap="2%p"
            android:keyEdgeFlags="left"
            android:keyLabel="渝"
            android:keyWidth="8%p" />
        <Key
            android:codes="24029"
            android:horizontalGap="2%p"
            android:keyLabel="川"
            android:keyWidth="8%p" />
        <Key
            android:codes="36149"
            android:horizontalGap="2%p"
            android:keyLabel="贵"
            android:keyWidth="8%p" />
        <Key
            android:codes="20113"
            android:horizontalGap="2%p"
            android:keyLabel="云"
            android:keyWidth="8%p" />
        <Key
            android:codes="34255"
            android:horizontalGap="2%p"
            android:keyLabel="藏"
            android:keyWidth="8%p" />
        <Key
            android:codes="38485"
            android:horizontalGap="2%p"
            android:keyLabel="陕"
            android:keyWidth="8%p" />

    </Row>

    <Row>

        <Key
            android:codes="29976"
            android:horizontalGap="26%p"
            android:keyLabel="甘"
            android:keyWidth="8%p" />
        <Key
            android:codes="38738"
            android:horizontalGap="2%p"
            android:keyEdgeFlags="right"
            android:keyLabel="青"
            android:keyWidth="8%p" />
        <Key
            android:codes="23425"
            android:horizontalGap="2%p"
            android:keyLabel="宁"
            android:keyWidth="8%p" />
        <Key
            android:codes="26032"
            android:horizontalGap="2%p"
            android:keyLabel="新"
            android:keyWidth="8%p" />
        <Key
            android:codes="20351"
            android:horizontalGap="2%p"
            android:keyLabel="使"
            android:keyWidth="8%p" />
        <Key
            android:codes="-3"
            android:keyIcon="@mipmap/icon_delete"
            android:horizontalGap="2%p"
            android:isRepeatable="false"
            android:keyEdgeFlags="right"
            android:keyWidth="15%p" />
    </Row>

</Keyboard>

number_or_letters中的代码:

<?xml version="1.0" encoding="UTF-8"?>
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
    android:horizontalGap="20.0px"
    android:keyHeight="8%"
    android:keyWidth="10%p"
    android:verticalGap="50.0px">
    <Row android:verticalGap="1%p">
        <Key
            android:codes="49"
            android:horizontalGap="1%p"
            android:keyEdgeFlags="left"
            android:keyLabel="1"
            android:keyWidth="8%p" />
        <Key
            android:codes="50"
            android:horizontalGap="2%p"
            android:keyLabel="2"
            android:keyWidth="8%p" />
        <Key
            android:codes="51"
            android:horizontalGap="2%p"
            android:keyLabel="3"
            android:keyWidth="8%p" />
        <Key
            android:codes="52"
            android:horizontalGap="2%p"
            android:keyLabel="4"
            android:keyWidth="8%p" />
        <Key
            android:codes="53"
            android:horizontalGap="2%p"
            android:keyLabel="5"
            android:keyWidth="8%p" />
        <Key
            android:codes="54"
            android:horizontalGap="2%p"
            android:keyLabel="6"
            android:keyWidth="8%p" />
        <Key
            android:codes="55"
            android:horizontalGap="2%p"
            android:keyLabel="7"
            android:keyWidth="8%p" />
        <Key
            android:codes="56"
            android:horizontalGap="2%p"
            android:keyLabel="8"
            android:keyWidth="8%p" />
        <Key
            android:codes="57"
            android:horizontalGap="2%p"
            android:keyLabel="9"
            android:keyWidth="8%p" />
        <Key
            android:codes="48"
            android:horizontalGap="2%p"
            android:keyEdgeFlags="right"
            android:keyLabel="0"
            android:keyWidth="8%p" />
    </Row>

    <Row android:verticalGap="1%p">
        <Key

            android:codes="65"
            android:horizontalGap="1%p"
            android:keyEdgeFlags="left"
            android:keyLabel="A"
            android:keyWidth="8%p" />
        <Key
            android:codes="66"
            android:horizontalGap="2%p"
            android:keyLabel="B"
            android:keyWidth="8%p"

            />
        <Key
            android:codes="67"
            android:horizontalGap="2%p"
            android:keyLabel="C"
            android:keyWidth="8%p"

            />
        <Key
            android:codes="68"
            android:horizontalGap="2%p"
            android:keyLabel="D"
            android:keyWidth="8%p"

            />
        <Key
            android:codes="69"
            android:horizontalGap="2%p"
            android:keyLabel="E"
            android:keyWidth="8%p"

            />
        <Key
            android:codes="70"
            android:horizontalGap="2%p"
            android:keyLabel="F"
            android:keyWidth="8%p"

            />
        <Key
            android:codes="71"
            android:horizontalGap="2%p"
            android:keyLabel="G"
            android:keyWidth="8%p"

            />
        <Key
            android:codes="72"
            android:horizontalGap="2%p"
            android:keyLabel="H"
            android:keyWidth="8%p"

            />
        <Key
            android:codes="74"
            android:horizontalGap="2%p"
            android:keyLabel="J"
            android:keyWidth="8%p"

            />
        <Key
            android:codes="75"
            android:horizontalGap="2%p"
            android:keyEdgeFlags="right"
            android:keyLabel="K"
            android:keyWidth="8%p" />
    </Row>

    <Row android:verticalGap="1%p">
        <Key
            android:codes="76"
            android:horizontalGap="1%p"
            android:keyEdgeFlags="left"
            android:keyLabel="L"
            android:keyWidth="8%p"

            />
        <Key
            android:codes="77"
            android:horizontalGap="2%p"
            android:keyLabel="M"
            android:keyWidth="8%p"

            />
        <Key
            android:codes="78"
            android:horizontalGap="2%p"
            android:keyLabel="N"
            android:keyWidth="8%p"

            />
        <Key
            android:codes="80"
            android:horizontalGap="2%p"
            android:keyLabel="P"
            android:keyWidth="8%p" />
        <Key
            android:codes="81"
            android:horizontalGap="2%p"
            android:keyLabel="Q"
            android:keyWidth="8%p"

            />
        <Key
            android:codes="82"
            android:horizontalGap="2%p"
            android:keyLabel="R"
            android:keyWidth="8%p"

            />
        <Key
            android:codes="83"
            android:horizontalGap="2%p"
            android:keyLabel="S"
            android:keyWidth="8%p"

            />
        <Key
            android:codes="84"
            android:horizontalGap="2%p"
            android:keyLabel="T"
            android:keyWidth="8%p"

            />
        <Key
            android:codes="85"
            android:horizontalGap="2%p"
            android:keyLabel="U"
            android:keyWidth="8%p" />

        <Key
            android:codes="86"
            android:horizontalGap="2%p"
            android:keyEdgeFlags="right"
            android:keyLabel="V"
            android:keyWidth="8%p" />
    </Row>

    <Row>

        <Key
            android:codes="87"
            android:horizontalGap="7%p"
            android:keyEdgeFlags="left"
            android:keyLabel="W"
            android:keyWidth="8%p" />
        <Key
            android:codes="88"
            android:horizontalGap="2%p"
            android:keyLabel="X"
            android:keyWidth="8%p" />

        <Key
            android:codes="89"
            android:horizontalGap="2%p"
            android:keyLabel="Y"
            android:keyWidth="8%p" />
        <Key
            android:codes="90"
            android:horizontalGap="2%p"
            android:keyLabel="Z"
            android:keyWidth="8%p" />
        <Key
            android:codes="28207"
            android:horizontalGap="2%p"
            android:keyLabel="港"
            android:keyWidth="8%p" />
        <Key
            android:codes="28595"
            android:horizontalGap="2%p"
            android:keyLabel="澳"
            android:keyWidth="8%p" />

        <Key
            android:codes="23398"
            android:horizontalGap="2%p"
            android:keyLabel="学"
            android:keyWidth="8%p" />
        <Key
            android:codes="39046"
            android:horizontalGap="2%p"
            android:keyEdgeFlags="right"
            android:keyLabel="领"
            android:keyWidth="8%p" />
        <Key
            android:codes="-3"
            android:horizontalGap="2%p"
            android:isRepeatable="false"
            android:keyIcon="@mipmap/icon_delete"
            android:keyWidth="13%p" />
    </Row>

</Keyboard>

2.把xml文件创建好编辑好之后编写一个KeyboardUtil 类把需要展示键盘的Activity和edittext和该工具类绑定.

在构造方法中初始化控件和设置键盘所需要展示的样式.

public KeyboardUtil(Activity activity, EditText edit) {
        mActivity = activity;
        mEdit = edit;
        provinceKeyboard = new Keyboard(activity, R.xml.province_abbreviation);
        numberKeyboard = new Keyboard(activity, R.xml.number_or_letters);
        mKeyboardView = (KeyboardView) activity.findViewById(R.id.keyboard_view);
        mKeyboardView.setKeyboard(provinceKeyboard);
        mKeyboardView.setEnabled(true);
        mKeyboardView.setPreviewEnabled(false);
        mKeyboardView.setOnKeyboardActionListener(listener);
    }

mKeyboardView.setKeyboard(provinceKeyboard);这行代码就是让展示键盘的View展示省份的键盘.

mKeyboardView.setOnKeyboardActionListener(listener);然后设置监听器.

    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) {
        }

        @Override
        public void onPress(int primaryCode) {
        }

        @Override
        public void onKey(int primaryCode, int[] keyCodes) {
            Editable editable = mEdit.getText();
            int start = mEdit.getSelectionStart();
            editable.insert(start, Character.toString((char) primaryCode));
        }
    };

设置键盘的监听器,每点击一个按钮都会调用一下onkey回调方法.

因为是调用自定义的软件盘所有需要把系统自带的软键盘给禁掉.

   /**
     * 禁掉系统软键盘
     */
    public void hideSoftInputMethod() {
        mActivity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
        int currentVersion = android.os.Build.VERSION.SDK_INT;
        String methodName = null;
        if (currentVersion >= 16) {
            // 4.2
            methodName = "setShowSoftInputOnFocus";
        } else if (currentVersion >= 14) {
            // 4.0
            methodName = "setSoftInputShownOnFocus";
        }
        if (methodName == null) {
            mEdit.setInputType(InputType.TYPE_NULL);
        } else {
            Class<EditText> cls = EditText.class;
            Method setShowSoftInputOnFocus;
            try {
                setShowSoftInputOnFocus = cls.getMethod(methodName, boolean.class);
                setShowSoftInputOnFocus.setAccessible(true);
                setShowSoftInputOnFocus.invoke(mEdit, false);
            } catch (NoSuchMethodException e) {
                mEdit.setInputType(InputType.TYPE_NULL);
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        }
    }

KeyboardUtil中的代码如下

public class KeyboardUtil {

    private Activity mActivity;
    private KeyboardView mKeyboardView;
    private EditText mEdit;
    /**
     * 省份简称键盘
     */
    private Keyboard provinceKeyboard;
    /**
     * 数字与大写字母键盘
     */
    private Keyboard numberKeyboard;

    public KeyboardUtil(Activity activity, EditText edit) {
        mActivity = activity;
        mEdit = edit;
        provinceKeyboard = new Keyboard(activity, R.xml.province_abbreviation);
        numberKeyboard = new Keyboard(activity, R.xml.number_or_letters);
        mKeyboardView = (KeyboardView) activity.findViewById(R.id.keyboard_view);
        mKeyboardView.setKeyboard(provinceKeyboard);
        mKeyboardView.setEnabled(true);
        mKeyboardView.setPreviewEnabled(false);
        mKeyboardView.setOnKeyboardActionListener(listener);
    }


    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) {
        }

        @Override
        public void onPress(int primaryCode) {
        }

        @Override
        public void onKey(int primaryCode, int[] keyCodes) {
            Editable editable = mEdit.getText();
            int start = mEdit.getSelectionStart();
            editable.insert(start, Character.toString((char) primaryCode));
        }
    };

    /**
     * 指定切换软键盘 isNumber false表示要切换为省份简称软键盘 true表示要切换为数字软键盘
     */
    private void changeKeyboard(boolean isNumber) {
        if (isNumber) {
            mKeyboardView.setKeyboard(numberKeyboard);
        } else {
            mKeyboardView.setKeyboard(provinceKeyboard);
        }
    }

    /**
     * 软键盘展示状态
     */
    public boolean isShow() {
        return mKeyboardView.getVisibility() == View.VISIBLE;
    }

    /**
     * 软键盘展示
     */
    public void showKeyboard() {
        int visibility = mKeyboardView.getVisibility();
        if (visibility == View.GONE || visibility == View.INVISIBLE) {
            mKeyboardView.setVisibility(View.VISIBLE);
        }
    }

    /**
     * 软键盘隐藏
     */
    public void hideKeyboard() {
        int visibility = mKeyboardView.getVisibility();
        if (visibility == View.VISIBLE) {
            mKeyboardView.setVisibility(View.INVISIBLE);
        }
    }

    /**
     * 禁掉系统软键盘
     */
    public void hideSoftInputMethod() {
        mActivity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
        int currentVersion = android.os.Build.VERSION.SDK_INT;
        String methodName = null;
        if (currentVersion >= 16) {
            // 4.2
            methodName = "setShowSoftInputOnFocus";
        } else if (currentVersion >= 14) {
            // 4.0
            methodName = "setSoftInputShownOnFocus";
        }
        if (methodName == null) {
            mEdit.setInputType(InputType.TYPE_NULL);
        } else {
            Class<EditText> cls = EditText.class;
            Method setShowSoftInputOnFocus;
            try {
                setShowSoftInputOnFocus = cls.getMethod(methodName, boolean.class);
                setShowSoftInputOnFocus.setAccessible(true);
                setShowSoftInputOnFocus.invoke(mEdit, false);
            } catch (NoSuchMethodException e) {
                mEdit.setInputType(InputType.TYPE_NULL);
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        }
    }
}

3.在Activity中调用KeyboardUtil中的代码.

public class MainActivity extends AppCompatActivity {
    private KeyboardUtil keyboardUtil;
    private EditText mEditText;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mEditText = findViewById(R.id.edit_text);
        mEditText.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent event) {
                if (keyboardUtil == null) {
                    keyboardUtil = new KeyboardUtil(MainActivity.this, mEditText);
                    keyboardUtil.hideSoftInputMethod();
                    keyboardUtil.showKeyboard();
                } else {
                    keyboardUtil.showKeyboard();
                }
                return false;
            }
        });

    }
}

Activity的布局文件核心代码:

<EditText
        android:id="@+id/edit_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <android.inputmethodservice.KeyboardView
        android:id="@+id/keyboard_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent" />

大功告成这就完成了第一种自定义键盘的功能.

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值