美文网首页
继承特定的viewgroup实现自定义view

继承特定的viewgroup实现自定义view

作者: 我就是杨过 | 来源:发表于2018-07-22 15:58 被阅读0次

    先上代码

    public class MinMaxEditText extends LinearLayout implements SaveFormField {
        @Inject
        Bus bus;
    
        TextView label;
        EditText value;
        TextView charLimit;
        TextView minLimit;
        int charLimitValue;
        private String labelText;
        private DirtyListener listener;
        private String originalString;
        private TextWatcher externalTextWatcher;
    
        public MinMaxEditText(Context context) {
            super(context);
            init();
        }
    
        public MinMaxEditText(Context context, AttributeSet attrs) {
            super(context, attrs);
    
            init();
            TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.MinMaxEditText, 0, 0);
    
            try {
                setLabel(a.getString(R.styleable.MinMaxEditText_label));
                setCharLimit(a.getInt(R.styleable.MinMaxEditText_charLimit, 0));
                setMinLimit(a.getInt(R.styleable.MinMaxEditText_minLimit, 0));
                setHint(a.getString(R.styleable.MinMaxEditText_hintText));
                showCharLimit(a.getBoolean(R.styleable.MinMaxEditText_showCharLimit, true));
                setIconId((a.getResourceId(R.styleable.MinMaxEditText_iconResource, -1)));
                setLimitTextSize(a.getDimension(R.styleable.MinMaxEditText_limitTextSize, 0));
                setHintTextColorIfExists(a);
                setEditTextTextColorIfExists(a);
            } finally {
                // TypedArray 是单例模式 回收之后  其他地方才能够使用
                a.recycle();
            }
        }
    
        private void init() {
            //这里是bus组件的引入 不用管
            GrindrApplication.getGrindrComponent().inject(this);
            //设置布局方向
            // 特定的布局view 有什么提供的方法 可以看源码  看提供哪些方法 来用
            setOrientation(VERTICAL);
            // 引入我们要展示的布局文件 并且赋值引用
            View.inflate(getContext(), R.layout.min_max_edit_text, this);
            label = findViewById(R.id.view_edit_profile_edit_label);
            value = findViewById(R.id.view_edit_profile_edit_value);
            charLimit = findViewById(R.id.view_edit_profile_edit_char_limit);
            minLimit = findViewById(R.id.view_edit_profile_edit_min_limit);
            //当输入的内容改变的时候 做一些判断和处理
            value.addTextChangedListener(new ExternalTextWatcher());
            //这个地方是设置输入软键盘enter键的显示
            value.setImeOptions(EditorInfo.IME_ACTION_DONE);
            //设置只能单行处理
            setNumLines();
        }
    
        //自定义listener的名称 并且添加
        public void addTextChangedListener(TextWatcher tw) {
            this.externalTextWatcher = tw;
        }
    
        public String getText() {
            return value.getText().toString();
        }
    
        public void setText(String text) {
            value.setText(text);
            originalString = text;
            setContentDescription();
        }
    
        public String getLabel() {
            return labelText;
        }
    
        public void setLabel(String labelText) {
            this.labelText = labelText;
            label.setText(labelText);
            setContentDescription();
        }
    
        private void setContentDescription() {
            setContentDescription(getResources().getString(R.string.edit_profile_edit_text_content_description, getLabel(), getText(), getText().length(), charLimitValue));
        }
    
        public void setCharLimit(int charLimitValue) {
            this.charLimitValue = charLimitValue;
            if (charLimitValue == 0) {
                charLimit.setVisibility(View.GONE);
            } else {
                charLimit.setVisibility(View.VISIBLE);
                int numOfChars = charLimit.getText().length();
                charLimit.setText(String.format(Locale.getDefault(), "%d/%d", numOfChars, charLimitValue));
                //这个地方是设置edittext输入字符的最大个数
                value.setFilters(new InputFilter[]{createInputFilter(charLimitValue)});
            }
        }
    
        public void setMinLimit(int charLimitValue) {
            if (charLimitValue == 0) {
                minLimit.setVisibility(View.GONE);
            } else {
                minLimit.setVisibility(View.VISIBLE);
                minLimit.setText(String.format(getResources().getString(R.string.min_max_edit_text_minimum), charLimitValue));
    
            }
        }
    
        public void setHint(String hint) {
            value.setHint(hint);
        }
    
        protected void setNumLines() {
            value.setMaxLines(1);
            value.setSingleLine();
            value.setLines(1);
        }
    
        public String getHint() {
            return value.getHint().toString();
        }
    
        public void showCharLimit(boolean show) {
            charLimit.setVisibility(show ? View.VISIBLE : View.GONE);
        }
    
        public void setIconId(int iconId) {
            if (iconId > 0) {
                value.setCompoundDrawablesWithIntrinsicBounds(ContextCompat.getDrawable(GrindrApplication.getGrindrApplication(), iconId), null, null, null);
            }
        }
    
        @Override
        public void setDirtyListener(DirtyListener listener) {
            this.listener = listener;
        }
    
        public EditText getValueView() {
            return value;
        }
    
        public void update(String value, DirtyListener dirtyListener) {
            setText(value);
            setDirtyListener(dirtyListener);
            getValueView().setHorizontallyScrolling(false);
            getValueView().setMaxLines(Integer.MAX_VALUE);
        }
    
        private void setLimitTextSize(float limitTextSize) {
            if (limitTextSize != 0) {
                charLimit.setTextSize(TypedValue.COMPLEX_UNIT_PX, limitTextSize);
                minLimit.setTextSize(TypedValue.COMPLEX_UNIT_PX, limitTextSize);
            }
        }
    
        private void setEditTextTextColorIfExists(TypedArray a) {
            if (a.hasValue(R.styleable.MinMaxEditText_minMaxEditTextColor)) {
                int editTextColor = a.getColor(R.styleable.MinMaxEditText_minMaxEditTextColor, 0);
                value.setTextColor(editTextColor);
            }
        }
    
        private void setHintTextColorIfExists(TypedArray a) {
            if (a.hasValue(R.styleable.MinMaxEditText_minMaxHintTextColor)) {
                int hintTextColor = a.getColor(R.styleable.MinMaxEditText_minMaxHintTextColor, 0);
                value.setHintTextColor(hintTextColor);
            }
        }
    
        private class ExternalTextWatcher implements TextWatcher {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                if (externalTextWatcher != null) {
                    externalTextWatcher.beforeTextChanged(s, start, count, after);
                }
            }
    
            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                if (externalTextWatcher != null) {
                    externalTextWatcher.onTextChanged(s, start, before, count);
                }
            }
    
            // 上面两个方法安全使用自定义的 listener 代替系统的 listener
            @Override
            public void afterTextChanged(Editable s) {        // s 是改变后的字符串的值
                //判断数值是否改变 改变的话用 改变isDirty的值
                if (listener != null && (originalString == null || !originalString.equals(s.toString()))) {
                    listener.onFieldDirty(true);
                }
                //设置字数显示的值 在这里进行组装
                if (charLimitValue != 0) {
                    charLimit.setText(String.format(Locale.getDefault(), "%d/%d", getCurCharSize(s), charLimitValue));
                }
                if (externalTextWatcher != null) {
                    externalTextWatcher.afterTextChanged(s);
                }
                setContentDescription();
            }
        }
    
        protected InputFilter createInputFilter(int charLimitValue){
            return new InputFilter.LengthFilter(charLimitValue);
        }
    
        protected int getCurCharSize(Editable s){
            return s.length();
        }
    }
    
    • 自定义属性文件如下
        <declare-styleable name="MinMaxEditText">
            <attr name="label" format="string" />
            <attr name="charLimit" format="integer" />
            <attr name="minLimit" format="integer" />
            <attr name="hintText" format="string" />
            <attr name="minMaxHintTextColor" format="color" />
            <attr name="showCharLimit" format="boolean" />
            <attr name="iconResource" format="reference" />
            <attr name="minMaxEditTextColor" format="color" />
            <attr name="limitTextSize" format="dimension" />
        </declare-styleable>
    

    说明

    • 自定义view的效果如图所示


      custom1.jpg
    • 功能: 设置上方的说明文字,设置输入框的最大输入数量,最小输入数量,hinttext,hinttext的color,输入框左边的图像标志,以及输入数量显示的数字大小。

    相关文章

      网友评论

          本文标题:继承特定的viewgroup实现自定义view

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