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:
- The KeyBoardView class of the integrated system initializes the KeyBoard layout and sets the KeyBoard object during initialization.
- Implement the OnKeyboardActionListener interface to handle key interaction events.
- Draw the key background and key icon as required.
- 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: