类支付宝密码输入框NumberEditText(简单粗暴的定制方式)

        因为项目需要,设计了一个下图样的验证码输入框(ps:个人认为还不如直接一个EditText,用户友好度可能更好,何况这页面99.9%的用户不会使用,但是没办法,别人才是专业的设计师)。

NumberEditText_smscode

        其实界面很简单,一个弹出框口,中间几个简单控件。也就验证码输入框需要自定义一下。首先看到,觉得继承个EditText或者View绘制下,然后监听下输入框情况就可以了。但是,本人比较懒,能用系统提供方法实现的话就尽量少去搞自定义。然后就变成了六个EditText接收值,但是如果每个EditText都搞监听,太浪费资源了,性能开销太大,输入也不流畅。之后,换下思维, 用了个十分粗暴但简单实用的方式:六个TextView+一个不可见EditText。

        大概思路,六个带边框的TextView, 然后一个完全透明的EditText覆盖在六个TextView上用来接收键盘的输入(这样的好处事,不用自己处理键盘事件,也因此少了键盘带来的各种兼容性问题)。然后给EditText加一个监听,将接收到的收入值复制给每个TextView。

View view = LayoutInflater.from(context).inflate(R.layout.e7yoo_number_edittext, null);
inputTv[0] = (TextView) view.findViewById(R.id.e7yoo_number_edittext_tv0);
inputTv[1] = (TextView) view.findViewById(R.id.e7yoo_number_edittext_tv1);
inputTv[2] = (TextView) view.findViewById(R.id.e7yoo_number_edittext_tv2);
inputTv[3] = (TextView) view.findViewById(R.id.e7yoo_number_edittext_tv3);
inputTv[4] = (TextView) view.findViewById(R.id.e7yoo_number_edittext_tv4);
inputTv[5] = (TextView) view.findViewById(R.id.e7yoo_number_edittext_tv5);
invisibleEt = (EditText) view.findViewById(R.id.e7yoo_number_edittext_et);
invisibleEt.addTextChangedListener(new InvisibleEtTextWatcher());
addView(view);

在TextWatcher的afterTextChanged(Editable s)中

for(int i = 0; i < tvLength; i++) {
    if(i < length) {
        inputTv[i].setText("" + chars[i]);
    } else {
        inputTv[i].setText("");
    }
}
if(length == tvLength && onInputFinishListener != null) {
    onInputFinishListener.onInputFinish(text);
}

另外提供清除方法

public void clearText() {
    int tvLength = inputTv.length;
    for (int i = 0; i < tvLength; i++) {
        inputTv[i].setText("");
    }
    invisibleEt.setText("");
}

和输入完成回调

public void setOnInputFinish(OnInputFinishListener listener) {
    this.onInputFinishListener = listener;
}
public interface OnInputFinishListener {
    void onInputFinish(String text);
}

使用很简单

<com.e7yoo.numberedittext.NumberEditText
    android:id="@+id/numberEt"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

然后在Java代码中

numberEditText = (NumberEditText) findViewById(R.id.numberEt);
numberEditText.setOnInputFinish(new NumberEditText.OnInputFinishListener() {
    @Override
    public void onInputFinish(String text) {
        // 展示输入结果
        resultTv.setText("上次输入为:" + text);
        // 清空输入框
        numberEditText.clearText();
    }
});

        这样做可以算是很简单粗暴的方式了,而且在UI发生变化时,也方便做一些调整。当然比较高级的Android玩家可能更喜欢去做一些标准的自定义控件,但我更推崇的是,在性能差别不大的情况下,使用最简单最快捷的方式去处理问题。

        源码地址:http://git.oschina.net/thinkin/NumberEditText

转自我的oschina

posted @ 2017-11-30 13:29  IT老五  阅读(676)  评论(0编辑  收藏  举报