Android imitation Alipay numeric keypad

Keywords: Android xml encoding github

brief introduction

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

Effect of this paper:

Customize 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 the key background and key icon as required.
  4. Set the listener to call back the input 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);  // Initialize keyboard
        setKeyboard(keyboard);
        setEnabled(true);
        setFocusable(true);
        setPreviewEnabled(false);  // Set the preview bubble not to be displayed when clicking the key
        setOnKeyboardActionListener(this);
    }

    /**
     * Redraw delete and blank keys
     *
     * @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) {
                // Draw blank key background
                drawKeyBackground(key, canvas, delKeyBackgroundColor);
            }
            if (key.codes[0] == Keyboard.KEYCODE_DELETE) {
                // Delete delete key background
                drawKeyBackground(key, canvas, delKeyBackgroundColor);
                // Draw delete key Icon
                drawKeyIcon(key, canvas, getResources().getDrawable(R.drawable.ic_delete));
            }
        }

    }

    /**
     * Draw the background of the key
     *
     * @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);
    }

    /**
     * Draw icon of key
     *
     * @param key
     * @param canvas
     * @param iconDrawable
     */
    private void drawKeyIcon(Keyboard.Key key, Canvas canvas, Drawable iconDrawable) {
        if (iconDrawable == null) {
            return;
        }
        // Calculate the rect range of icon
        if (keyIconRect == null || keyIconRect.isEmpty()) {
            // Get the display size of keyicon, because the image is placed in different drawable DPI directory, and the display size is different
            int intrinsicWidth = iconDrawable.getIntrinsicWidth();
            int intrinsicHeight = iconDrawable.getIntrinsicHeight();
            int drawWidth = intrinsicWidth;
            int drawHeight = intrinsicHeight;
            // Limit the size of pictures and prevent the range of picture keys
            if (drawWidth > key.width) {
                drawWidth = key.width;
                // The height is scaled
                drawHeight = (int) (drawWidth * 1.0f / intrinsicWidth * intrinsicHeight);
            } else if (drawHeight > key.height) {
                drawHeight = key.height;
                drawWidth = (int) (drawHeight * 1.0f / intrinsicHeight * intrinsicWidth);
            }
            // Get the X and Y coordinates of the picture. The picture is in the middle of the key
            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) {

    }

    /**
    * Handle button click events
    */
    @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 {
        // Input callback
        void onInput(String text);
       // Delete callback
        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"    <! --Set the background selector for the key -->
        android:keyTextColor="@android:color/black"
        android:keyTextSize="26sp"
        android:shadowRadius="0" />      <!-- shadowRadius = 0 ,Prevent fuzzy display of key numbers --->

The results are:

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

Posted by rationalrabbit on Wed, 01 Apr 2020 11:56:38 -0700