验证码输入框

   我先贴出图:

   

  这是我从一篇博客里面的demo里面抠出来的,然后使用起来比较方便:

public class SecurityCodeView extends RelativeLayout {

    private LinearLayout containerEt;

    private EditText et;
    // 输入框数量
    private int mEtNumber;
    // 输入框的宽度
    private int mEtWidth;
    //输入框分割线
    private Drawable mEtDividerDrawable;
    //输入框文字颜色
    private int mEtTextColor;
    //输入框文字大小
    private float mEtTextSize;
    //输入框获取焦点时背景
    private Drawable mEtBackgroundDrawableFocus;
    // 输入框没有焦点时背景
    private Drawable mEtBackgroundDrawableNormal;

    //存储TextView的数据 数量由自定义控件的属性传入
    private TextView[] mTextViews;


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

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

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

    //初始化 布局和属性
    private void init(Context context, AttributeSet attrs, int defStyleAttr) {
        LayoutInflater.from(context).inflate(R.layout.layout_identifying_code, this);
        containerEt = (LinearLayout) this.findViewById(R.id.container_et);
        et = (EditText) this.findViewById(R.id.et);

        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.SecurityCodeView, defStyleAttr, 0);
        mEtNumber = typedArray.getInteger(R.styleable.SecurityCodeView_icv_et_number, 1);
        mEtWidth = typedArray.getDimensionPixelSize(R.styleable.SecurityCodeView_icv_et_width, 42);
        mEtDividerDrawable = typedArray.getDrawable(R.styleable.SecurityCodeView_icv_et_divider_drawable);
        mEtTextSize = typedArray.getDimensionPixelSize(R.styleable.SecurityCodeView_icv_et_text_size, 16);
        mEtTextColor = typedArray.getColor(R.styleable.SecurityCodeView_icv_et_text_color, Color.WHITE);
        mEtBackgroundDrawableFocus = typedArray.getDrawable(R.styleable.SecurityCodeView_icv_et_bg_focus);
        mEtBackgroundDrawableNormal = typedArray.getDrawable(R.styleable.SecurityCodeView_icv_et_bg_normal);
        //释放资源
        typedArray.recycle();
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        initTextViews(getContext(), mEtNumber, mEtWidth, mEtDividerDrawable, mEtTextSize, mEtTextColor);
        initEtContainer(mTextViews);
        setListener();
    }


    //初始化TextView
    private void initTextViews(Context context, int etNumber, int etWidth, Drawable etDividerDrawable, float etTextSize, int etTextColor) {
        // 设置 editText 的输入长度
        et.setCursorVisible(false);//将光标隐藏
        et.setFilters(new InputFilter[]{new InputFilter.LengthFilter(etNumber)}); //最大输入长度
        // 设置分割线的宽度
        if (etDividerDrawable != null) {
            etDividerDrawable.setBounds(0, 0, etDividerDrawable.getMinimumWidth(), etDividerDrawable.getMinimumHeight());
            containerEt.setDividerDrawable(etDividerDrawable);
        }
        mTextViews = new TextView[etNumber];
        for (int i = 0; i < mTextViews.length; i++) {
            TextView textView = new EditText(context);
            textView.setTextSize(etTextSize);
            textView.setTextColor(etTextColor);
            textView.setWidth(etWidth);
            textView.setHeight(etWidth);
            if (i == 0) {
                textView.setBackground(mEtBackgroundDrawableFocus);
//                textView.setBackgroundDrawable(mEtBackgroundDrawableFocus);
            } else {
                textView.setBackground(mEtBackgroundDrawableNormal);
//                textView.setBackgroundDrawable(mEtBackgroundDrawableNormal);
            }
            textView.setGravity(Gravity.CENTER);

            textView.setFocusable(false);

            mTextViews[i] = textView;
        }
    }

    //初始化存储TextView 的容器
    private void initEtContainer(TextView[] mTextViews) {
        for (int i = 0; i < mTextViews.length; i++) {
            containerEt.addView(mTextViews[i]);
        }
    }


    private void setListener() {
        // 监听输入内容
        et.addTextChangedListener(new TextWatcher() {

            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
            }

            @Override
            public void afterTextChanged(Editable editable) {
                //这个afterTextChanged只会在新增的时候被调
                String inputStr = editable.toString();
                if (inputStr != null && !inputStr.equals("")) {
                    setText(inputStr);
                    et.setText("");
                }
            }
        });

        // 监听删除按键
        et.setOnKeyListener(new OnKeyListener() {
            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                if (keyCode == KeyEvent.KEYCODE_DEL && event.getAction() == KeyEvent.ACTION_DOWN) {
                    onKeyDelete();
                    return true;
                }
                return false;
            }
        });
    }


    // 给TextView 设置文字
    public void setText(String inputContent) {
        Log.i("cy==View", inputContent);
        for (int i = 0; i < mTextViews.length; i++) {
            TextView tv = mTextViews[i];
            if (tv.getText().toString().trim().equals("")) {
                tv.setText(inputContent);
                // 添加输入完成的监听
                if (inputCompleteListener != null) {
                    inputCompleteListener.inputComplete();
                }
                tv.setBackground(mEtBackgroundDrawableNormal);
                if (i < mEtNumber - 1) {
                    mTextViews[i + 1].setBackground(mEtBackgroundDrawableFocus);
                }
                break;
            }
        }
    }

    // 监听删除
    public void onKeyDelete() {
        for (int i = mTextViews.length - 1; i >= 0; i--) {
            TextView tv = mTextViews[i];
            if (!tv.getText().toString().trim().equals("")) {
                tv.setText("");
                // 添加删除完成监听
                if (inputCompleteListener != null) {
                    inputCompleteListener.deleteContent();
                }
                tv.setBackground(mEtBackgroundDrawableFocus);
                if (i < mEtNumber - 1) {
                    mTextViews[i + 1].setBackground(mEtBackgroundDrawableNormal);
                }
                break;
            }
        }
    }


    /**
     * 获取输入文本
     *
     * @return
     */
    public String getTextContent() {
        StringBuffer buffer = new StringBuffer();
        for (TextView tv : mTextViews) {
            buffer.append(tv.getText().toString().trim());
        }
        return buffer.toString();
    }

    /**
     * 删除所有内容
     */
    public void clearAllText() {
        for (int i = 0; i < mTextViews.length; i++) {
            if (i == 0) {
                mTextViews[i].setBackgroundDrawable(mEtBackgroundDrawableFocus);
            } else {
                mTextViews[i].setBackgroundDrawable(mEtBackgroundDrawableNormal);
            }
            mTextViews[i].setText("");
        }
    }


    /**
     * 获取输入的位数
     *
     * @return
     */
    public int getTextCount() {
        return mEtNumber;
    }

    // 输入完成 和 删除成功 的监听
    private InputCompleteListener inputCompleteListener;

    public void setInputCompleteListener(InputCompleteListener inputCompleteListener) {
        this.inputCompleteListener = inputCompleteListener;
    }

    public interface InputCompleteListener {
        void inputComplete();

        void deleteContent();
    }


}


在xml中使用:


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

    <********SecurityCodeView
        android:id="@+id/icv"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:layout_centerHorizontal="true"
        android:layout_marginLeft="10dp"
        android:layout_marginRight="10dp"
        android:layout_marginTop="26dp"
        app:icv_et_bg_focus="@drawable/shape_icv_et_bg_focus"
        app:icv_et_bg_normal="@drawable/shape_icv_et_bg_normal"
        app:icv_et_divider_drawable="@drawable/shape_divider_identifying"
        app:icv_et_number="4"
        app:icv_et_text_color="#000000"
        app:icv_et_width="60dp" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="5dp"
        android:onClick="onClick"
        android:text="清空" />


</LinearLayout>

里面的自定义属性解释如下:

(1)icv_et_with 是单个框的宽度

(2)icv_et_bg_focus是选中的时候框的background

(3)icv_et_bg_normal 是没有被选中的框的bg

(4)icv_et_num 是多少个框

(5)icv_et_text_color 是框里面数字的颜色

(6)icv_et_divider_drawable 是两个框之间的view,你看起来试空白的,其实是一个view,你可以写一个不是透明的shape试试就知道了

我这里贴出几个bg:

被选中的框的bg:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <solid android:color="#F2F2F2" />
    <!-- 大小 -->
    <size
        android:width="25dp"
        android:height="25dp" /><!-- 宽度和高度 -->
    <corners android:radius="2dp" />

    <stroke
        android:width="1dp"
        android:color="#A6D8EB" />
</shape>
框正常的bg:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <solid android:color="#F2F2F2" />
    <!-- 大小 -->
    <size
        android:width="25dp"
        android:height="25dp" /><!-- 宽度和高度 -->
    <corners android:radius="2dp" />

    <stroke
        android:width="1dp"
        android:color="#C7C7CD" />
</shape>
divider的bg:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">

    <size
        android:width="6dp"
        android:height="6dp" />
    <solid android:color="#0000" />
</shape>

自定义属性的xml,在res/values/attrs.xml里面:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!-- 自定义验证码输入框-->
    <declare-styleable name="SecurityCodeView">
        <!--输入框的数量-->
        <attr name="icv_et_number" format="integer" />
        <!--输入框的宽度-->
        <attr name="icv_et_width" format="dimension|reference" />
        <!--输入框之间的分割线-->
        <attr name="icv_et_divider_drawable" format="reference" />
        <!--输入框文字颜色-->
        <attr name="icv_et_text_color" format="color|reference" />
        <!--输入框文字大小-->
        <attr name="icv_et_text_size" format="dimension|reference" />
        <!--输入框获取焦点时边框-->
        <attr name="icv_et_bg_focus" format="reference" />
        <!--输入框没有焦点时边框-->
        <attr name="icv_et_bg_normal" format="reference" />
    </declare-styleable>

</resources>


在acrtivity中的使用:

 private SecurityCodeView icv;

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

        icv = (SecurityCodeView) findViewById(R.id.icv);

        icv.setInputCompleteListener(new SecurityCodeView.InputCompleteListener() {
            @Override
            public void inputComplete() {
                Log.i("icv_input", icv.getTextContent());
            }

            @Override
            public void deleteContent() {
                Log.i("icv_delete", icv.getTextContent());
            }
        });


    }

    public void onClick(View view) {
        icv.clearAllText();
    }




猜你喜欢

转载自blog.csdn.net/qq_34723470/article/details/78095406