欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android 仿微信數(shù)字鍵盤

 更新時(shí)間:2021年05月31日 10:42:23   作者:不會(huì)飛的小豬  
大部分的金融App會(huì)對(duì)默認(rèn)的數(shù)字鍵盤進(jìn)行處理,以實(shí)現(xiàn)自定義的數(shù)字安全鍵盤?;诖?,本文對(duì)對(duì)微信數(shù)字鍵盤樣式進(jìn)行了仿寫,實(shí)現(xiàn)了一套自定義的數(shù)字安全鍵盤(支持隨機(jī)數(shù)字分布)。

一、圖示效果

二、需要考慮的問題

布局的實(shí)現(xiàn)方式;
demo中使用了popupwindow,通過xml文件進(jìn)行Tablayout布局。

禁掉EditText默認(rèn)軟鍵盤的彈出,替換為自定義的數(shù)字鍵盤及與其它EditText切換焦點(diǎn)時(shí)的彈出效果;

刪除和增加字符時(shí)需要同步更新光標(biāo)的位置;

隨機(jī)數(shù)字分布的實(shí)現(xiàn);

三、實(shí)現(xiàn)代碼

1.MainActivity調(diào)用處代碼:

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";
    private EditText numberEt;
    private KeyboardPopupWindow keyboardPopupWindow;
    private boolean isUiCreated = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
    }

    private void initView() {
        numberEt = findViewById(R.id.numberEt);
        keyboardPopupWindow = new KeyboardPopupWindow(MainActivity.this, getWindow().getDecorView(), numberEt,true);
//        numberEt.setInputType(InputType.TYPE_NULL);//該設(shè)置會(huì)導(dǎo)致光標(biāo)不可見
        numberEt.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (keyboardPopupWindow != null) {
                    keyboardPopupWindow.show();
                }
            }
        });
        numberEt.setOnFocusChangeListener(new View.OnFocusChangeListener() {
            @Override
            public void onFocusChange(View v, boolean hasFocus) {
                if (keyboardPopupWindow != null && isUiCreated) {//isUiCreated 很重要,Unable to add window -- token null is not valid; is your activity running?
                    keyboardPopupWindow.refreshKeyboardOutSideTouchable(!hasFocus);// 需要等待頁(yè)面創(chuàng)建完成后焦點(diǎn)變化才去顯示自定義鍵盤
                }

                if (hasFocus) {//隱藏系統(tǒng)軟鍵盤
                    InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                    imm.hideSoftInputFromWindow(numberEt.getWindowToken(), 0);
                }

            }
        });
    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        isUiCreated = true;
    }


    @Override
    protected void onDestroy() {
        if (keyboardPopupWindow != null) {
            keyboardPopupWindow.releaseResources();
        }
        super.onDestroy();
    }
}

可以看到,這塊的代碼實(shí)現(xiàn)很簡(jiǎn)單,主要是通過KeyboardPopupWindow 這個(gè)自定義的View來實(shí)現(xiàn)鍵盤彈出及按鍵點(diǎn)擊效果。需要注意的是isUiCreated 這個(gè)標(biāo)志位,需要通過onWindowFocusChanged等方法來確定當(dāng)前頁(yè)面加載完畢后去刷新自定義鍵盤的狀態(tài),否則會(huì)報(bào)錯(cuò)。

2.自定義數(shù)字鍵盤的代碼:

public class KeyboardPopupWindow extends PopupWindow {
    private static final String TAG = "KeyboardPopupWindow";
    private Context context;
    private View anchorView;
    private View parentView;
    private EditText editText;
    private boolean isRandomSort = false;//數(shù)字是否隨機(jī)排序
    private List<Integer> list = new ArrayList<>();
    private int[] commonButtonIds = new int[]{R.id.button00, R.id.button01, R.id.button02, R.id.button03,
            R.id.button04, R.id.button05, R.id.button06, R.id.button07, R.id.button08, R.id.button09};

    /**
     * @param context
     * @param anchorView
     * @param editText
     * @param isRandomSort 數(shù)字是否隨機(jī)排序
     */
    public KeyboardPopupWindow(Context context, View anchorView, EditText editText, boolean isRandomSort) {
        this.context = context;
        this.anchorView = anchorView;
        this.editText = editText;
        this.isRandomSort = isRandomSort;
        if (context == null || anchorView == null) {
            return;
        }
        initConfig();
        initView();
    }


    private void initConfig() {
        setOutsideTouchable(false);
        setFocusable(false);
        setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
        forbidDefaultSoftKeyboard();
    }

    /**
     * 禁止系統(tǒng)默認(rèn)的軟鍵盤彈出
     */
    private void forbidDefaultSoftKeyboard() {
        if (editText == null) {
            return;
        }
        if (android.os.Build.VERSION.SDK_INT > 10) {//4.0以上,使用反射的方式禁止系統(tǒng)自帶的軟鍵盤彈出
            try {
                Class<EditText> cls = EditText.class;
                Method setShowSoftInputOnFocus;
                setShowSoftInputOnFocus = cls.getMethod("setShowSoftInputOnFocus", boolean.class);
                setShowSoftInputOnFocus.setAccessible(true);
                setShowSoftInputOnFocus.invoke(editText, false);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 刷新自定義的popupwindow是否outside可觸摸反應(yīng):如果是不可觸摸的,則顯示該軟鍵盤view
     *
     * @param isTouchable
     */
    public void refreshKeyboardOutSideTouchable(boolean isTouchable) {
        setOutsideTouchable(isTouchable);
        if (!isTouchable) {
            show();
        } else {
            dismiss();
        }
    }

    private void initView() {
        parentView = LayoutInflater.from(context).inflate(R.layout.keyboadview, null);
        initKeyboardView(parentView);
        setWidth(ViewGroup.LayoutParams.MATCH_PARENT);
        setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
        setContentView(parentView);
    }

    private void initKeyboardView(View view) {
        LinearLayout dropdownLl = view.findViewById(R.id.dropdownLl);
        dropdownLl.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dismiss();
            }
        });

        //①給數(shù)字鍵設(shè)置點(diǎn)擊監(jiān)聽
        for (int i = 0; i < commonButtonIds.length; i++) {
            final Button button = view.findViewById(commonButtonIds[i]);
            button.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    int curSelection = editText.getSelectionStart();
                    int length = editText.getText().toString().length();
                    if (curSelection < length) {
                        String content = editText.getText().toString();
                        editText.setText(content.substring(0, curSelection) + button.getText() + content.subSequence(curSelection, length));
                        editText.setSelection(curSelection + 1);
                    } else {
                        editText.setText(editText.getText().toString() + button.getText());
                        editText.setSelection(editText.getText().toString().length());
                    }
                }
            });
        }

        //②給小數(shù)點(diǎn)按鍵設(shè)置點(diǎn)擊監(jiān)聽
        view.findViewById(R.id.buttonDot).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int curSelection = editText.getSelectionStart();
                int length = editText.getText().toString().length();
                if (curSelection < length) {
                    String content = editText.getText().toString();
                    editText.setText(content.substring(0, curSelection) + "." + content.subSequence(curSelection, length));
                    editText.setSelection(curSelection + 1);
                } else {
                    editText.setText(editText.getText().toString() + ".");
                    editText.setSelection(editText.getText().toString().length());
                }
            }
        });

        //③給叉按鍵設(shè)置點(diǎn)擊監(jiān)聽
        view.findViewById(R.id.buttonCross).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int length = editText.getText().toString().length();
                int curSelection = editText.getSelectionStart();
                if (length > 0 && curSelection > 0 && curSelection <= length) {
                    String content = editText.getText().toString();
                    editText.setText(content.substring(0, curSelection - 1) + content.subSequence(curSelection, length));
                    editText.setSelection(curSelection - 1);
                }
            }
        });
    }


    public void show() {
        if (!isShowing() && anchorView != null) {
            doRandomSortOp();
            this.showAtLocation(anchorView, Gravity.BOTTOM, 0, 0);
        }
    }

    /**
     * 隨機(jī)分布數(shù)字
     */
    private void doRandomSortOp() {
        if (parentView == null) {
            return;
        }
        if (!isRandomSort) {
            for (int i = 0; i < commonButtonIds.length; i++) {
                final Button button = parentView.findViewById(commonButtonIds[i]);
                button.setText("" + i);
            }
        } else {
            list.clear();
            Random ran = new Random();
            while (list.size() < commonButtonIds.length) {
                int n = ran.nextInt(commonButtonIds.length);
                if (!list.contains(n))
                    list.add(n);
            }
            for (int i = 0; i < commonButtonIds.length; i++) {
                final Button button = parentView.findViewById(commonButtonIds[i]);
                button.setText("" + list.get(i));
            }
        }
    }

    public void releaseResources() {
        this.dismiss();
        context = null;
        anchorView = null;
        if (list != null) {
            list.clear();
            list = null;
        }
    }  
}

代碼實(shí)現(xiàn)的邏輯相對(duì)簡(jiǎn)單:

  1. 通過給popupwindow設(shè)置contentView、彈出位置、邊界外觸摸參數(shù)等數(shù)值,實(shí)現(xiàn)大體樣式上的效果;
  2. 給contentView中的每個(gè)button設(shè)置點(diǎn)擊事件,并處理傳遞的EditText數(shù)值及焦點(diǎn)變化情況;
  3. 設(shè)置隨機(jī)標(biāo)志位,進(jìn)行數(shù)值鍵盤數(shù)值隨機(jī)的分布;
  4. forbidDefaultSoftKeyboard中處理:禁止EditText默認(rèn)的軟鍵盤彈出。因?yàn)橐獙?shí)現(xiàn)EditText焦點(diǎn)仍舊可見的效果,目前試過的其它集中方式仍有較大的缺陷,所以是通過反射的方法來達(dá)到目的。

四.小結(jié)

當(dāng)然,除了以上方式,還可以使用系統(tǒng)的KeyboardView和Keyboard來實(shí)現(xiàn)相應(yīng)的效果。

在仿寫的過程中會(huì)發(fā)現(xiàn),實(shí)現(xiàn)這一效果會(huì)涉及到一些體驗(yàn)性的細(xì)節(jié)點(diǎn),而微信正是做到了這一點(diǎn),所以在使用層面上會(huì)很方便。有些細(xì)節(jié)點(diǎn)會(huì)可能會(huì)比實(shí)現(xiàn)整個(gè)大致效果更為麻煩,但有時(shí)候恰巧這些很容易被忽視的小九九是與眾不同的地方。

源碼地址:

https://github.com/ganshenml/KeyboardPopupWindow

到這里就結(jié)束啦。

以上就是Android仿微信數(shù)字鍵盤的詳細(xì)內(nèi)容,更多關(guān)于Android 數(shù)字鍵盤的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Android滾動(dòng)條廣告實(shí)現(xiàn)代碼示例

    Android滾動(dòng)條廣告實(shí)現(xiàn)代碼示例

    本篇文章主要介紹了Android滾動(dòng)條廣告實(shí)現(xiàn)代碼示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-09-09
  • android實(shí)現(xiàn)年齡段選擇器

    android實(shí)現(xiàn)年齡段選擇器

    這篇文章主要為大家詳細(xì)介紹了android實(shí)現(xiàn)年齡段選擇器,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-11-11
  • Android-Jetpack-Navigation組件使用示例

    Android-Jetpack-Navigation組件使用示例

    這篇文章主要介紹了Android-Jetpack-Navigation組件使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08
  • Android金額輸入框只允許輸入小數(shù)點(diǎn)后兩位效果

    Android金額輸入框只允許輸入小數(shù)點(diǎn)后兩位效果

    實(shí)現(xiàn)android 金額輸入框輸入小數(shù)點(diǎn)后兩位的效果也不是很復(fù)雜,只需要設(shè)置輸入框輸入的字符類型、設(shè)置InputFilter、設(shè)置輸入變化監(jiān)聽即可。這篇文章主要介紹了Android金額輸入框只允許輸入小數(shù)點(diǎn)后兩位 ,需要的朋友可以參考下
    2017-05-05
  • Flutter在項(xiàng)目中使用動(dòng)畫不使用包實(shí)現(xiàn)詳解

    Flutter在項(xiàng)目中使用動(dòng)畫不使用包實(shí)現(xiàn)詳解

    這篇文章主要為大家介紹了Flutter在項(xiàng)目中使用動(dòng)畫不使用包實(shí)現(xiàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • Android開發(fā)之SQLite的使用方法

    Android開發(fā)之SQLite的使用方法

    本篇文章介紹了,Android開發(fā)之SQLite的使用方法。需要的朋友參考下
    2013-04-04
  • 教你安裝配置Android Studio

    教你安裝配置Android Studio

    對(duì)于Android Studio相信大家都不陌生了,作為谷歌推出的安卓開發(fā)工具,做過java的同學(xué)應(yīng)該都了解,下面我們就簡(jiǎn)單介紹下這款工具的安裝預(yù)配置
    2015-12-12
  • Android WebView基礎(chǔ)應(yīng)用詳解

    Android WebView基礎(chǔ)應(yīng)用詳解

    這篇文章主要為大家介紹了Android中WebView這一控件的基礎(chǔ)應(yīng)用,例如:播放音樂,播放視頻等,文中的示例代碼講解詳細(xì),對(duì)于我們了解WebView很有幫助,需要的同學(xué)可以學(xué)習(xí)一下
    2021-12-12
  • Android三種網(wǎng)絡(luò)通訊方式及Android的網(wǎng)絡(luò)通訊機(jī)制

    Android三種網(wǎng)絡(luò)通訊方式及Android的網(wǎng)絡(luò)通訊機(jī)制

    在android平臺(tái)目前提供了三種網(wǎng)絡(luò)接口可以使用:分別是java.net.*(標(biāo)準(zhǔn)Java接口)、Org.apache接口和Android.net.*(Android網(wǎng)絡(luò)接口),本文主要給大家介紹android三種網(wǎng)絡(luò)通訊方式及android的網(wǎng)絡(luò)通訊機(jī)制,小伙伴們一起學(xué)習(xí)吧
    2015-11-11
  • Android實(shí)現(xiàn)高亮搜索功能的示例

    Android實(shí)現(xiàn)高亮搜索功能的示例

    這篇文章主要介紹了Android實(shí)現(xiàn)高亮搜索功能的示例,幫助大家更好的理解和學(xué)習(xí)使用Android開發(fā),感興趣的朋友可以了解下
    2021-05-05

最新評(píng)論