自定义Android Dialog EditText 密码输入框

时间:2024-03-22 19:58:21
在一些需要输入支付密码的需求中,如微信支付的黑圆点。

自定义Android Dialog EditText 密码输入框

开始也是一直在想着怎么自定义EditText去做,确实网上已经有自定义view的实现。之前也是参考别人写的,并修改了部分后用于项目中,大家可以搜下“PasswordInputView”,好多作者实现了,大家的思路都差不多。不知道参考哪位作者的了,因为自己改了部分参数跟方法,修改了颜色,找不到对比踪迹了。
但是测试发现自定义的那个View第一个输入框总比其的5个大点点,要仔细看,然后密码输入框的线也有点粗细不一,边角跟设计图也不一致,测试就提bug单了。

后面想着怎么优化来着,继续在那个类上改来改去,边角上总有点跟设计图不一致,产品就没通过了。基础差,没办法。
停顿下,去厕所蹲下大便思考下......过不久,只听脑子里一个微波炉的声音响起:“叮”的一声,有思路了!

做一个假象!
就是:EditText文本输入透明、文字透明,然后盖在一个View上面,然后监控这个EditText的 afterTextChanged 处理EditText 下面的那个View相关的显示逻辑。

开干。

1、布局文件:dialog_pay.xml

Code Text:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical"
    android:padding="15dp">

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/bg_white_rect_circle_border"
        android:orientation="vertical">

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center_vertical"
            android:padding="8dp">

            <ImageView
                android:id="@+id/dialog_close"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentRight="true"
                android:layout_marginLeft="-8dp"
                android:padding="15dp"
                android:src="@mipmap/ic_dialog_close"
                android:visibility="visible" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true"
                android:text="请输入支付密码"
                android:textColor="@color/gray_general_lable"
                android:textSize="@dimen/text_size_l" />

        </RelativeLayout>

        <View
            android:layout_width="match_parent"
            android:layout_height="0.5dp"
            android:background="@color/divider_color" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="20dp"
            android:layout_marginRight="20dp"
            android:layout_marginTop="16dp"
            android:gravity="center_horizontal"
            android:text="支付金额"
            android:textColor="@color/gray_general_title"
            android:textSize="@dimen/text_size_m" />

        <TextView
            android:id="@+id/dialog_money"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="20dp"
            android:layout_marginRight="20dp"
            android:gravity="center_horizontal"
            android:text="0"
            android:textColor="@color/black_general_title"
            android:textSize="22sp" />

        <FrameLayout
            android:id="@+id/fragment_password"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="40dp"
                android:layout_margin="15dp"
                android:gravity="center"
                android:orientation="horizontal">

                <ImageView
                    android:id="@+id/et_pwd_1"
                    style="@style/EditTextPasswordStyle" />

                <ImageView
                    android:id="@+id/et_pwd_2"
                    style="@style/EditTextPasswordStyle"
                    android:layout_marginLeft="10dp" />

                <ImageView
                    android:id="@+id/et_pwd_3"
                    style="@style/EditTextPasswordStyle"
                    android:layout_marginLeft="10dp" />

                <ImageView
                    android:id="@+id/et_pwd_4"
                    style="@style/EditTextPasswordStyle"
                    android:layout_marginLeft="10dp" />

                <ImageView
                    android:id="@+id/et_pwd_5"
                    style="@style/EditTextPasswordStyle"
                    android:layout_marginLeft="10dp" />

                <ImageView
                    android:id="@+id/et_pwd_6"
                    style="@style/EditTextPasswordStyle"
                    android:layout_marginLeft="10dp" />
            </LinearLayout>

            <EditText
                android:id="@+id/et_pwd_real"
                android:layout_width="match_parent"
                android:layout_height="40dp"
                android:layout_margin="15dp"
                android:background="@color/color_transparent"
                android:cursorVisible="false"
                android:inputType="numberPassword"
                android:maxLength="6"
                android:maxLines="1"
                android:textColor="@color/color_transparent" />

        </FrameLayout>

    </LinearLayout>
</LinearLayout>

Code Design:
自定义Android Dialog EditText 密码输入框


2、自定义Dialog:PayDialog.java

public class PayDialog extends Dialog implements View.OnClickListener {

    private TextView mDialogMoney;

    private EditText mEtPwdReal;
    private ImageView mEt1, mEt2, mEt3, mEt4, mEt5, mEt6;

    public interface PasswordCallback {
        void callback(String password);
    }

    public PasswordCallback mPasswordCallback;

    public PayDialog(Context context) {
        super(context, R.style.PasswordDialog);
        initDilaog();
    }

    void initDilaog() {
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.dialog_pay);
        setCancelable(false);
        setCanceledOnTouchOutside(false);

        findViewById(R.id.dialog_close).setOnClickListener(this);

        mDialogMoney = (TextView) findViewById(R.id.dialog_money);

        mEtPwdReal = (EditText) findViewById(R.id.et_pwd_real);
        mEtPwdReal.addTextChangedListener(new PasswordEditChangedListener(mEtPwdReal));

        mEt1 = (ImageView) findViewById(R.id.et_pwd_1);
        mEt2 = (ImageView) findViewById(R.id.et_pwd_2);
        mEt3 = (ImageView) findViewById(R.id.et_pwd_3);
        mEt4 = (ImageView) findViewById(R.id.et_pwd_4);
        mEt5 = (ImageView) findViewById(R.id.et_pwd_5);
        mEt6 = (ImageView) findViewById(R.id.et_pwd_6);
    }

    private void requestFocus() {
        mEtPwdReal.requestFocus();
        this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
    }

    /**
     * 重制
     */
    public void clearPasswordText() {
        mEtPwdReal.setText("");
        requestFocus();
    }

    /**
     * 设置金额
     *
     * @param money
     */
    public void setMoney(int money) {
        mDialogMoney.setText("¥" + money + ".00");
    }

    /**
     * 设置回调
     *
     * @param passwordCallback
     */
    public void setPasswordCallback(PasswordCallback passwordCallback) {
        this.mPasswordCallback = passwordCallback;
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.dialog_close:
                dismiss();
                break;
        }
    }

    private class PasswordEditChangedListener implements TextWatcher {

        private EditText mEditText;

        public PasswordEditChangedListener(EditText editText) {
            this.mEditText = editText;
        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {

        }

        @Override
        public void afterTextChanged(Editable s) {
            String ret = s.toString().trim();
            if (mEditText.getId() == R.id.et_pwd_real) {
                char[] array = ret.toCharArray();
                for (int i = 0; i < array.length; i++) {
                    //设置图片为黑色圆点
                    if (i == 0) {
                        mEt1.setImageResource(R.mipmap.icon_pwd);
                    } else if (i == 1) {
                        mEt2.setImageResource(R.mipmap.icon_pwd);
                    } else if (i == 2) {
                        mEt3.setImageResource(R.mipmap.icon_pwd);
                    } else if (i == 3) {
                        mEt4.setImageResource(R.mipmap.icon_pwd);
                    } else if (i == 4) {
                        mEt5.setImageResource(R.mipmap.icon_pwd);
                    } else if (i == 5) {
                        mEt6.setImageResource(R.mipmap.icon_pwd);
                    }
                }
                clearTextView(array.length, mEt1, mEt2, mEt3, mEt4, mEt5, mEt6);
                //自动提交
                if (array.length == 6) {
                    if (mPasswordCallback != null)
                        mPasswordCallback.callback(String.valueOf(array));
                }
            }
        }

        /**
         * 按删除键后,删除的值对应的图标还原
         *
         * @param length
         * @param editTexts
         */
        void clearTextView(int length, ImageView... editTexts) {
            for (int i = 0; i < 6; i++) {
                //比如当前密码长度为4位,当大于4的图标,就要还原成未输入情况
                if (i > length - 1) {
                    editTexts[i].setImageResource(0);
                }
            }
        }
    }
}



3、调用Dialog:MainActivity.java
public class MainActivity extends Activity {

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

        findViewById(R.id.btn_pay).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                createPayDialog();
            }
        });
    }

    void createPayDialog() {
        final PayDialog payDialog = new PayDialog(this);
        payDialog.setMoney(520);
        payDialog.setPasswordCallback(new PayDialog.PasswordCallback() {
            @Override
            public void callback(String password) {
                if ("000000".equals(password)) {
                    payDialog.clearPasswordText();
                    Toast.makeText(MainActivity.this, "密码为错误,请重试", Toast.LENGTH_SHORT).show();

                } else {
                    Toast.makeText(MainActivity.this, "密码为:" + password, Toast.LENGTH_SHORT).show();
                    payDialog.dismiss();
                }
            }
        });
        payDialog.clearPasswordText();
        payDialog.show();
    }
}

4、运行效果图:

自定义Android Dialog EditText 密码输入框


资源地址:http://download.csdn.net/download/liang_fei_xp/9969719