Android custom numeric keyboard
- Use TableLayout to create the numeric keyboard layout.
- Bind View.OnClickListener on each custom key view to response user input.
- In responses, append or delete text to that password field which implements by EditText.You can use append() or setText() to control what will be filled in the password field.
I write a custom view for reusing in anywhere, here is the code:
KeyboardView.java
public class KeyboardView extends FrameLayout implements View.OnClickListener {
private EditText mPasswordField;
public KeyboardView(Context context) {
super(context);
init();
}
public KeyboardView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public KeyboardView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
inflate(getContext(), R.layout.keyboard, this);
initViews();
}
private void initViews() {
mPasswordField = $(R.id.password_field);
$(R.id.t9_key_0).setOnClickListener(this);
$(R.id.t9_key_1).setOnClickListener(this);
$(R.id.t9_key_2).setOnClickListener(this);
$(R.id.t9_key_3).setOnClickListener(this);
$(R.id.t9_key_4).setOnClickListener(this);
$(R.id.t9_key_5).setOnClickListener(this);
$(R.id.t9_key_6).setOnClickListener(this);
$(R.id.t9_key_7).setOnClickListener(this);
$(R.id.t9_key_8).setOnClickListener(this);
$(R.id.t9_key_9).setOnClickListener(this);
$(R.id.t9_key_clear).setOnClickListener(this);
$(R.id.t9_key_backspace).setOnClickListener(this);
}
@Override
public void onClick(View v) {
// handle number button click
if (v.getTag() != null && "number_button".equals(v.getTag())) {
mPasswordField.append(((TextView) v).getText());
return;
}
switch (v.getId()) {
case R.id.t9_key_clear: { // handle clear button
mPasswordField.setText(null);
}
break;
case R.id.t9_key_backspace: { // handle backspace button
// delete one character
Editable editable = mPasswordField.getText();
int charCount = editable.length();
if (charCount > 0) {
editable.delete(charCount - 1, charCount);
}
}
break;
}
}
public String getInputText() {
return mPasswordField.getText().toString();
}
protected <T extends View> T $(@IdRes int id) {
return (T) super.findViewById(id);
}
}
layout keyboard.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="8dp">
<EditText
android:id="@+id/password_field"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:background="#eeeeee"
android:enabled="false"
android:minHeight="48dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceMedium"/>
<TableLayout
android:id="@+id/keyboard"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/white"
android:divider="@drawable/keyboard_divider"
android:orientation="vertical"
android:showDividers="beginning|middle|end">
<TableRow style="@style/keyboard_row">
<TextView
android:id="@+id/t9_key_1"
style="@style/keyboard_number_button"
android:text="@string/number_one"/>
<TextView
android:id="@+id/t9_key_2"
style="@style/keyboard_number_button"
android:text="@string/number_two"/>
<TextView
android:id="@+id/t9_key_3"
style="@style/keyboard_number_button"
android:text="@string/number_three"/>
</TableRow>
<TableRow style="@style/keyboard_row">
<TextView
android:id="@+id/t9_key_4"
style="@style/keyboard_number_button"
android:text="@string/number_four"/>
<TextView
android:id="@+id/t9_key_5"
style="@style/keyboard_number_button"
android:text="@string/number_five"/>
<TextView
android:id="@+id/t9_key_6"
style="@style/keyboard_number_button"
android:text="@string/number_six"/>
</TableRow>
<TableRow style="@style/keyboard_row">
<TextView
android:id="@+id/t9_key_7"
style="@style/keyboard_number_button"
android:text="@string/number_seven"/>
<TextView
android:id="@+id/t9_key_8"
style="@style/keyboard_number_button"
android:text="@string/number_eight"/>
<TextView
android:id="@+id/t9_key_9"
style="@style/keyboard_number_button"
android:text="@string/number_nine"/>
</TableRow>
<TableRow style="@style/keyboard_row">
<TextView
android:id="@+id/t9_key_clear"
style="@style/keyboard_button"
android:text="@string/btn_clear"
android:textAppearance="?android:attr/textAppearanceMedium"/>
<TextView
android:id="@+id/t9_key_0"
style="@style/keyboard_number_button"
android:text="@string/number_zero"/>
<TextView
android:id="@+id/t9_key_backspace"
style="@style/keyboard_button"
android:text="@string/btn_backspace"
android:textAppearance="?android:attr/textAppearanceMedium"/>
</TableRow>
</TableLayout>
</LinearLayout>
style.xml
<style name="keyboard_row">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:divider">@drawable/keyboard_divider</item>
<item name="android:gravity">center</item>
<item name="android:showDividers">beginning|middle|end</item>
</style>
<style name="keyboard_button">
<item name="android:layout_width">0dp</item>
<item name="android:layout_height">match_parent</item>
<item name="android:layout_weight">1</item>
<item name="android:paddingTop">12dp</item>
<item name="android:paddingBottom">12dp</item>
<item name="android:clickable">true</item>
<item name="android:gravity">center</item>
<item name="android:scaleType">centerInside</item>
<item name="android:background">@drawable/keyboard_button_bg</item>
<item name="android:textAppearance">?android:attr/textAppearanceLarge</item>
</style>
<style name="keyboard_number_button" parent="keyboard_button">
<item name="android:tag">number_button</item>
</style>
drawable keyboard_button_bg.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" android:exitFadeDuration="@android:integer/config_shortAnimTime">
<item android:state_pressed="true">
<shape>
<solid android:color="#dddddd"/>
</shape>
</item>
<item android:state_pressed="false">
<shape>
<solid android:color="@android:color/transparent"/>
</shape>
</item>
</selector>
drawable keyboard_divider.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#dddddd"/>
<size
android:width="1px"
android:height="1px"/>
</shape>
strings.xml
<string name="number_zero">0</string>
<string name="number_one">1</string>
<string name="number_two">2</string>
<string name="number_three">3</string>
<string name="number_four">4</string>
<string name="number_five">5</string>
<string name="number_six">6</string>
<string name="number_seven">7</string>
<string name="number_eight">8</string>
<string name="number_nine">9</string>
<string name="btn_clear">Clear</string>
<string name="btn_backspace">Back</string>
Use the custom KeyboardView
in your layout :
<com.xxx.yyy.KeyboardView
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
Old answer:
The keyboard layout code looks like this:
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/anti_theft_t9_grid"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white_grey"
android:divider="@android:color/darker_gray"
android:orientation="vertical"
android:showDividers="middle|beginning|end" >
<TableRow
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:divider="@android:color/darker_gray"
android:gravity="center"
android:showDividers="middle" >
<TextView
android:id="@+id/anti_theft_t9_key_1"
style="@style/anti_theft_t9_key"
android:text="@string/number_one"
android:textIsSelectable="false" />
<TextView
android:id="@+id/anti_theft_t9_key_2"
style="@style/anti_theft_t9_key"
android:text="@string/number_two"
android:textIsSelectable="false" />
<TextView
android:id="@+id/anti_theft_t9_key_3"
style="@style/anti_theft_t9_key"
android:text="@string/number_three"
android:textIsSelectable="false" />
</TableRow>
<TableRow
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:divider="@android:color/darker_gray"
android:gravity="center"
android:showDividers="middle" >
<TextView
android:id="@+id/anti_theft_t9_key_4"
style="@style/anti_theft_t9_key"
android:text="@string/number_four"
android:textIsSelectable="false" />
<TextView
android:id="@+id/anti_theft_t9_key_5"
style="@style/anti_theft_t9_key"
android:text="@string/number_five"
android:textIsSelectable="false" />
<TextView
android:id="@+id/anti_theft_t9_key_6"
style="@style/anti_theft_t9_key"
android:text="@string/number_six"
android:textIsSelectable="false" />
</TableRow>
<TableRow
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:divider="@android:color/darker_gray"
android:gravity="center"
android:showDividers="middle" >
<TextView
android:id="@+id/anti_theft_t9_key_7"
style="@style/anti_theft_t9_key"
android:text="@string/number_seven"
android:textIsSelectable="false" />
<TextView
android:id="@+id/anti_theft_t9_key_8"
style="@style/anti_theft_t9_key"
android:text="@string/number_eight"
android:textIsSelectable="false" />
<TextView
android:id="@+id/anti_theft_t9_key_9"
style="@style/anti_theft_t9_key"
android:text="@string/number_nine"
android:textIsSelectable="false" />
</TableRow>
<TableRow
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:divider="@android:color/darker_gray"
android:gravity="center"
android:showDividers="middle" >
<TextView
android:id="@+id/anti_theft_t9_key_clear"
style="@style/anti_theft_t9_key"
android:text="@string/anti_theft_keyboard_clear"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textIsSelectable="false" />
<TextView
android:id="@+id/anti_theft_t9_key_0"
style="@style/anti_theft_t9_key"
android:text="@string/number_zero"
android:textIsSelectable="false" />
<ImageView
android:id="@+id/anti_theft_t9_key_backspace"
style="@style/anti_theft_t9_key"
android:contentDescription="@string/app_name_for_anti_theft"
android:src="@drawable/anti_theft_keyboard_backspace"
android:textIsSelectable="false" />
</TableRow>
</TableLayout>
Each key style:
<style name="anti_theft_t9_key">
<item name="android:layout_width">0dp</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_weight">1</item>
<item name="android:paddingTop">@dimen/anti_theft_t9_key_paddingTop</item>
<item name="android:paddingBottom">@dimen/anti_theft_t9_key_paddingBottom</item>
<item name="android:clickable">true</item>
<item name="android:gravity">center</item>
<item name="android:scaleType">centerInside</item>
<item name="android:background">@drawable/anti_theft_btn_blue_bg</item>
<item name="android:textAppearance">?android:attr/textAppearanceLarge</item>
</style>
Responses of each key:
private EditText mEtPassword ;
private void setViews(){
// find view references...
// set OnClickListener to each key view...
}
private void onT9KeyClicked(int key) {
switch (key) {
case R.id.anti_theft_t9_key_0:
mEtPassword.append("0");
break;
case R.id.anti_theft_t9_key_1:
mEtPassword.append("1");
break;
case R.id.anti_theft_t9_key_2:
mEtPassword.append("2");
break;
case R.id.anti_theft_t9_key_3:
mEtPassword.append("3");
break;
case R.id.anti_theft_t9_key_4:
mEtPassword.append("4");
break;
case R.id.anti_theft_t9_key_5:
mEtPassword.append("5");
break;
case R.id.anti_theft_t9_key_6:
mEtPassword.append("6");
break;
case R.id.anti_theft_t9_key_7:
mEtPassword.append("7");
break;
case R.id.anti_theft_t9_key_8:
mEtPassword.append("8");
break;
case R.id.anti_theft_t9_key_9:
mEtPassword.append("9");
break;
case R.id.anti_theft_t9_key_backspace: {
// delete one character
String passwordStr = mEtPassword.getText().toString();
if (passwordStr.length() > 0) {
String newPasswordStr = new StringBuilder(passwordStr)
.deleteCharAt(passwordStr.length() - 1).toString();
mEtPassword.setText(newPasswordStr);
}
}
break;
case R.id.anti_theft_t9_key_clear:
// clear password field
mEtPassword.setText(null);
break;
}
}