Android基于KeyboardView和Keyboard实现自定义软键盘 自定义键盘背景色

Android基于KeyboardView和Keyboard实现自定义软键盘

在一些特别的情况下我们需要去自定义键盘
例如: 银行app的密码输入之类的

笨方法就是直接使用布局写我们的自定义软键盘
但这样写的话我们的代码量就很多
Android官方提供了KeyboardView和Keyboard两个类
我们可以用这两个类去实现自己的软键盘

Demo 已上传 GitHub
https://github.com/pengchengfuGit/DIYKeyboard.git

1.主界面的布局与代码

这是我们主界面的xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:background="@android:color/darker_gray"
    android:layout_height="match_parent">

    <EditText
        android:id="@+id/et"
        android:layout_width="match_parent"
        android:layout_height="50dp" />

    <android.inputmethodservice.KeyboardView
        android:id="@+id/kv_keyboard"
        android:background="@android:color/white"
        android:layout_width="match_parent"
        android:keyBackground="@android:color/holo_purple"
        android:keyTextColor="#333333"
        android:focusable="true"
        android:focusableInTouchMode="true"
        android:paddingTop="1dp"
        android:shadowColor="#FFFFFF"
        android:shadowRadius="0.0"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true" />

</RelativeLayout>

主界面的Activity 这里写了个KeyBoardUtil来初始的我们自定义软键盘

public class MainActivity extends Activity {
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_payment);
        final KeyboardView keyboard = (KeyboardView) findViewById(R.id.kv_keyboard);
        final EditText editText = (EditText) findViewById(R.id.et);
        //在我们点EditText的时候弹出我们的软键盘
        editText.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if(editText.hasFocus()){
                    //用来初始化我们的软键盘
                    new KeyBoardUtil(keyboard,editText).showKeyboard();
                }
                return false;
            }
        });
    }
}

2.KeyBoard的键盘按钮配置

这是配置我们自定义软键盘的按钮的
软键盘显示的按钮通过xml来配置
这个xml的文件放个res/xml/… 目录
没有xml文件夹的 手动创建一个
** keyWidth , keyHeight 可以采用百分比的写法
** android:keyWidth=”25%p”

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

    <Row>
        <Key
            android:keyIcon="@color/white"
            android:codes="49"
            android:keyLabel="1" />
        <Key
            android:codes="50"
            android:keyLabel="2" />
        <Key
            android:codes="51"
            android:keyLabel="3" />
        <Key
            android:codes="-5"
            android:keyLabel="删除" />
    </Row>

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


        <Key
            android:codes="-4"
            android:keyHeight="150dp"
            android:keyLabel="完成"/>
    </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="46"
            android:keyLabel="." />
        <Key
            android:keyWidth="50.2%p"
            android:codes="48"
            android:keyLabel="0" />
    </Row>
</Keyboard>

这里解释下xml里的几个参数

属性 说明
keyLabel 按键显示的内容
keyIcon 按键显示的图标内容
keyWidth 按键的宽度
keyHeight 按键的高度
horizontalGap 代表按键前的间隙水平方向上的
isSticky 按键是否是sticky的,就像shift 键 具有两种状态
isModifier 按键是不是功能键
keyOutputText 指定按键输出的内容是字符串
isRepeatable 按键是可重复的,如果长按键可以触发重复按键事件则为true,else为false
keyEdgeFlags 指定按键的对齐指令,取值为left或者right

一些特殊的按键的codes建议采用系统已经定义好的值
常见的像删除 确认 取消

public static final int EDGE_LEFT = 1;
public static final int EDGE_RIGHT = 2;
public static final int EDGE_TOP = 4;
public static final int EDGE_BOTTOM = 8;
public static final int KEYCODE_SHIFT = -1;
public static final int KEYCODE_MODE_CHANGE = -2;
public static final int KEYCODE_CANCEL = -3;
public static final int KEYCODE_DONE = -4;
public static final int KEYCODE_DELETE = -5
public static final int KEYCODE_ALT = -6;

3.配置软键盘

配置软键盘中的实现 我把它放在了KeyBoardUtil

import android.content.Context;
import android.inputmethodservice.Keyboard;
import android.inputmethodservice.KeyboardView;
import android.text.Editable;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;

public class KeyBoardUtil {

    private KeyboardView keyboardView;
    private EditText editText;
    private Keyboard k1;// 自定义键盘

    public KeyBoardUtil(KeyboardView keyboardView, EditText editText) {
        //setInputType为InputType.TYPE_NULL   不然会弹出系统键盘  
        editText.setInputType(InputType.TYPE_NULL);
        k1 = new Keyboard(editText.getContext(), R.xml.key);
        this.keyboardView = keyboardView;
        this.editText = editText;
        this.keyboardView.setOnKeyboardActionListener(listener);
        this.keyboardView.setKeyboard(k1);
        this.keyboardView.setEnabled(true);
        this.keyboardView.setPreviewEnabled(false);
    }

    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 = editText.getText();
            int start = editText.getSelectionStart();
            switch (primaryCode) {
                case Keyboard.KEYCODE_DELETE:
                    if (editable != null && editable.length() > 0) {
                        if (start > 0) {
                            editable.delete(start - 1, start);
                        }
                    }
                    break;
                case Keyboard.KEYCODE_CANCEL:
                    keyboardView.setVisibility(View.GONE);
                    break;
                default:
                    editable.insert(start, Character.toString((char) primaryCode));
                    break;
            }
        }
    };

    // Activity中获取焦点时调用,显示出键盘
    public void showKeyboard() {
        int visibility = keyboardView.getVisibility();
        if (visibility == View.GONE || visibility == View.INVISIBLE) {
            keyboardView.setVisibility(View.VISIBLE);
        }
    }

    // 隐藏键盘
    public void hideKeyboard() {
        int visibility = keyboardView.getVisibility();
        if (visibility == View.VISIBLE|| visibility == View.INVISIBLE) {
            keyboardView.setVisibility(View.GONE);
        }
    }
}

这样我们的软键盘就实现了

自定义键盘背景色

有时候我们给不同的按键, 设置不同的背景色
像下图的确定按钮

这里写图片描述

这时用原生的KeyboardView和Keyboard是实现不了的
原生的只能所有的按钮都是统一的样式
字体颜色 , 按键背景色

那如何实现我们不同按键不同的字体颜色,不同的背景色呢
这时我们可以去重写KeyboardView的OnDraw()方法


public class DIYKeyboardView extends KeyboardView {

    public DIYKeyboardView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Keyboard keyboard = getKeyboard();
        if (keyboard == null) return;
        List<Keyboard.Key> keys = keyboard.getKeys();
        if (keys != null && keys.size() > 0) {
            Paint paint = new Paint();
            paint.setTextAlign(Paint.Align.CENTER);
            Typeface font = Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD);
            paint.setTypeface(font);
            paint.setAntiAlias(true);
            for (Keyboard.Key key : keys) {
                if (key.codes[0] == -3) {
                    Drawable dr = getContext().getResources().getDrawable(R.drawable.keyboard_blue);
                    dr.setBounds(key.x, key.y, key.x + key.width, key.y + key.height);
                    dr.draw(canvas);
                } else {
                    Drawable dr = getContext().getResources().getDrawable(R.drawable.keyboard_white);
                    dr.setBounds(key.x, key.y, key.x + key.width, key.y + key.height);
                    dr.draw(canvas);
                }
                if (key.label != null) {
                    if (key.codes[0] == -4 ||
                            key.codes[0] == -5) {
                        paint.setTextSize(17 * 2);
                    } else {
                        paint.setTextSize(20 * 2);
                    }
                    if (key.codes[0] == -4) {
                        paint.setColor(getContext().getResources().getColor(R.color.white));
                    } else {
                        paint.setColor(getContext().getResources().getColor(R.color.blue_03A9F4));
                    }
                    Rect rect = new Rect(key.x, key.y, key.x + key.width, key.y + key.height);
                    Paint.FontMetricsInt fontMetrics = paint.getFontMetricsInt();
                    int baseline = (rect.bottom + rect.top - fontMetrics.bottom - fontMetrics.top) / 2;
                    // 下面这行是实现水平居中,drawText对应改为传入targetRect.centerX()
                    paint.setTextAlign(Paint.Align.CENTER);
                    canvas.drawText(key.label.toString(), rect.centerX(), baseline, paint);
                }
            }
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qq_29983773/article/details/79501658