美文网首页
继承特定的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