先上代码
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,输入框左边的图像标志,以及输入数量显示的数字大小。
网友评论