这次设计师给出的设计图中依然是包含了一个iOS系统级的功能,就是当输入框包含文本是,右边会出现一键清空的按钮,很方便,但是安卓却没有这样的功能。因为这种需求应该是每一个App应该都会有的,之前一直稀里糊涂的就随便弄了以下,现在想想,还是决定封装一下,方便以后的App使用吧。
需求分析
1.支持普通文本的一键清除功能
2.支持密码控件的显示/隐藏文本
3.支持手机号码的前缀显示
4.自持自定义手机号码前缀View
要优雅
1.参数可通过styleable配置
2.支持资源图片自定义
3.尽量减少库的大小,尽量只集成需要的单一功能
4.不需要修改EditText,只需要在EditText外部添加拓展布局
OK,我们来写代码
在EditText外面包裹RelativeLayout以放置其他辅助View
public class EditTextEX {
public EditTextEX(Context context) {
super(context);
init(context, null);
}
public EditTextEX(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public EditTextEX(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
}
设置自定义属性
在values中定义styleable
<declare-styleable name="EditTextEX">
<!-- 文本输入框ID -->
<attr name="edtId" format="reference"/>
<!-- 是否需要一键清空 默认不需要 -->
<attr name="needClear" format="boolean"/>
<!-- 是否需要密码的显示隐藏 默认不显示 -->
<attr name="needShowHidePassword" format="boolean"/>
<!-- 默认是否显示密码 -->
<attr name="ShowPassword" format="boolean"/>
<!-- 是否需要手机号码前缀 -->
<attr name="needPhoneNumberPrefix" format="boolean"/>
<!-- 手机号前缀显示 默认为+86 -->
<attr name="phoneNumberPrefix" format="string"/>
<!-- 后缀布局清空按钮和密码显示的间距 默认11dp -->
<attr name="suffixItemPadding" format="dimension"/>
<!-- 后缀布局与EditText的右间距 -->
<attr name="suffixRightPadding" format="dimension"/>
</declare-styleable>
在代码中获取这些属性
if (attrs != null) {
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.EditTextEX);
edtId = typedArray.getResourceId(R.styleable.EditTextEX_edtId, 0);
needClear = typedArray.getBoolean(R.styleable.EditTextEX_needClear, false);
needShowHidePassword = typedArray.getBoolean(R.styleable.EditTextEX_needShowHidePassword, false);
showPassword = typedArray.getBoolean(R.styleable.EditTextEX_ShowPassword, false);
needPhoneNumberPrefix = typedArray.getBoolean(R.styleable.EditTextEX_needPhoneNumberPrefix, false);
phoneNumberPrefix = typedArray.getString(R.styleable.EditTextEX_phoneNumberPrefix);
suffixItemPadding = typedArray.getDimensionPixelSize(R.styleable.EditTextEX_suffixItemPadding, padding);
suffixRightPadding = typedArray.getDimensionPixelSize(R.styleable.EditTextEX_suffixRightPadding, 0);
if (TextUtils.isEmpty(phoneNumberPrefix)) {
phoneNumberPrefix = "+86";
}
typedArray.recycle();
}
初始化默认前缀布局和后缀布局
这里两个布局的宽度取自EditText的padding,paddingLeft为前缀布局的宽度,paddingRight为后缀布局的宽度
hasSuffix = needClear || needShowHidePassword;
hasPrefix = needPhoneNumberPrefix;
if (hasSuffix) {
suffix = new LinearLayout(context);
suffix.setOrientation(LinearLayout.HORIZONTAL);
suffix.setGravity(Gravity.CENTER_VERTICAL|Gravity.RIGHT);
suffix.setPadding(0, 0,suffixRightPadding, 0);
}
if (needClear) {
btn_clear = new ImageView(context);
btn_clear.setImageResource(R.drawable.edt_clear_btn);
btn_clear.setScaleType(ImageView.ScaleType.CENTER);
btn_clear.setPadding(suffixItemPadding, 0, 0, 0);
suffix.addView(btn_clear, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT));
}
if (needShowHidePassword) {
btn_show_hide = new ImageView(context);
btn_show_hide.setImageResource(R.drawable.edt_show_hide_btn);
btn_show_hide.setScaleType(ImageView.ScaleType.CENTER);
btn_show_hide.setPadding(suffixItemPadding, 0, 0, 0);
suffix.addView(btn_show_hide, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT));
}
if (hasPrefix) {
prefix = new LinearLayout(context);
prefix.setOrientation(LinearLayout.HORIZONTAL);
prefix.setGravity(CENTER_VERTICAL);
}
if (needPhoneNumberPrefix) {
TextView tv1 = new TextView(context);
tv1.setText(phoneNumberPrefix);
tv1.setTextColor(getResources().getColor(R.color.c_333));
tv1.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimensionPixelSize(R.dimen.d_32));
tv1.setGravity(Gravity.CENTER);
prefix.addView(tv1, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
View divider = new View(context);
divider.setBackgroundColor(getResources().getColor(R.color.divider));
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(1, ViewGroup.LayoutParams.MATCH_PARENT);
int d_8 = getResources().getDimensionPixelSize(R.dimen.d_8);
params.setMargins(padding, d_8, padding, d_8);
prefix.addView(divider, params);
}
暂不支持使用代码声明
使用方法
1.使用EditTextEX嵌套EditText,布局方式同RelativeLayout
2.设置attrs中的属性
3.根据需要设置EditText的padding
4.效果图