原標題:Android 自定義控件 - 仿支付寶數字鍵盤
簡介
在一些帶有支付功能的 App 中,輸入的密碼一般只能是純數字,雖然我們可以指定 EditText 輸入框只能輸入數字,但是為了提供用戶的使用體驗,我們往往更傾向于使用自定義的純數字鍵盤。
本文效果:
實現步驟:
集成系統的 KeyBoardView 類,在初始化時初始化鍵盤布局,設置 KeyBoard 對象。
實現 OnKeyboardActionListener 接口,處理按鍵交互事件。
根據需求繪制按鍵背景和按鍵圖標。
設置監聽器,將輸入的內容回調給調用方。
鍵盤布局
在 res/xml/ 目錄下創建 xml 文件:key_password_number.xml
android:horizontalGap="1dp"
android:keyHeight="9%p"
android:keyWidth="33.3333%p"
android:verticalGap="1dp">
android:codes="49"
android:keyLabel="1"/>
android:codes="50"
android:keyLabel="2"/>
android:codes="51"
android:keyLabel="3"/>
android:codes="52"
android:keyLabel="4"/>
android:codes="53"
android:keyLabel="5"/>
android:codes="54"
android:keyLabel="6"/>
android:codes="55"
android:keyLabel="7"/>
android:codes="56"
android:keyLabel="8"/>
android:codes="57"
android:keyLabel="9"/>
android:codes="-10"
android:keyLabel=""/>
android:codes="48"
android:keyLabel="0"/>
android:codes="-5"
android:keyLabel=""/>
繼承 KeyBoardView
publicclassPwdKeyboardViewextendsKeyboardViewimplementsKeyboardView.OnKeyboardActionListener{
privatestaticfinalString TAG = "PwdKeyboardView";
privatestaticfinalintKEY_EMPTY = - 10;
privateintdelKeyBackgroundColor = 0xffcccccc;
privateRect keyIconRect;
publicPwdKeyboardView(Context context, AttributeSet attrs){
super(context, attrs);
Log.d(TAG, "PwdKeyboardView: two params");
init(context);
}
publicPwdKeyboardView(Context context, AttributeSet attrs, intdefStyleAttr){
super(context, attrs, defStyleAttr);
Log.d(TAG, "PwdKeyboardView: three params");
init(context);
}
privatevoidinit(Context context){
Keyboard keyboard = newKeyboard(context, R.xml.key_password_number); // 初始化 keyboard
setKeyboard(keyboard);
setEnabled( true);
setFocusable( true);
setPreviewEnabled( false); // 設置點擊按鍵不顯示預覽氣泡
setOnKeyboardActionListener( this);
}
/**
* 重新繪制刪除按鍵和空白鍵
*
* @paramcanvas
*/
@Override
publicvoidonDraw(Canvas canvas){
super.onDraw(canvas);
List keys = getKeyboard().getKeys();
for(Keyboard.Key key : keys) {
if(key.codes[ 0] == KEY_EMPTY) {
// 繪制空白鍵背景
drawKeyBackground(key, canvas, delKeyBackgroundColor);
}
if(key.codes[ 0] == Keyboard.KEYCODE_DELETE) {
// 刪除刪除按鍵背景
drawKeyBackground(key, canvas, delKeyBackgroundColor);
// 繪制刪除按鍵圖標
drawKeyIcon(key, canvas, getResources().getDrawable(R.drawable.ic_delete));
}
}
}
/**
* 繪制按鍵的背景
*
* @paramkey
* @paramcanvas
* @paramcolor
*/
privatevoiddrawKeyBackground(Keyboard.Key key, Canvas canvas, intcolor){
ColorDrawable drawable = newColorDrawable(color);
drawable.setBounds(key.x, key.y, key.x + key.width, key.y + key.height);
drawable.draw(canvas);
}
/**
* 繪制按鍵的 icon
*
* @paramkey
* @paramcanvas
* @paramiconDrawable
*/
privatevoiddrawKeyIcon(Keyboard.Key key, Canvas canvas, Drawable iconDrawable){
if(iconDrawable == null) {
return;
}
// 計算按鍵icon 的rect 范圍
if(keyIconRect == null|| keyIconRect.isEmpty()) {
// 得到 keyicon 的顯示大小,因為圖片放在不同的drawable-dpi目錄下,顯示大小也不一樣
intintrinsicWidth = iconDrawable.getIntrinsicWidth();
intintrinsicHeight = iconDrawable.getIntrinsicHeight();
intdrawWidth = intrinsicWidth;
intdrawHeight = intrinsicHeight;
// 限制圖片的大小,防止圖片按鍵范圍
if(drawWidth > key.width) {
drawWidth = key.width;
// 此時高就按照比例縮放
drawHeight = ( int) (drawWidth * 1.0f/ intrinsicWidth * intrinsicHeight);
} elseif(drawHeight > key.height) {
drawHeight = key.height;
drawWidth = ( int) (drawHeight * 1.0f/ intrinsicHeight * intrinsicWidth);
}
// 獲取圖片的 x,y 坐標,圖片在按鍵的正中間
intleft = key.x + key.width / 2- drawWidth / 2;
inttop = key.y + key.height / 2- drawHeight / 2;
keyIconRect = newRect(left, top, left + drawWidth, top + drawHeight);
}
if(keyIconRect != null&& !keyIconRect.isEmpty()) {
iconDrawable.setBounds(keyIconRect);
iconDrawable.draw(canvas);
}
}
@Override
publicvoidonPress(intprimaryCode){
}
@Override
publicvoidonRelease(intprimaryCode){
}
/**
* 處理按鍵的點擊事件
*/
@Override
publicvoidonKey(intprimaryCode, 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
publicvoidonText(CharSequence charSequence){
}
@Override
publicvoidswipeLeft(){
}
@Override
publicvoidswipeRight(){
}
@Override
publicvoidswipeDown(){
}
@Override
publicvoidswipeUp(){
}
publicinterfaceOnKeyListener{
// 輸入回調
voidonInput(String text);
// 刪除回調
voidonDelete();
}
privateOnKeyListener listener;
publicvoidsetOnKeyListener(OnKeyListener listener){
this.listener = listener;
}
}
使用 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"
android:keyTextColor= "@android:color/black"
android:keyTextSize= "26sp"
android:shadowRadius= "0"/>
顯示結果為:
完整代碼:https://github.com/xing16/PwdKeyboardView返回搜狐,查看更多
責任編輯: