Android基于KeyboardView和Keyboard实现自定义软键盘 自定义键盘背景色
16lz
2021-01-26
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 = -5public 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.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); } } } }}
更多相关文章
- 在android的状态栏中增加menu,home和back快捷键的方法
- 【Android(安卓)UI设计与开发】8.顶部标题栏(一)ActionBar 奥义·
- Android(安卓)可拖动的悬浮按钮
- 《Android(安卓)应用》TextView追加文本并向下滚动
- Android模拟器使用KSOAP2调用WebService
- Android(安卓)学习 之 键盘问题
- 软键盘弹出后ScrollView设置为滚动
- Android(安卓)中文 API (25) —— ZoomControls
- CheckBox选择按钮,换颜色