美文网首页
Android 自定义控件 IPEditText

Android 自定义控件 IPEditText

作者: sssssss_ | 来源:发表于2022-06-14 16:30 被阅读0次

    自定义的IP输入框

    参考自:https://github.com/lanyan520/Idea-EditText

    功能分析

    1. 四个输入框;
    2. 输入框最多输入3位数,且不能大于255;
    3. 不满足条件2的时候,自动切换到下一个输入框;
    4. get方法能快速获取IP地址

    1. AbsEditText
    2. AbsEditTextGroup
    3. IPEditText
    4. IPView

    使用

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">
    
        <com.zhd.screenviewer.ipview.IPView
            android:id="@+id/ip_view"
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:layout_margin="10dp" />
    
    </LinearLayout>
    

    代码

    1. AbsEditText

    import android.content.Context;
    import android.text.InputFilter;
    import android.text.method.NumberKeyListener;
    import android.util.AttributeSet;
    
    
    public abstract class AbsEditText extends androidx.appcompat.widget.AppCompatEditText {
        public AbsEditText(Context context) {
            this(context, null, 0);
        }
    
        public AbsEditText(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public AbsEditText(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            setMaxLength();
            addInputFilter();
        }
    
        /**
         * 初始化配置
         */
        protected void setMaxLength() {
            //setOnKeyListener((OnKeyListener) DigitsKeyListener.getInstance(""));
            setFilters(new InputFilter[]{ new InputFilter.LengthFilter(getMaxLength()) });
        }
    
        protected void addInputFilter() {
            setKeyListener(new NumberKeyListener() {
                @Override
                protected char[] getAcceptedChars() {
                    return getInputFilterAcceptedChars();
                }
    
                @Override
                public int getInputType() {
                    return getEditTextInputType();
                }
            });
        }
    
        /**
         * 输入内容最大长度
         * @return
         */
        public abstract int getMaxLength();
    
        /**
         * 输入内容过滤
         * @return
         */
        public abstract char[] getInputFilterAcceptedChars();
    
        /**
         * 输入内容检查是否ok
         * @return
         */
        public abstract boolean checkInputValue();
    
        public abstract int getEditTextInputType();
        
    }
    

    2. AbsEditTextGroup

    
    import java.util.ArrayList;
    
    import android.content.Context;
    import android.graphics.drawable.ColorDrawable;
    import android.text.Editable;
    import android.text.TextWatcher;
    import android.util.AttributeSet;
    import android.view.Gravity;
    import android.view.KeyEvent;
    import android.view.View;
    import android.widget.LinearLayout;
    import android.widget.TextView;
    
    
    public abstract class AbsEditTextGroup extends LinearLayout implements TextWatcher {
    
        protected float sp16 = 16.0f;
        protected int dp4 = 4;
        protected ArrayList<AbsEditText> editTexts = new ArrayList<AbsEditText>();
    
        public AbsEditTextGroup(Context context) {
            this(context, null, 0);
        }
    
        public AbsEditTextGroup(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public AbsEditTextGroup(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            addViews();
            buildListener();
        }
    
    
        protected void addViews() {
            for (int i = 0; i < getChildCount(); i++) {
                if (i % 2 == 0) {
                    AbsEditText absEditText = createAbsEditText();
                    editTexts.add(absEditText);
                    addView(absEditText);
                } else {
                    addView(createSemicolonTextView());
                }
            }
        }
    
        protected AbsEditText createAbsEditText() {
    
            AbsEditText absEditText = getAbsEditText();
            LayoutParams params = new LayoutParams(0, LayoutParams.MATCH_PARENT);
            params.weight = 1;
            absEditText.setLayoutParams(params);
            absEditText.setTextSize(sp16);//sp
            absEditText.setTextColor(0xFF888888);
            absEditText.setGravity(Gravity.CENTER);
            absEditText.setPadding(dp4, dp4, dp4, dp4);
            absEditText.setSingleLine();
            absEditText.setHint("0");
            absEditText.setFocusableInTouchMode(true);
            absEditText.setBackgroundDrawable(new ColorDrawable(0xFFFFFFFF));
            applyEditTextTheme(absEditText);
            return absEditText;
        }
    
        protected TextView createSemicolonTextView() {
            TextView textView = new TextView(getContext());
            LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
            textView.setLayoutParams(params);
            textView.setTextSize(sp16);//sp
            textView.setTextColor(0xFF444444);
            textView.setText(getSemicolomText());
            applySemicolonTextViewTheme(textView);
            return textView;
        }
    
        protected void buildListener() {
            for (int i = 0; i < editTexts.size(); i++) {
                editTexts.get(i).addTextChangedListener(this);
                if (i != 0) {
                    editTexts.get(i).setOnKeyListener(new OnDelKeyListener(editTexts.get(i - 1), editTexts.get(i)));
                }
            }
        }
    
        @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) {
            if (s.toString().length() == getDelMaxLength()) {
                for (int i = 0; i < editTexts.size() - 1; i++) {
                    if (editTexts.get(i).hasFocus()) { //hasFocus √ & isFocus ×
                        editTexts.get(i).clearFocus();
                        editTexts.get(i + 1).requestFocus();
                        break;
                    }
                }
            }
        }
    
        public boolean checkInputValue() {
            boolean result = true;
            for (int i = 0; i < editTexts.size(); i++) {
                if (!editTexts.get(i).checkInputValue()) {
                    result = false;
                    break;
                }
            }
    
            return result;
        }
    
        /**
         * IP网关子网掩码转byte4个字节
         * @return
         */
        public byte[] getBytesWithIP() {
            byte[] result = new byte[4];
            for (int i = 0; i < editTexts.size(); i++) {
                int number = Integer.valueOf(editTexts.get(i).getText().toString());
                result[i] = (byte) number;
            }
            return result;
        }
    
        /**
         * Mac地址转换6字节byte
         * @return
         */
        public byte[] getBytesWithMac() {
            byte[] result = new byte[6];
            for (int i = 0; i < editTexts.size(); i++) {
                String mac = editTexts.get(i).getText().toString();
                byte byteMac = Integer.valueOf(mac, 16).byteValue();
                result[i] = byteMac;
            }
            return result;
        }
    
    
        /**
         * 重置自布局的输入控件
         */
        public void resetText() {
            for (AbsEditText editText : editTexts) {
                editText.setText("");
            }
        }
    
        class OnDelKeyListener implements OnKeyListener {
    
            private AbsEditText clearEditText;
            private AbsEditText requestEditText;
    
            public OnDelKeyListener(AbsEditText requestEditText, AbsEditText clearEditText) {
                this.requestEditText = requestEditText;
                this.clearEditText = clearEditText;
            }
    
            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                if (keyCode == KeyEvent.KEYCODE_DEL
                        && event.getAction() == KeyEvent.ACTION_DOWN && clearEditText.getSelectionStart() == 0) {
                    clearEditText.clearFocus();
                    requestEditText.requestFocus();
                    requestEditText.setSelection(requestEditText.getText().toString().trim().length());
                    return true;
                }
                return false;
            }
        }
    
        public ArrayList<AbsEditText> getChildEditTextViews() {
            return editTexts;
        }
    
        public abstract int getChildCount();
    
        public abstract AbsEditText getAbsEditText();
    
        public abstract String getSemicolomText();
    
        public abstract int getDelMaxLength();
    
        public abstract void applySemicolonTextViewTheme(TextView semicolonTextView);
    
        public abstract void applyEditTextTheme(AbsEditText absEditText);
    }
    

    3. IPEditText

    import android.content.Context;
    import android.text.InputType;
    import android.util.AttributeSet;
    
    
    public class IPEditText extends AbsEditText {
    
        public IPEditText(Context context) {
            this(context, null, 0);
        }
    
        public IPEditText(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public IPEditText(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
        }
    
        @Override
        public int getMaxLength() {
            return 3;
        }
    
        @Override
        public char[] getInputFilterAcceptedChars() {
            return new char[]{ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
        }
    
        @Override
        public boolean checkInputValue() {
            String textValue = getText().toString().trim();
            if (textValue.isEmpty()) {
                return false;
            } else {
                int number = Integer.valueOf(textValue);
                return number >= 0 && number <= 255;
            }
        }
    
        @Override
        public int getEditTextInputType() {
            return InputType.TYPE_CLASS_NUMBER;
        }
    }
    

    4. IPView

    import android.content.Context;
    import android.text.Editable;
    import android.util.AttributeSet;
    import android.view.Gravity;
    import android.widget.TextView;
    
    
    public class IPView extends AbsEditTextGroup {
        public IPView(Context context) {
            this(context, null, 0);
        }
    
        public IPView(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public IPView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
        }
    
        @Override
        public int getChildCount() {
            return 7;
        }
    
        @Override
        public AbsEditText getAbsEditText() {
            return new IPEditText(getContext());
        }
    
        @Override
        public String getSemicolomText() {
            return ".";
        }
    
        @Override
        public int getDelMaxLength() {
            return 3;
        }
    
        @Override
        public void applySemicolonTextViewTheme(TextView semicolonTextView) {
            semicolonTextView.setPadding(0, 0, 0, 5);
            semicolonTextView.getPaint().setFakeBoldText(true);
            semicolonTextView.setBackgroundColor(0xFFFFFFFF);
            semicolonTextView.setGravity(Gravity.BOTTOM);
        }
    
        @Override
        public void applyEditTextTheme(AbsEditText absEditText) {
    
        }
    
        @Override
        public void afterTextChanged(Editable s) {
            if (s.toString().length() == getDelMaxLength()) {
                for (int i = 0; i < editTexts.size() - 1; i++) {
                    if (editTexts.get(i).hasFocus()) { //hasFocus √ & isFocus ×
                        editTexts.get(i).clearFocus();
                        editTexts.get(i + 1).requestFocus();
    
                        String lastEditTextValue = editTexts.get(i).getText().toString();
                        if (Integer.parseInt(lastEditTextValue) > 255) {
                            editTexts.get(i).setText(lastEditTextValue.substring(0, 2));
                            editTexts.get(i + 1).setText(lastEditTextValue.substring(2, 3));
                            editTexts.get(i + 1).setSelection(1);
                        }
                        break;
                    }
                }
            }
        }
    
        /**
         * 设置初始值,例如默认网关:"255\\.255\\.255\\.0" 正则表达式转义字符相关知识
         */
        public void setGatewayText(String[] ips) {
            if (ips == null) {
                ips = new String[]{ "255", "255", "255", "0" };
            }
            for (int i = 0; i < editTexts.size(); i++) {
                editTexts.get(i).setText(ips[i]);
            }
        }
    }
    

    相关文章

      网友评论

          本文标题:Android 自定义控件 IPEditText

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