lht80s 2019-07-04 16:40 采纳率: 50%
浏览 138
已采纳

请教一种效果的实现方法

图片说明

就是这种效果,有几个要求:

1、使用的不是定制的键盘,而是系统自带的键盘。

2、显示是四个分开的数字,但可以连续输入,按删除按钮会逐个删除,用户**无法**通过点击选取其中某个进行单独修改。

不知道有没有现成的控件,或者用什么方法可以实现。我现在脑袋有点僵了,想不出来。求大神赐教。

  • 写回答

2条回答 默认 最新

  • 你好好呀! 2019-07-05 10:17
    关注

    效果图:
    图片说明

    直接把类复制进去 把属性放到values下的attrs.xml文件中 即可使用,下划线的颜色可自行定义
    示例:

    <VerifyCodeNumView
            android:id="@+id/icv"
            android:layout_width="match_parent"
            android:layout_height="54dp"
            android:layout_marginTop="32dp"
            android:focusable="true"
            app:icv_et_bg_focus="@drawable/shape_code_et_bg_focus"
            app:icv_et_bg_normal="@drawable/shape_code_et_bg_normal"
            app:icv_et_number="4"
            app:icv_et_text_color="#404040"
            app:icv_et_text_size="27dp"
            app:icv_et_width="54dp"/>
    
    

    类:

    public class VerifyCodeNumView extends RelativeLayout {
    
        private static final String TAG = VerifyCodeNumView.class.getSimpleName();
    
        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 EditText[] mTextViews;
    
        private MyTextWatcher myTextWatcher = new MyTextWatcher();
    
        private InputMethodManager imm;
    
        public VerifyCodeNumView(Context context) {
            this(context, null);
        }
    
        public VerifyCodeNumView(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public VerifyCodeNumView(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_identify_num_code, this);
            containerEt = (LinearLayout) this.findViewById(R.id.container_et);
            et = (EditText) this.findViewById(R.id.et);
    
            TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.VerificationCodeView, defStyleAttr, 0);
            mEtNumber = typedArray.getInteger(R.styleable.VerificationCodeView_icv_et_number, 1);
            mEtWidth = typedArray.getDimensionPixelSize(R.styleable.VerificationCodeView_icv_et_width, 42);
            mEtDividerDrawable = typedArray.getDrawable(R.styleable.VerificationCodeView_icv_et_divider_drawable);
            mEtTextSize = typedArray.getDimensionPixelSize(R.styleable.VerificationCodeView_icv_et_text_size, 16);
            mEtTextColor = typedArray.getColor(R.styleable.VerificationCodeView_icv_et_text_color, Color.BLACK);
            mEtBackgroundDrawableFocus = typedArray.getDrawable(R.styleable.VerificationCodeView_icv_et_bg_focus);
            mEtBackgroundDrawableNormal = typedArray.getDrawable(R.styleable.VerificationCodeView_icv_et_bg_normal);
            //释放资源
            typedArray.recycle();
    
    
            Log.d(TAG, "mEtTextSize:"+mEtTextSize);
            // 当xml中未配置时 这里进行初始配置默认图片
    //        if (mEtDividerDrawable == null) {
    //            mEtDividerDrawable = context.getResources().getDrawable(R.drawable.shape_divider_identifying);
    //        }
    
            if (mEtBackgroundDrawableFocus == null) {
                mEtBackgroundDrawableFocus = context.getResources().getDrawable(R.drawable.shape_icv_et_bg_focus);
            }
    
            if (mEtBackgroundDrawableNormal == null) {
                mEtBackgroundDrawableNormal = context.getResources().getDrawable(R.drawable.shape_icv_et_bg_normal);
            }
    
            imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
    
            initUI();
        }
    
        // 初始UI
        private void initUI() {
            initTextViews(getContext(), mEtNumber, mEtWidth, mEtDividerDrawable, mEtTextSize, mEtTextColor);
            initEtContainer(mTextViews);
            setListener();
        }
    
    
        public void focule() {
            et.requestFocus();
            imm.showSoftInput(et, InputMethodManager.RESULT_UNCHANGED_SHOWN);
            et.setSelection(et.getText().length());
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            // 设置当 高为 warpContent 模式时的默认值 为 50dp
            int mHeightMeasureSpec = heightMeasureSpec;
    
            int heightMode = MeasureSpec.getMode(mHeightMeasureSpec);
            if (heightMode == MeasureSpec.AT_MOST) {
                mHeightMeasureSpec = MeasureSpec.makeMeasureSpec((int) dp2px(50, getContext()), MeasureSpec.EXACTLY);
            }
    
            super.onMeasure(widthMeasureSpec, mHeightMeasureSpec);
        }
    
    
        //初始化TextView
        private void initTextViews(Context context, int etNumber, int etWidth, Drawable etDividerDrawable, float etTextSize, int etTextColor) {
            // 设置 editText 的输入长度
            et.setCursorVisible(true);//将光标隐藏
            et.setFilters(new InputFilter[]{new InputFilter.LengthFilter(etNumber)}); //最大输入长度
            // 设置分割线的宽度
            if (etDividerDrawable != null) {
                etDividerDrawable.setBounds(0, 0, etDividerDrawable.getMinimumWidth(), etDividerDrawable.getMinimumHeight());
                containerEt.setDividerDrawable(etDividerDrawable);
            }
            mTextViews = new EditText[etNumber];
            for (int i = 0; i < mTextViews.length; i++) {
                EditText textView = new EditText(context);
                textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, etTextSize);
                textView.setTextColor(etTextColor);
                textView.setWidth(etWidth);
                textView.setHeight(etWidth);
                textView.setCursorVisible(true);
                textView.setBackgroundDrawable(mEtBackgroundDrawableNormal);
                textView.setGravity(Gravity.CENTER);
    
                textView.setFocusable(false);
                textView.setTypeface(Typeface.DEFAULT_BOLD);
    
                mTextViews[i] = textView;
            }
        }
    
        //初始化存储TextView 的容器
        private void initEtContainer(EditText[] mTextViews) {
            for (int i = 0; i < mTextViews.length; i++) {
                containerEt.addView(mTextViews[i]);
                if (i < mTextViews.length - 1) {
                    LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(0, 1);
                    layoutParams.weight = 1;
                    containerEt.addView(new View(getContext()), layoutParams);
                }
            }
        }
    
    
        private void setListener() {
            et.setOnTouchListener(new OnTouchListener() {
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    if(event.getAction()==MotionEvent.ACTION_UP) {
                        imm.showSoftInput(et, InputMethodManager.RESULT_UNCHANGED_SHOWN);
                        et.setSelection(et.getText().length());
                    }
                    return true;
                }
            });
            // 监听输入内容
            et.addTextChangedListener(myTextWatcher);
    
        }
    
        // 给TextView 设置文字
        private void setText(String inputContent) {
            Log.d(TAG, "setText:"+et.getText().toString());
            char[] chars = inputContent.toCharArray();
            for (int i = 0; i < mTextViews.length; i++) {
                EditText tv = mTextViews[i];
                if (i < chars.length) {
                    tv.setText(String.valueOf(chars[i]));
                }else {
                    tv.setText("");
                }
                if (i < chars.length) {
                    tv.setBackground(mEtBackgroundDrawableFocus);
                }else {
                    tv.setBackground(mEtBackgroundDrawableNormal);
                }
            }
            if (inputCompleteListener != null) {
                inputCompleteListener.inputComplete();
            }
        }
    
        StringBuffer buffer = new StringBuffer();
        /**
         * 获取输入文本
         *
         * @return string
         */
        public String getInputContent() {
            buffer.delete(0, buffer.length());
            for (EditText tv : mTextViews) {
                buffer.append(tv.getText().toString().trim());
            }
            return buffer.toString();
        }
    
        /**
         * 删除输入内容
         */
        public void clearInputContent() {
            for (int i = 0; i < 4; i++) {
                mTextViews[i].setBackground(mEtBackgroundDrawableNormal);
                mTextViews[i].setText("");
            }
            et.setText("");
        }
    
        /**
         * 设置输入框个数
         * @param etNumber
         */
        public void setEtNumber(int etNumber) {
            this.mEtNumber = etNumber;
            et.removeTextChangedListener(myTextWatcher);
            containerEt.removeAllViews();
            initUI();
        }
    
    
        /**
         * 获取输入的位数
         *
         * @return int
         */
        public int getEtNumber() {
            return mEtNumber;
        }
    
        // 输入完成 和 删除成功 的监听
        private InputCompleteListener inputCompleteListener;
    
        public void setInputCompleteListener(InputCompleteListener inputCompleteListener) {
            this.inputCompleteListener = inputCompleteListener;
        }
    
        public interface InputCompleteListener {
            void inputComplete();
        }
    
    
        public float dp2px(float dpValue, Context context) {
            return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
                    dpValue, context.getResources().getDisplayMetrics());
        }
    
        public float sp2px(float spValue, Context context) {
            return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
                    spValue, context.getResources().getDisplayMetrics());
        }
    
        private class MyTextWatcher implements TextWatcher {
    
            @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 editable) {
                String inputStr = editable.toString();
                setText(inputStr);
            }
        }
    
    }
    

    属性attr:

        <declare-styleable name="VerificationCodeView">
            <!--输入框的数量-->
            <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>
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 安装svn网络有问题怎么办
  • ¥15 Python爬取指定微博话题下的内容,保存为txt
  • ¥15 vue2登录调用后端接口如何实现
  • ¥65 永磁型步进电机PID算法
  • ¥15 sqlite 附加(attach database)加密数据库时,返回26是什么原因呢?
  • ¥88 找成都本地经验丰富懂小程序开发的技术大咖
  • ¥15 如何处理复杂数据表格的除法运算
  • ¥15 如何用stc8h1k08的片子做485数据透传的功能?(关键词-串口)
  • ¥15 有兄弟姐妹会用word插图功能制作类似citespace的图片吗?
  • ¥15 latex怎么处理论文引理引用参考文献