学习笔记-自定义密码输入框和自定义数字密码软键盘

来源:互联网 发布:mac 的火箭按钮不见了 编辑:程序博客网 时间:2024/06/01 11:50
      最近项目里有一个支付功能,需要自定义键盘,于是我在网上搜了一下,发现这个和我需求很相符,等项目完工,打算分享给大家,却找不到项目的博主了,这里还是感谢博主,我就直接贴代码分享给大家了;
XNumberKeyboardView.java
import android.content.Context;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Rect;import android.graphics.drawable.ColorDrawable;import android.graphics.drawable.Drawable;import android.inputmethodservice.Keyboard;import android.inputmethodservice.KeyboardView;import android.util.AttributeSet;import java.util.Arrays;import java.util.Collections;import java.util.List;/** * 数字键盘。 * * @author wuzhen */public class XNumberKeyboardView extends KeyboardView implements KeyboardView.OnKeyboardActionListener {    // 用于区分左下角空白的按键    private static final int KEYCODE_EMPTY = -10;    private int mDeleteWidth;    private int mDeleteHeight;    private int mDeleteBackgroundColor;    private Drawable mDeleteDrawable;    private Rect mDeleteDrawRect;    private IOnKeyboardListener mOnKeyboardListener;    public XNumberKeyboardView(Context context, AttributeSet attrs) {        super(context, attrs);        init(context, attrs, 0);    }    public XNumberKeyboardView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        init(context, attrs, defStyleAttr);    }    private void init(Context context, AttributeSet attrs, int defStyleAttr) {        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.XNumberKeyboardView,                defStyleAttr, 0);        mDeleteDrawable = a.getDrawable(R.styleable.XNumberKeyboardView_xnkv_deleteDrawable);        mDeleteBackgroundColor = a.getColor(                R.styleable.XNumberKeyboardView_xnkv_deleteBackgroundColor, Color.TRANSPARENT);        mDeleteWidth = a.getDimensionPixelOffset(R.styleable.XNumberKeyboardView_xnkv_deleteWidth,                -1);        mDeleteHeight = a.getDimensionPixelOffset(R.styleable.XNumberKeyboardView_xnkv_deleteHeight,                -1);        a.recycle();        // 设置软键盘按键的布局        Keyboard keyboard = new Keyboard(context, R.xml.keyboard_number);        setKeyboard(keyboard);        setEnabled(true);        setPreviewEnabled(false); // 设置按键没有点击放大镜显示的效果        setOnKeyboardActionListener(this);    }    @Override    public void onDraw(Canvas canvas) {        super.onDraw(canvas);        // 遍历所有的按键        List<Keyboard.Key> keys = getKeyboard().getKeys();        for (Keyboard.Key key : keys) {            // 如果是左下角空白的按键,重画按键的背景            if (key.codes[0] == KEYCODE_EMPTY) {                drawKeyBackground(key, canvas, mDeleteBackgroundColor);            }            // 如果是右下角的删除按键,重画按键的背景,并且绘制删除图标            else if (key.codes[0] == Keyboard.KEYCODE_DELETE) {                drawKeyBackground(key, canvas, mDeleteBackgroundColor);                drawDeleteButton(key, canvas);            }        }    }    // 绘制按键的背景    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);    }    // 绘制删除按键    private void drawDeleteButton(Keyboard.Key key, Canvas canvas) {        if (mDeleteDrawable == null) {            return;        }        // 计算删除图标绘制的坐标        if (mDeleteDrawRect == null || mDeleteDrawRect.isEmpty()) {            int drawWidth, drawHeight;            int intrinsicWidth = mDeleteDrawable.getIntrinsicWidth();            int intrinsicHeight = mDeleteDrawable.getIntrinsicHeight();            if (mDeleteWidth > 0 && mDeleteHeight > 0) {                drawWidth = mDeleteWidth;                drawHeight = mDeleteHeight;            } else if (mDeleteWidth > 0 && mDeleteHeight <= 0) {                drawWidth = mDeleteWidth;                drawHeight = drawWidth * intrinsicHeight / intrinsicWidth;            } else if (mDeleteWidth <= 0 && mDeleteHeight > 0) {                drawHeight = mDeleteHeight;                drawWidth = drawHeight * intrinsicWidth / intrinsicHeight;            } else {                drawWidth = intrinsicWidth;                drawHeight = intrinsicHeight;            }            // 限制图标的大小,防止图标超出按键            if (drawWidth > key.width) {                drawWidth = key.width;                drawHeight = drawWidth * intrinsicHeight / intrinsicWidth;            }            if (drawHeight > key.height) {                drawHeight = key.height;                drawWidth = drawHeight * intrinsicWidth / intrinsicHeight;            }            // 获取删除图标绘制的坐标            int left = key.x + (key.width - drawWidth) / 2;            int top = key.y + (key.height - drawHeight) / 2;            mDeleteDrawRect = new Rect(left, top, left + drawWidth, top + drawHeight);        }        // 绘制删除的图标        if (mDeleteDrawRect != null && !mDeleteDrawRect.isEmpty()) {            mDeleteDrawable.setBounds(mDeleteDrawRect.left, mDeleteDrawRect.top,                    mDeleteDrawRect.right, mDeleteDrawRect.bottom);            mDeleteDrawable.draw(canvas);        }    }    @Override    public void onKey(int primaryCode, int[] keyCodes) {        // 处理按键的点击事件        // 点击了删除按键        if (primaryCode == Keyboard.KEYCODE_DELETE) {            if (mOnKeyboardListener != null)                mOnKeyboardListener.onDeleteKeyEvent();        }        // 点击了数字按键        else if (primaryCode != KEYCODE_EMPTY) {            if (mOnKeyboardListener != null) {                mOnKeyboardListener.onInsertKeyEvent(Character.toString(                        (char) primaryCode));            }        }    }    // 0-9 数字的 Character 值    private final List<Character> keyCodes = Arrays.asList('0', '1', '2', '3', '4', '5', '6', '7',            '8', '9');    /**     * 随机打乱数字键盘上键位的排列顺序。     */    public void shuffleKeyboard() {        Keyboard keyboard = getKeyboard();        if (keyboard != null && keyboard.getKeys() != null && keyboard.getKeys().size() > 0) {            Collections.shuffle(keyCodes); // 随机排序数字            // 遍历所有的按键            List<Keyboard.Key> keys = getKeyboard().getKeys();            int index = 0;            for (Keyboard.Key key : keys) {                // 如果按键是数字                if (key.codes[0] != KEYCODE_EMPTY && key.codes[0] != Keyboard.KEYCODE_DELETE) {                    char code = keyCodes.get(index++);                    key.codes[0] = code;                    key.label = Character.toString(code);                }            }            setKeyboard(keyboard);        }    }    @Override    public void onPress(int primaryCode) {    }    @Override    public void onRelease(int primaryCode) {    }    @Override    public void onText(CharSequence text) {    }    @Override    public void swipeLeft() {    }    @Override    public void swipeRight() {    }    @Override    public void swipeDown() {    }    @Override    public void swipeUp() {    }    /**     * 设置键盘的监听事件。     *     * @param listener 监听事件     */    public void setIOnKeyboardListener(IOnKeyboardListener listener) {        this.mOnKeyboardListener = listener;    }    /**     * 键盘的监听事件。     */    public interface IOnKeyboardListener {        /**         * 点击数字按键。         *         * @param text 输入的数字         */        void onInsertKeyEvent(String text);        /**         * 点击了删除按键。         */        void onDeleteKeyEvent();    }}
layout.xml
<com.shanlin.autostore.view.XNumberKeyboardView        android:id="@+id/view_keyboard"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_alignParentBottom="true"        android:background="#E1E1E1"        android:focusable="true"        android:focusableInTouchMode="true"        android:keyBackground="@drawable/selector_key_bg"        android:keyTextColor="#000000"        android:shadowColor="@android:color/transparent"        android:shadowRadius="0"        app:xnkv_deleteBackgroundColor="#E0E0E0"        app:xnkv_deleteDrawable="@mipmap/delete"        app:xnkv_deleteWidth="22dp" />
自定义属性文件
<declare-styleable name="XNumberKeyboardView">        <!-- 删除按键的图标 -->        <attr name="xnkv_deleteDrawable" format="reference"/>        <!-- 删除按键图标的宽度 -->        <attr name="xnkv_deleteWidth" format="dimension|reference"/>        <!-- 删除按键图标的高度 -->        <attr name="xnkv_deleteHeight" format="dimension|reference"/>        <!-- 删除按键图标的颜色 -->        <attr name="xnkv_deleteBackgroundColor" format="color|reference"/>    </declare-styleable>
在res 目录下新建一个xml 文件夹,放软键盘资源文件 keyboard_num.xml
        <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:keyIcon="@android:color/transparent" />    </Row></Keyboard>

代码里面就是在键盘监听下进行自己的操作就OK了;

然后是密码输入框控件GridPasswordView , 非常强大, Github地址;使用起来也很方便;

自定义属性如下:
<declare-styleable name="gridPasswordView">        <attr name="gpvTextColor" format="color|reference"/>        <attr name="gpvTextSize" format="dimension"/>        <attr name="gpvLineColor" format="color"/>        <attr name="gpvGridColor" format="color"/>        <attr name="gpvLineWidth" format="dimension"/>        <attr name="gpvPasswordLength" format="integer"/>        <attr name="gpvPasswordTransformation" format="string"/>        <attr name="gpvPasswordType" format="enum">            <enum name="numberPassword" value="0"/>            <enum name="textPassword" value="1"/>            <enum name="textVisiblePassword" value="2"/>            <enum name="textWebPassword" value="3"/>        </attr>    </declare-styleable>





原创粉丝点击