Android 最簡單的自定義數字鍵盤之一

Jooyer發表於2018-06-25

作者: Jooyer, 時間: 2018.6 .8

Github地址,歡迎點贊,fork

只需要四個類 + 幾個 XML 檔案即可,即拷即用

接下來我們依次講解:

  1. NumberKeyboardView
  2. KeyboardContainer
  3. key_board_container.xml
  4. KeyboardUtil
  5. OnDoneListener
  6. 其他幾個 XML 檔案

首先我們看看 NumberKeyboardView 真面目:

// 這裡必須繼承自 KeyboardView,至於構造方法和獲取屬性則是一般套路
public class NumberKeyboardView extends KeyboardView {
    private static final String TAG = NumberKeyboardView.class.getSimpleName();
    private Drawable rKeyBackground;
    private Paint mPaint;
    private int rLabelTextSize;
    private int rKeyTextSize;
    private int rKeyTextColor;
    private float rShadowRadius;
    private int rShadowColor;

    public NumberKeyboardView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context,attrs);
    }

    public NumberKeyboardView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context,attrs);
    }

// 獲取自定義的屬性,很多 demo 使用反射,其他我們可以換個套路,自己定義屬性就好了
    private void init(Context context, AttributeSet attrs) {
        TypedArray arr = context.obtainStyledAttributes(attrs,R.styleable.NumberKeyboardView);
        rKeyBackground = arr.getDrawable(R.styleable.NumberKeyboardView_keyBackground);
        if (null  == rKeyBackground){
            rKeyBackground = context.getResources().getDrawable(R.drawable.key_number_bg);
        }
        rLabelTextSize =    arr.getDimensionPixelSize(R.styleable.NumberKeyboardView_labelTextSize,18);
        rKeyTextSize = arr.getDimensionPixelSize(R.styleable.NumberKeyboardView_keyTextSize,18);
        rKeyTextColor = arr.getColor(R.styleable.NumberKeyboardView_keyTextColor,0xFF000000);
        rShadowColor = arr.getColor(R.styleable.NumberKeyboardView_shadowColor,0);
        rShadowRadius = arr.getFloat(R.styleable.NumberKeyboardView_shadowRadius,0f);
        arr.recycle();

		// 初始化畫筆
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setTextSize(rKeyTextSize);
        mPaint.setTextAlign(Paint.Align.CENTER);
        mPaint.setAlpha(255);
    }

    @Override
    public void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        onRefreshKey(canvas);
    }

    /**
     * onRefreshKey是對父類的private void onBufferDraw()進行的重寫.
     * 只是在對key的繪製過程中進行了重新設定.
     */
    private void onRefreshKey(Canvas canvas) {
        final int kbdPaddingLeft = getPaddingLeft();
        final int kbdPaddingTop = getPaddingTop();
        Drawable keyBackground = null;
        mPaint.setColor(rKeyTextColor);
        List<Keyboard.Key> keys = getKeyboard().getKeys();
        // 遍歷每一個 key ,key 來自於 res/xml/ 中的檔案定義的
        for (Keyboard.Key key : keys) {
            keyBackground = key.iconPreview;
            if (null == keyBackground) {
                keyBackground = rKeyBackground;
            }
            int[] drawableState = key.getCurrentDrawableState();
            keyBackground.setState(drawableState);
            CharSequence keyLabel = key.label;
            String label = keyLabel == null ? null : adjustCase(keyLabel).toString();
            final Rect bounds = keyBackground.getBounds();
            if (key.width != bounds.right ||
                    key.height != bounds.bottom) {
                keyBackground.setBounds(0, 0, key.width, key.height);
            }
            canvas.translate(key.x + kbdPaddingLeft, key.y + kbdPaddingTop);
            // 繪製每一個 key 背景
            keyBackground.draw(canvas);
            if (label != null) { // 繪製每一個 key 上面的文字資訊
                mPaint.setColor(rKeyTextColor);
                if (key.codes[0] == getKeyCode(R.integer.action_done)) {
                    mPaint.setTextSize(dp2px(rLabelTextSize));
                    mPaint.setTypeface(Typeface.DEFAULT);
                    mPaint.setColor(Color.WHITE);
                } else if (key.codes[0] == getKeyCode(R.integer.line_feed)) {
                    mPaint.setTextSize(dp2px(16));
                    mPaint.setTypeface(Typeface.DEFAULT);
                } else if (label.length() > 1 && key.codes.length < 2) {
                    mPaint.setTextSize(dp2px(rLabelTextSize));
                    mPaint.setTypeface(Typeface.DEFAULT);
                } else {
                    mPaint.setTextSize(dp2px(rKeyTextSize));
                    mPaint.setTypeface(Typeface.DEFAULT);
                }

                // 繪製每一個 key(沒有設定圖片的) 底部陰影
                mPaint.setShadowLayer(rShadowRadius, 0, 0, rShadowColor);
                // Draw the text
                canvas.drawText(label,
                        key.width/ 2,
                        key.height / 2  + (mPaint.getTextSize() - mPaint.descent()) / 2,
                        mPaint);
                // Turn off drop shadow
                mPaint.setShadowLayer(0, 0, 0, 0);
            } else if (key.icon != null) { // 繪製鍵盤上的圖示
                final int drawableX = (key.width
                        - key.icon.getIntrinsicWidth()) / 2 ;
                final int drawableY = (key.height
                        - key.icon.getIntrinsicHeight()) / 2 ;
                canvas.translate(drawableX, drawableY);
                key.icon.setBounds(0, 0,
                        key.icon.getIntrinsicWidth(), key.icon.getIntrinsicHeight());
                key.icon.draw(canvas);
                canvas.translate(-drawableX, -drawableY);
            }
            canvas.translate(-key.x - kbdPaddingLeft, -key.y - kbdPaddingTop);
        }
    }


    private int getKeyCode(@IntegerRes int redId) {
        return getContext().getResources().getInteger(redId);
    }

    private int dp2px(int def) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, def, getResources().getDisplayMetrics());
    }

	// 參考了大神們的作品,其實這裡都是數字鍵,這個方法沒有什麼作用,具體參考連結,文章末尾給出
    private CharSequence adjustCase(CharSequence label) {
        if (getKeyboard().isShifted() && label != null && label.length() < 3
                && Character.isLowerCase(label.charAt(0))) {
            label = label.toString().toUpperCase();
        }
        return label;
    }
	
	// 動態設定 如 確定 這種文字大小
    public void setTextSize(int textSize) {
        rLabelTextSize = textSize;
    }
}
複製程式碼

其實就是根據 xml 中數字和文字,圖片繪製到 canvas 中.

然後我們看看 KeyboardContainer

public class KeyboardContainer extends ConstraintLayout {
    private NumberKeyboardView mNumberKeyboardView;

    public KeyboardContainer(Context context) {
        this(context, null);
    }

    public KeyboardContainer(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public KeyboardContainer(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    private void init(Context context) {
        View view = LayoutInflater.from(context).inflate(R.layout.key_board_container, this, true);
        mNumberKeyboardView = (NumberKeyboardView) view.findViewById(R.id.number_keyboard_view);
        mNumberKeyboardView.setEnabled(true);
        mNumberKeyboardView.setPreviewEnabled(false);
    }

    public void setOnKeyboardActionListener(KeyboardView.OnKeyboardActionListener listener) {
        mNumberKeyboardView.setOnKeyboardActionListener(listener);
    }

    public NumberKeyboardView getKeyboardView() {
        return mNumberKeyboardView;
    }


    public void setKeyboardType(KeyboardType type) {
        Keyboard keyboard = new Keyboard(getContext(), type == KeyboardType.NORMAL ?
                R.xml.keyboard_number : R.xml.keyboard_dot_number);
        mNumberKeyboardView.setTextSize(type == KeyboardType.NORMAL ? 24 : 18);
        mNumberKeyboardView.setKeyboard(keyboard);
    }

    public enum KeyboardType {
        NORMAL, DOT
    }
    
}
複製程式碼

這裡就是一個簡單的自定義組合控制元件

接著,瞅瞅那個佈局檔案: key_board_container.xml

<?xml version="1.0" encoding="utf-8"?>
<cn.molue.jooyer.numberkeyboard.NumberKeyboardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/number_keyboard_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:background="#d8d3cf"
    android:focusable="true"
    android:focusableInTouchMode="true"
    app:keyBackground="@drawable/key_number_bg"
    app:keyTextColor="#333333"
    app:shadowColor="#ffffff"
    app:shadowRadius="0"
    />
複製程式碼

app: 都是一些自定義的屬性了, 佈局也是非常的簡單

接著看看比較重要的一個東西: KeyboardUtil

public class KeyboardUtil {
    private static final String TAG = KeyboardUtil.class.getSimpleName();

    private KeyboardView mKeyboardView;

    private EditText mEditText;
    private ViewGroup mRootView;
    private Rect mRect = new Rect();

    private KeyboardContainer mKeyboardContainer;
    private FrameLayout.LayoutParams mKeyboardContainerParams;

    private int dp2px(Context context, int def) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, def, context.getResources().getDisplayMetrics());
    }

    public KeyboardUtil(final Activity context, KeyboardContainer.KeyboardType type) {
        mRootView = (ViewGroup) context.getWindow().getDecorView().findViewById(android.R.id.content);
        mKeyboardContainer = new KeyboardContainer(context);
        mKeyboardContainer.setOnKeyboardActionListener(mKeyboardActionListener);
        mKeyboardContainerParams = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.WRAP_CONTENT);
        mKeyboardContainerParams.gravity = Gravity.BOTTOM;
        mKeyboardContainer.setKeyboardType(type);
    }

    @SuppressLint("ClickableViewAccessibility")
    public void bindEditText(EditText editText) {
        mEditText = editText;
        mEditText.setTag(0);
        mEditText.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (0 == ((int) v.getTag())) {
                    if (null != mOnDoneListener) {
                        mOnDoneListener.onTouchEditText(mEditText);
                    }
                    showSoftKeyboard();
                }
                if (mEditText.getText().length() > 0
                        && mEditText.getSelectionStart() !=  mEditText.getText().length()) {
                    mEditText.setSelection(mEditText.getText().length());
                }
                return false;
            }
        });
        mKeyboardContainer.setOnKeyboardActionListener(mKeyboardActionListener);
        hideSystemSoftKeyboard();
    }


    private void showSoftKeyboard() {
        mEditText.setTag(1);
        mRootView.addOnLayoutChangeListener(mOnLayoutChangeListener);

        mKeyboardContainer.setPadding(
                dp2px(mEditText.getContext(), 0),
                dp2px(mEditText.getContext(), -1),
                dp2px(mEditText.getContext(), 0),
                dp2px(mEditText.getContext(), 0));
        if (mRootView.indexOfChild(mKeyboardContainer) == -1) { // 這個思路不錯哦
            if (null != mKeyboardContainer.getParent()) {
                ((ViewGroup) mKeyboardContainer.getParent()).removeView(mKeyboardContainer);
            }
            mRootView.addView(mKeyboardContainer, mRootView.getChildCount(), mKeyboardContainerParams);
        } else {
            mKeyboardContainer.setVisibility(View.VISIBLE);
        }

        mKeyboardContainer.setAnimation(AnimationUtils.loadAnimation(mEditText.getContext(),
                R.anim.anim_bottom_in));
    }

    public void hideSoftKeyboard() {
        if (null != mEditText && -1 != mRootView.indexOfChild(mKeyboardContainer)) {
            mEditText.setTag(0);
            mKeyboardContainer.startAnimation(AnimationUtils.loadAnimation(mEditText.getContext(),
                    R.anim.anim_bottom_out));

            mKeyboardContainer.postDelayed(new Runnable() {
                @Override
                public void run() {
                    mRootView.removeView(mKeyboardContainer);
                }
            }, 400);
        }
    }


    private void hideSystemSoftKeyboard() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            mEditText.setShowSoftInputOnFocus(false);
        } else {
            mEditText.setInputType(InputType.TYPE_NULL);
        }
    }


    private int getKeyCode(Context context, @IntegerRes int redId) {
        return context.getResources().getInteger(redId);
    }


    private final KeyboardView.OnKeyboardActionListener mKeyboardActionListener = new KeyboardView.OnKeyboardActionListener() {
        @Override
        public void onPress(int primaryCode) {
            // 按下 key 時執行
        }

        @Override
        public void onRelease(int primaryCode) {
            // 釋放 key 時執行
        }

        // 點選  key 時執行
        @Override
        public void onKey(int primaryCode, int[] keyCodes) {
            Editable editable = mEditText.getText();
            int start = mEditText.getSelectionStart();
            if (primaryCode == Keyboard.KEYCODE_CANCEL
                    || primaryCode == getKeyCode(mEditText.getContext(), R.integer.hide_keyboard)) {
                hideSoftKeyboard();
                mOnDoneListener.onHide();
            } else if (primaryCode == Keyboard.KEYCODE_DELETE) { // 回退
                if (editable != null && editable.length() > 0) {
                    if (start > 0) {
                        editable.delete(start - 1, start);
                    }
                }
            } else if (primaryCode == getKeyCode(mEditText.getContext(), R.integer.action_done)) { // 確定
                if (null != mOnDoneListener) {
                    mOnDoneListener.onDone(mEditText.getText().toString());
                }
            } else if (primaryCode == getKeyCode(mEditText.getContext(), R.integer.line_feed)) { // 換行
                editable.insert(start, "\n");
            } else { // 輸入鍵盤值
                editable.insert(start, Character.toString((char) primaryCode));
            }
        }

        @Override
        public void onText(CharSequence text) {

        }

        @Override
        public void swipeLeft() {

        }

        @Override
        public void swipeRight() {

        }

        @Override
        public void swipeDown() {

        }

        @Override
        public void swipeUp() {

        }
    };

    private final View.OnLayoutChangeListener mOnLayoutChangeListener = new View.OnLayoutChangeListener() {
        @Override
        public void onLayoutChange(View v, int left, int top, int right, int bottom,
                                   int oldLeft, int oldTop, int oldRight, int oldBottom) {
            int hasMoved = 0;
            Object rootViewTag = mRootView.getTag(R.id.root_view);
            if (rootViewTag != null) {
                hasMoved = (int) rootViewTag;
            }
            if (mKeyboardContainer.getVisibility() == View.GONE) {
                mRootView.removeOnLayoutChangeListener(mOnLayoutChangeListener);
                if (hasMoved > 0) {
                    mRootView.getChildAt(0).scrollBy(0, -1 * hasMoved);
                    mRootView.setTag(R.id.root_view, 0);
                }
            } else {
                mRect.setEmpty();
                mRootView.getWindowVisibleDisplayFrame(mRect);
                int[] etLocation = new int[2];
                mEditText.getLocationOnScreen(etLocation);

                int keyboardTop = etLocation[1] + mEditText.getHeight()
                        + mEditText.getPaddingTop() + mEditText.getPaddingBottom() + 1;   //1px is a divider

                Object anchorTag = mEditText.getTag(R.id.anchor_view);
                View mShowAnchorView = null;
                if (anchorTag != null && anchorTag instanceof View) {
                    mShowAnchorView = (View) anchorTag;
                }
                if (mShowAnchorView != null) {
                    int[] saLocation = new int[2];
                    mShowAnchorView.getLocationOnScreen(saLocation);
                    keyboardTop = saLocation[1] + mShowAnchorView.getHeight() + mShowAnchorView.getPaddingTop() + mShowAnchorView   //1px is a divider
                            .getPaddingBottom() + 1;
                }
                int moveHeight = keyboardTop + mKeyboardContainer.getHeight() - mRect.bottom;
                //height > 0  , rootView 需要繼續上滑
                if (moveHeight > 0) {
                    mRootView.getChildAt(0).scrollBy(0, moveHeight);
                    mRootView.setTag(R.id.root_view, hasMoved + moveHeight);
                } else {
                    int moveBackHeight = Math.min(hasMoved, Math.abs(moveHeight));
                    if (moveBackHeight > 0) {
                        mRootView.getChildAt(0).scrollBy(0, -1 * moveBackHeight);
                        mRootView.setTag(R.id.root_view, hasMoved - moveBackHeight);
                    }
                }

            }
        }
    };

    public KeyboardContainer getKeyboardContainer() {
        return mKeyboardContainer;
    }

    private OnDoneListener mOnDoneListener;

    public void setOnDoneListener(OnDoneListener onDoneListener) {
        mOnDoneListener = onDoneListener;
    }

}
複製程式碼

這裡註釋不多,大家看方法名,大體就明白啥意思了, 主要 ## mOnLayoutChangeListener ## ,當發現輸入框被鍵盤遮擋時,會將輸入框根檢視上移,具體效果,可以打日誌看哈

倒數第二就是看哈回撥了,貼個程式碼,來湊行數....,哈哈

interface OnDoneListener {
	// 當點選確定按鈕時會回撥此方法
    fun onDone(text: String)
    
    // 當 et 被點選後,需要操作可以在此處
    fun onTouchEditText(et: EditText) {
    }
}
複製程式碼

最後就是幾個我就一股腦都丟擲來了,準備接招!!!

  1. 在 res/anim 中建立如下2個動畫

    anim_bottom_in.xml

    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android">
        <translate
            android:duration="400"
            android:fromYDelta="100%p"/>
    </set>
    複製程式碼

    anim_bottom_out.xml

    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android">
        <translate
            android:duration="400"
            android:toYDelta="100%p" />
    </set> 
    複製程式碼
  2. 在 res/drawable 中建立如下幾個 drawable 檔案

    keyboard_number.xml

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android">
        <solid android:color="@android:color/white"/>
    </shape>
    複製程式碼

    keyboard_number_pressed.xml

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android">
        <solid android:color="#b9afa9"/>
    </shape>
    複製程式碼

    key_number_bg.xml

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:state_pressed="true" android:drawable="@drawable/keyboard_number_pressed"/>
        <item android:drawable="@drawable/keyboard_number"/>
    </selector>
    複製程式碼

    key_num_done.xml

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:state_pressed="true" android:drawable="#9d472c"/>
        <item android:drawable="#c35b3a"/>
    </selector>
    複製程式碼
  3. 在 res/values 下建立如下幾個檔案

    keyboard_attrs.xml

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <declare-styleable name="NumberKeyboardView">
            <!--鍵盤背景色 -->
            <attr name="keyBackground" format="color"/>
            <!-- 鍵盤文字顏色 -->
            <attr name="keyTextColor" format="color"/>
            <!-- 陰影顏色 -->
            <attr name="shadowColor" format="color"/>
            <!-- 例如 '完成' 這種文字 -->
            <attr name="labelTextSize" format="dimension"/>
            <!-- 鍵盤文字大小 -->
            <attr name="keyTextSize" format="dimension"/>
            <!-- 鍵盤陰影圓角 -->
            <attr name="shadowRadius" format="float"/>
        </declare-styleable>
    </resources>
    複製程式碼

    keyboard_codes.xml

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <integer name="hide_keyboard">-10</integer>
        <integer name="action_done">-11</integer>
        <integer name="line_feed">-12</integer>
    </resources>
    複製程式碼

    keyboard_ids.xml

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <item type="id" name="root_view"/>
        <item type="id" name="anchor_view" />
    </resources>
    複製程式碼
  4. 在 res/ xml (xml資料夾需要自己建立)建立如下2個檔案

keyboard_dot_number.xml ,多了一個換行和 ','

<?xml version="1.0" encoding="UTF-8"?>
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
          android:horizontalGap="0.1333%p"
          android:keyHeight="49dp"
          android:keyWidth="24.9%p"
          android:verticalGap="1px">
    <Row>
        <Key
            android:codes="49"
            android:keyEdgeFlags="left"
            android:keyLabel="1"/>
        <Key
            android:codes="50"
            android:keyLabel="2"/>
        <Key
            android:codes="51"
            android:keyLabel="3"/>
        <Key
            android:codes="-5"
            android:keyIcon="@mipmap/my_numkb_backspace"
            android:isRepeatable="true"
            />
    </Row>
    <Row>
        <Key
            android:codes="52"
            android:keyEdgeFlags="left"
            android:keyLabel="4"/>
        <Key
            android:codes="53"
            android:keyLabel="5"/>
        <Key
            android:codes="54"
            android:keyLabel="6"/>
        <Key
            android:codes="44"
            android:keyLabel=","/>
    </Row>
    <Row android:horizontalGap="1px">
        <Key
            android:codes="55"
            android:keyEdgeFlags="left"
            android:keyLabel="7"/>
        <Key
            android:codes="56"
            android:keyLabel="8"/>
        <Key
            android:codes="57"
            android:keyLabel="9"/>
        <Key
            android:codes="43"
            android:keyLabel="+"/>
    </Row>
    <Row android:horizontalGap="1px">
        <Key
            android:codes="@integer/hide_keyboard"
            android:keyIcon="@mipmap/my_numkb_hide"
            android:keyEdgeFlags="left"/>
        <Key
            android:codes="48"
            android:keyLabel="0"/>
        <Key
            android:codes="@integer/line_feed"
            android:keyLabel="換行"/>

        <Key
            android:codes="@integer/action_done"
            android:iconPreview="@drawable/key_num_done"
            android:keyLabel="確定"/>
    </Row>
</Keyboard>
複製程式碼

keyboard_number.xml

<?xml version="1.0" encoding="UTF-8"?>
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
          android:horizontalGap="0.1333%p"
          android:keyHeight="49dp"
          android:keyWidth="24.9%p"
          android:verticalGap="1px">
    <Row>
        <Key
            android:codes="49"
            android:keyEdgeFlags="left"
            android:keyLabel="1"/>
        <Key
            android:codes="50"
            android:keyLabel="2"/>
        <Key
            android:codes="51"
            android:keyLabel="3"/>
        <Key
            android:codes="-5"
            android:keyIcon="@mipmap/my_numkb_backspace"
            android:isRepeatable="true"
            android:keyHeight="99dp"
            />
    </Row>
    <Row>
        <Key
            android:codes="52"
            android:keyEdgeFlags="left"
            android:keyLabel="4"/>
        <Key
            android:codes="53"
            android:keyLabel="5"/>
        <Key
            android:codes="54"
            android:keyLabel="6"/>
    </Row>
    <Row android:horizontalGap="1px">
        <Key
            android:codes="55"
            android:keyEdgeFlags="left"
            android:keyLabel="7"/>
        <Key
            android:codes="56"
            android:keyLabel="8"/>
        <Key
            android:codes="57"
            android:keyLabel="9"/>
        <Key
            android:codes="@integer/action_done"
            android:iconPreview="@drawable/key_num_done"
            android:keyHeight="99dp"
            android:keyLabel="確定"/>
    </Row>
    <Row android:horizontalGap="1px">
        <Key
            android:codes="@integer/hide_keyboard"
            android:keyIcon="@mipmap/my_numkb_hide"
            android:keyEdgeFlags="left"/>
        <Key
            android:codes="48"
            android:keyLabel="0"
            android:keyWidth="49.9%p"/>
    </Row>
</Keyboard>
複製程式碼

這樣一個簡單易用的鍵盤就完成了,可以根據需要自己定製.

下面看看基本用法

// KeyboardType 一般型別是沒有逗號的,另一種有逗號
val keyboardUtil = KeyboardUtil(this,
        KeyboardContainer.KeyboardType.NORMAL);
keyboardUtil.bindEditText(et_test) // 繫結一個 EditText 
keyboardUtil.setOnDoneListener(object : OnDoneListener {
    override fun onDone(text: String) { // 按鍵盤確認鍵回撥此方法
        Log.i("TEST", "------------->$text ")
    }
    /**
     *  這裡當 觸控了 EditText 會回撥這,
     *  如果不需要此回撥,可不用重寫
     */
    override fun onTouchEditText(et: EditText) {
    }
})
複製程式碼

使用就是這麼簡單, 如果有疑問請下方留言噢!

膜拜的大神:

  1. https://juejin.im/post/5ae0ff7ff265da0b9671e835 ,此處有詳細系統API解釋,我就沒有在文章中多講
  2. https://www.jianshu.com/p/b1973de976e4 , 效果和此大神類似,部分方法等也直接使用大神之作

相關文章