自定义输入控件

转发请注明出处

这里写图片描述
网络上大部分的输入控件都是多个EditText组合而成,本例中采用的是:

  • 单个EditText作为输入的捕捉控件
  • 多个ImageView的子类作为显示的控件,绘制EditText中的数据

如上图:

  • 输入前和输入后输入框需要发生响应的改变
  • 点击自定义控件要弹出软键盘
  • EditText数据捕捉,以及EditView不能操作(如果可以操作,数据处理会混乱)
  • 输完后会得到相应的提示
  • ImageView的子类可以设置宽高,字体大小颜色,以及两个View之间的间隔

那么代码走起:
首先是ImageView的子类TextImageView,onDraw的实现也很简单,就是判断text是否长度大于0,如果大于0则绘制文字,还有一些细节处理就是设置字体颜色,字体大写,获取字体的宽高

    @Override
    protected void onDraw(Canvas canvas) {
        if (text.length() > 0) {
            if (isDrawSrc) {
                super.onDraw(canvas);
            }
            canvas.drawText(text, 0, text.length(), (getMeasuredWidth() - textWidth) / 2, (getMeasuredHeight() + dy) / 2, textPaint);
        } else {
            super.onDraw(canvas);
        }
    }

其次PasswordView是一个自定义ViewGroup,引入了一个布局,布局中就是一个EditText(数据捕捉)和一个Linearlayout(代码添加TextImageView)。EditText的宽高是1dp和0dp(避免用户可以操作EditText);给Linearlayout设置divider属性(两个TextImageView的间隔)

PasswordView的核心代码如下:
- 代码控制EditView获取输入

public void requestEtFocus() {
        catchInput.setFocusable(true);
        catchInput.setFocusableInTouchMode(true);
        catchInput.setClickable(true);
        catchInput.requestFocus();
        showSoftKeyboard(catchInput);
        catchInput.setCursorVisible(false);
        catchInput.setSelection(catchInput.length());
    }
    // 动态添加TextImageView 
    for (int i = 0; i < passwordLength; i++) {
            TextImageView view = new TextImageView(context);
            view.setTextSize(textSize);
            view.setTextColor(textColor);
            content.addView(view);
            if (unInputBg != 0) {
                view.setBackgroundResource(unInputBg);// 设置未输入前的背景
            }
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams((int) itemWidth, (int) itemHeight);
            if (i == 0) {
                params.setMargins((int) dpToPixel(1), 0, 0, 0);
            }
            if (i == passwordLength - 1) {
                params.setMargins(0, 0, (int) dpToPixel(1), 0);
            }
            view.setLayoutParams(params);
            views[i] = view;
            // 分割字体,给TextIamgeView绘制文字
            if (text != null && i < text.length()) {
                setItemText(text.subSequence(i, i + 1));
            }
        }
        // 输入监听
        catchInput.addTextChangedListener(new 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) {
                if (s.length() > 0) {
                    // index:成员变量;保存当前的输入了几个字符
                    if (index > s.length()) {
                        removeItemText();// 删除
                    } else {
                        setText(s);
                        if (s.length() == passwordLength) {
                            if (listener != null) {
                                // 输入完成回调
                                listener.onInputCodeEnd(s);
                            }
                        }
                    }
                } else if (s.length() == 0 && index > 0) {
                    removeItemText();
                }
            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });

实现比较简单,大多都是一些细节处理,具体看源码https://github.com/cqf-hn/PasswordView


猜你喜欢

转载自blog.csdn.net/Hello_GoodBey/article/details/80223485