美文网首页
Andoriod EditText 监听删除按键问题解决方案

Andoriod EditText 监听删除按键问题解决方案

作者: WilburLi | 来源:发表于2019-10-29 13:46 被阅读0次

    起因是在做自定义 验证码 VIEW时遇到,特此记录如下


    image.png

    思路:
    问题在于它们只能与硬件键盘配合使用。要使用IME(软键盘)执行此操作,重写sendKeyEvent在EditText的InputConnection类。在IME中发生关键事件时调用此方法。

    具体方案代码:

    public class XEditText extends android.support.v7.widget.AppCompatEditText {
        private OnDelKeyEventListener delKeyEventListener;
    
        public XEditText(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
        }
    
        public XEditText(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public XEditText(Context context) {
            super(context);
        }
        /**
         * 解决部分机型不支持监听delete键
         */
        @Override
        public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
            return new XInputConnection(super.onCreateInputConnection(outAttrs),
                    true);
        }
    
        private class XInputConnection extends InputConnectionWrapper {
            public XInputConnection(InputConnection target, boolean mutable) {
                super(target, mutable);
            }
    
            @Override
            public boolean sendKeyEvent(KeyEvent event) {
                if (event.getAction() == KeyEvent.ACTION_DOWN
                        && event.getKeyCode() == KeyEvent.KEYCODE_DEL) {
                    if (delKeyEventListener != null) {
                        delKeyEventListener.onDeleteClick();
                        return true;
                    }
                }
                return super.sendKeyEvent(event);
            }
    
            @Override
            public boolean deleteSurroundingText(int beforeLength, int afterLength) {
                if (beforeLength == 1 && afterLength == 0) {
                    return sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN,
                            KeyEvent.KEYCODE_DEL))
                            && sendKeyEvent(new KeyEvent(KeyEvent.ACTION_UP,
                            KeyEvent.KEYCODE_DEL));
                }
                return super.deleteSurroundingText(beforeLength, afterLength);
            }
        }
    
        /**
         * EditText 删除回调
         */
        public void setDelKeyEventListener(OnDelKeyEventListener delKeyEventListener) {
            this.delKeyEventListener = delKeyEventListener;
        }
    
        public interface OnDelKeyEventListener {
            void onDeleteClick();
        }
    }
    

    以上是解决DEL无法监听DEL按钮问题,下是是验证码自定义控件
    (不是自己写的,COPY网上代码)

    public class PhoneCode extends RelativeLayout {
        private Context context;
        private TextView tv_code1;
        private TextView tv_code2;
        private TextView tv_code3;
        private TextView tv_code4;
        private View v1;
        private View v2;
        private View v3;
        private View v4;
        private XEditText et_code;
        private List<String> codes = new ArrayList<>();
        private InputMethodManager imm;
    
        public PhoneCode(Context context) {
            super(context);
            this.context = context;
            loadView();
        }
    
        public PhoneCode(Context context, AttributeSet attrs) {
            super(context, attrs);
            this.context = context;
            loadView();
        }
    
        private void loadView() {
            imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
            View view = LayoutInflater.from(context).inflate(R.layout.phone_code, this);
            initView(view);
            initEvent();
        }
    
        private void initView(View view) {
            tv_code1 = (TextView) view.findViewById(R.id.tv_code1);
            tv_code2 = (TextView) view.findViewById(R.id.tv_code2);
            tv_code3 = (TextView) view.findViewById(R.id.tv_code3);
            tv_code4 = (TextView) view.findViewById(R.id.tv_code4);
            et_code = (XEditText) view.findViewById(R.id.et_code);
            v1 = view.findViewById(R.id.v1);
            v2 = view.findViewById(R.id.v2);
            v3 = view.findViewById(R.id.v3);
            v4 = view.findViewById(R.id.v4);
            et_code.setOnKeyListener(new OnKeyListener() {
                @Override
                public boolean onKey(View v, int keyCode, KeyEvent event) {
                    if (keyCode == KeyEvent.KEYCODE_DEL) {
                    }
                    return false;
                }
            });
        }
    
        private void initEvent() {
            //验证码输入
            et_code.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) {
                    if (editable != null && editable.length() > 0) {
                        et_code.setText("");
                        if (codes.size() < 4) {
                            codes.add(editable.toString());
                            showCode();
                        }
                    }
                }
            });
            // 监听验证码删除按键
            et_code.setOnKeyListener(new View.OnKeyListener() {
                @Override
                public boolean onKey(View view, int keyCode, KeyEvent keyEvent) {
                    if (keyCode == KeyEvent.KEYCODE_DEL && keyEvent.getAction() == KeyEvent.ACTION_DOWN && codes.size() > 0) {
                        codes.remove(codes.size() - 1);
                        showCode();
                        return true;
                    }
                    return false;
                }
            });
        }
    
        /**
         * 显示输入的验证码
         */
        private void showCode() {
            String code1 = "";
            String code2 = "";
            String code3 = "";
            String code4 = "";
            if (codes.size() >= 1) {
                code1 = codes.get(0);
            }
            if (codes.size() >= 2) {
                code2 = codes.get(1);
            }
            if (codes.size() >= 3) {
                code3 = codes.get(2);
            }
            if (codes.size() >= 4) {
                code4 = codes.get(3);
            }
            tv_code1.setText(code1);
            tv_code2.setText(code2);
            tv_code3.setText(code3);
            tv_code4.setText(code4);
    
            setColor();//设置高亮颜色
            callBack();//回调
        }
    
        /**
         * 设置高亮颜色
         */
        private void setColor() {
            int color_default = Color.parseColor("#999999");
            int color_focus = Color.parseColor("#3F8EED");
            v1.setBackgroundColor(color_default);
            v2.setBackgroundColor(color_default);
            v3.setBackgroundColor(color_default);
            v4.setBackgroundColor(color_default);
            if (codes.size() == 0) {
                v1.setBackgroundColor(color_focus);
            }
            if (codes.size() == 1) {
                v2.setBackgroundColor(color_focus);
            }
            if (codes.size() == 2) {
                v3.setBackgroundColor(color_focus);
            }
            if (codes.size() >= 3) {
                v4.setBackgroundColor(color_focus);
            }
        }
    
        /**
         * 回调
         */
        private void callBack() {
            if (onInputListener == null) {
                return;
            }
            if (codes.size() == 4) {
                onInputListener.onSucess(getPhoneCode());
            } else {
                onInputListener.onInput();
            }
        }
    
        //定义回调
        public interface OnInputListener {
            void onSucess(String code);
    
            void onInput();
        }
    
        private OnInputListener onInputListener;
    
        public void setOnInputListener(OnInputListener onInputListener) {
            this.onInputListener = onInputListener;
        }
    
        /**
         * 显示键盘
         */
        public void showSoftInput() {
            //显示软键盘
            if (imm != null && et_code != null) {
                et_code.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        imm.showSoftInput(et_code, 0);
                    }
                }, 200);
            }
        }
    
        /**
         * 获得手机号验证码
         *
         * @return 验证码
         */
        public String getPhoneCode() {
            StringBuilder sb = new StringBuilder();
            for (String code : codes) {
                sb.append(code);
            }
            return sb.toString();
        }
    }
    

    布局文件如下:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <LinearLayout
            android:id="@+id/ll_code"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
            <LinearLayout
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:orientation="vertical"
                android:layout_marginRight="7dp">
                <TextView
                    android:id="@+id/tv_code1"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:textColor="#2D2D2D"
                    android:textSize="40sp"
                    android:background="@null"
                    android:gravity="center"/>
                <View
                    android:id="@+id/v1"
                    android:layout_width="match_parent"
                    android:layout_height="1dp"
                    android:background="#3F8EED" />
            </LinearLayout>
    
            <LinearLayout
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:orientation="vertical"
                android:layout_marginRight="7dp"
                android:layout_marginLeft="7dp">
                <TextView
                    android:id="@+id/tv_code2"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:textColor="#2D2D2D"
                    android:textSize="40sp"
                    android:background="@null"
                    android:gravity="center"/>
                <View
                    android:id="@+id/v2"
                    android:layout_width="match_parent"
                    android:layout_height="1dp"
                    android:background="#999999" />
            </LinearLayout>
            <LinearLayout
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:orientation="vertical"
                android:layout_marginRight="7dp"
                android:layout_marginLeft="7dp">
                <TextView
                    android:id="@+id/tv_code3"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:textColor="#2D2D2D"
                    android:textSize="40sp"
                    android:background="@null"
                    android:gravity="center"/>
                <View
                    android:id="@+id/v3"
                    android:layout_width="match_parent"
                    android:layout_height="1dp"
                    android:background="#999999" />
            </LinearLayout>
            <LinearLayout
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:orientation="vertical"
                android:layout_marginLeft="7dp">
                <TextView
                    android:id="@+id/tv_code4"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:textColor="#2D2D2D"
                    android:background="@null"
                    android:textSize="40sp"
                    android:gravity="center"/>
                <View
                    android:id="@+id/v4"
                    android:layout_width="match_parent"
                    android:layout_height="1dp"
                    android:background="#999999" />
            </LinearLayout>
        </LinearLayout>
    
        <com.syido.express.view.XEditText
            android:id="@+id/et_code"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignTop="@+id/ll_code"
            android:layout_alignBottom="@+id/ll_code"
            android:background="@android:color/transparent"
            android:textColor="@android:color/transparent"
            android:cursorVisible="false"
            android:inputType="number"/>
    </RelativeLayout>
    

    相关文章

      网友评论

          本文标题:Andoriod EditText 监听删除按键问题解决方案

          本文链接:https://www.haomeiwen.com/subject/alnwvctx.html