Android imitation Alipay number keyboard

Introduction

In some apps with payment function, the input password can only be pure numbers. Although we can specify that the EditText input box can only input numbers, in order to provide users with a user experience, we tend to use custom pure numbers. Numeric keypad.

The effect of this article:

Custom KeyboardView

Implementation steps:

  1. The KeyBoardView class of the integrated system initializes the keyboard layout and sets the KeyBoard object during initialization.
  2. Implement the OnKeyboardActionListener interface to handle key interaction events.
  3. Draw button backgrounds and button icons as required.
  4. Set up a listener to call back the input content to the caller.

keyboard layout

Create an xml file in the res/xml/ directory: key_password_number.xml

<?xml version="1.0" encoding="utf-8"?>
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
    android:horizontalGap="1dp"
    android:keyHeight="9%p"
    android:keyWidth="33.3333%p"
    android:verticalGap="1dp">

    <Row>
        <Key
            android:codes="49"
            android:keyLabel="1" />
        <Key
            android:codes="50"
            android:keyLabel="2" />
        <Key
            android:codes="51"
            android:keyLabel="3" />
    </Row>

    <Row>
        <Key
            android:codes="52"
            android:keyLabel="4" />
        <Key
            android:codes="53"
            android:keyLabel="5" />
        <Key
            android:codes="54"
            android:keyLabel="6" />
    </Row>

    <Row>
        <Key
            android:codes="55"
            android:keyLabel="7" />
        <Key
            android:codes="56"
            android:keyLabel="8" />
        <Key
            android:codes="57"
            android:keyLabel="9" />
    </Row>

    <Row>
        <Key
            android:codes="-10"
            android:keyLabel="" />
        <Key
            android:codes="48"
            android:keyLabel="0" />
        <Key
            android:codes="-5"
            android:keyLabel="" />
    </Row>
</Keyboard>

Inherit KeyBoardView

public class PwdKeyboardView extends KeyboardView implements KeyboardView.OnKeyboardActionListener {

    private static final String TAG = "PwdKeyboardView";

    private static final int KEY_EMPTY = -10;

    private int delKeyBackgroundColor = 0xffcccccc;

    private Rect keyIconRect;


    public PwdKeyboardView(Context context, AttributeSet attrs) {
        super(context, attrs);
        Log.d(TAG, "PwdKeyboardView: two params");
        init(context);

    }

    public PwdKeyboardView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        Log.d(TAG, "PwdKeyboardView: three params");
        init(context);
    }


    private void init(Context context) {
        Keyboard keyboard = new Keyboard(context, R.xml.key_password_number);  // 初始化 keyboard
        setKeyboard(keyboard);
        setEnabled(true);
        setFocusable(true);
        setPreviewEnabled(false);  // 设置点击按键不显示预览气泡
        setOnKeyboardActionListener(this);
    }

    /**
     * 重新绘制删除按键和空白键
     *
     * @param canvas
     */
    @Override
    public void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        List<Keyboard.Key> keys = getKeyboard().getKeys();
        for (Keyboard.Key key : keys) {
            if (key.codes[0] == KEY_EMPTY) {
                // 绘制空白键背景
                drawKeyBackground(key, canvas, delKeyBackgroundColor);
            }
            if (key.codes[0] == Keyboard.KEYCODE_DELETE) {
                // 删除删除按键背景
                drawKeyBackground(key, canvas, delKeyBackgroundColor);
                // 绘制删除按键图标
                drawKeyIcon(key, canvas, getResources().getDrawable(R.drawable.ic_delete));
            }
        }

    }

    /**
     * 绘制按键的背景
     *
     * @param key
     * @param canvas
     * @param color
     */
    private void drawKeyBackground(Keyboard.Key key, Canvas canvas, int color) {
        ColorDrawable drawable = new ColorDrawable(color);
        drawable.setBounds(key.x, key.y, key.x + key.width, key.y + key.height);
        drawable.draw(canvas);
    }

    /**
     * 绘制按键的 icon
     *
     * @param key
     * @param canvas
     * @param iconDrawable
     */
    private void drawKeyIcon(Keyboard.Key key, Canvas canvas, Drawable iconDrawable) {
        if (iconDrawable == null) {
            return;
        }
        // 计算按键icon 的rect 范围
        if (keyIconRect == null || keyIconRect.isEmpty()) {
            // 得到 keyicon 的显示大小,因为图片放在不同的drawable-dpi目录下,显示大小也不一样
            int intrinsicWidth = iconDrawable.getIntrinsicWidth();
            int intrinsicHeight = iconDrawable.getIntrinsicHeight();
            int drawWidth = intrinsicWidth;
            int drawHeight = intrinsicHeight;
            // 限制图片的大小,防止图片按键范围
            if (drawWidth > key.width) {
                drawWidth = key.width;
                // 此时高就按照比例缩放
                drawHeight = (int) (drawWidth * 1.0f / intrinsicWidth * intrinsicHeight);
            } else if (drawHeight > key.height) {
                drawHeight = key.height;
                drawWidth = (int) (drawHeight * 1.0f / intrinsicHeight * intrinsicWidth);
            }
            // 获取图片的 x,y 坐标,图片在按键的正中间
            int left = key.x + key.width / 2 - drawWidth / 2;
            int top = key.y + key.height / 2 - drawHeight / 2;
            keyIconRect = new Rect(left, top, left + drawWidth, top + drawHeight);
        }

        if (keyIconRect != null && !keyIconRect.isEmpty()) {
            iconDrawable.setBounds(keyIconRect);
            iconDrawable.draw(canvas);
        }
    }


    @Override
    public void onPress(int primaryCode) {

    }

    @Override
    public void onRelease(int primaryCode) {

    }

    /**
    * 处理按键的点击事件
    */
    @Override
    public void onKey(int primaryCode, int[] keyCodes) {
        Log.d(TAG, "onKey: primaryCode = " + primaryCode + ", keyCodes = " + Arrays.toString(keyCodes));
        if (primaryCode == KEY_EMPTY) {
            return;
        }
        if (listener != null) {
            if (primaryCode == Keyboard.KEYCODE_DELETE) {
                listener.onDelete();
            } else {
                listener.onInput(String.valueOf((char) primaryCode));
            }
        }


    }

    @Override
    public void onText(CharSequence charSequence) {

    }

    @Override
    public void swipeLeft() {

    }

    @Override
    public void swipeRight() {

    }

    @Override
    public void swipeDown() {

    }

    @Override
    public void swipeUp() {

    }

    public interface OnKeyListener {
        // 输入回调
        void onInput(String text);
       // 删除回调
        void onDelete();
    }

    private OnKeyListener listener;

    public void setOnKeyListener(OnKeyListener listener) {
        this.listener = listener;
    }

}

Using PwdKeyboardView

<com.xing.pwdkeyboardview.PwdKeyboardView
        android:id="@+id/key_board"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#919191"
        android:keepScreenOn="true"
        android:keyBackground="@drawable/selector_key_board"    <! --设置按键的背景选择器 -->
        android:keyTextColor="@android:color/black"
        android:keyTextSize="26sp"
        android:shadowRadius="0" />      <!-- shadowRadius = 0 ,防止按键数字显示模糊 --->

The displayed result is:

keynumber![](C:\Users\Administrator\Desktop\2018-03-25_203243.png)

Full code: https://github.com/xing16/PwdKeyboardView

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325413151&siteId=291194637