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);
                }
            }
        }
    }
}
  • 4
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
Android 中,自定义软键盘需要实现一个继承自 InputMethodService 的服务,这个服务会在用户打开软键盘时被调用。下面是一些步骤来创建自定义软键盘: 1. 创建一个新的 Android 项目,并在 AndroidManifest.xml 文件中声明一个新的服务: ```xml <service android:name=".CustomKeyboard" android:label="Custom Keyboard" android:permission="android.permission.BIND_INPUT_METHOD"> <meta-data android:name="android.view.im" android:resource="@xml/method" /> </service> ``` 上面的代码声明了一个名为 CustomKeyboard 的服务,并将其与 android.view.im 绑定。在 res/xml 目录下创建一个名为 method.xml 的文件,用于指定 CustomKeyboard 的布局和行为: ```xml <?xml version="1.0" encoding="utf-8"?> <input-method xmlns:android="http://schemas.android.com/apk/res/android" android:settingsActivity=".SettingsActivity" android:imeSubtypeLocale="en_US" android:imeSubtypeMode="keyboard" > </input-method> ``` 上面的代码指定了键盘的设置活动、语言环境和子类型模式。 2. 创建 CustomKeyboard 类,并继承 InputMethodService。在这个类中,你需要重写一些回调方法,例如 onCreateInputView()、onKeyDown() 和 onStartInputView() 等。这些方法将决定键盘的外观和行为。 ```java public class CustomKeyboard extends InputMethodService implements KeyboardView.OnKeyboardActionListener { private KeyboardView keyboardView; private Keyboard keyboard; @Override public View onCreateInputView() { keyboardView = (KeyboardView) getLayoutInflater().inflate(R.layout.keyboard, null); keyboard = new Keyboard(this, R.xml.qwerty); keyboardView.setKeyboard(keyboard); keyboardView.setOnKeyboardActionListener(this); return keyboardView; } @Override public void onStartInputView(EditorInfo info, boolean restarting) { super.onStartInputView(info, restarting); keyboardView.setPreviewEnabled(false); } @Override public void onKey(int primaryCode, int[] keyCodes) { InputConnection ic = getCurrentInputConnection(); switch (primaryCode) { case Keyboard.KEYCODE_DELETE: ic.deleteSurroundingText(1, 0); break; case Keyboard.KEYCODE_SHIFT: // do something break; default: char c = (char) primaryCode; ic.commitText(String.valueOf(c), 1); } } } ``` 上面的代码创建了一个名为 CustomKeyboard 的类,并在 onCreateInputView() 方法中设置了键盘的布局和行为。在 onStartInputView() 方法中,我们禁用了键盘预览功能。在 onKey() 方法中,我们检查按下的键码并执行相应的操作。 3. 创建键盘布局。在 res/xml 目录下创建一个名为 qwerty.xml 的文件,用于指定键盘布局: ```xml <?xml version="1.0" encoding="utf-8"?> <Keyboard xmlns:android="http://schemas.android.com/apk/res/android" android:keyWidth="10%p" android:keyHeight="60dp" android:horizontalGap="0px" android:verticalGap="0px" android:keyEdgeFlags="left"> <Row> <Key android:keyLabel="q" android:keyEdgeFlags="left"/> <Key android:keyLabel="w"/> <Key android:keyLabel="e"/> <Key android:keyLabel="r"/> <Key android:keyLabel="t"/> <Key android:keyLabel="y"/> <Key android:keyLabel="u"/> <Key android:keyLabel="i"/> <Key android:keyLabel="o"/> <Key android:keyLabel="p" android:keyEdgeFlags="right"/> </Row> <Row> <Key android:keyLabel="a" android:keyEdgeFlags="left"/> <Key android:keyLabel="s"/> <Key android:keyLabel="d"/> <Key android:keyLabel="f"/> <Key android:keyLabel="g"/> <Key android:keyLabel="h"/> <Key android:keyLabel="j"/> <Key android:keyLabel="k"/> <Key android:keyLabel="l android:keyEdgeFlags="right"/> </Row> <Row> <Key android:keyLabel="shift" android:horizontalGap="10%p" android:keyWidth="20%p" android:keyEdgeFlags="left" android:isModifier="true" android:isSticky="true"/> <Key android:keyLabel="z"/> <Key android:keyLabel=""/> <Key android:keyLabel="c"/> <Key android:keyLabel="v"/> <Key android:keyLabel="b"/> <Key android:keyLabel="n"/> <Key android:keyLabel="m"/> <Key android:keyLabel="delete" android:keyWidth="20%p" android:keyEdgeFlags="right" android:icon="@drawable/ic_delete"/> </Row> <Row> <Key android:keyLabel="123" android:keyEdgeFlags="left" android:keyWidth="20%p"/> <Key android:keyLabel=" " android:keyWidth="40%p"/> <Key android:keyLabel="return" android:keyWidth="20%p" android:keyEdgeFlags="right"/> </Row> </Keyboard> ``` 上面的代码指定了一个基本的 QWERTY 键盘布局,包含字母、数字和删除键。 4. 运行应用程序并测试自定义软键盘。在测试键盘时,你需要在 Android 设备的输入法设置中激活你的自定义键盘。 以上就是创建自定义软键盘的基本步骤,你可以根据需要修改键盘的布局和行为。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值