本文为菜鸟窝作者刘婷的连载。”商城项目实战”系列来聊聊仿”京东淘宝的购物商城”如何实现。
类似于淘宝、京东等购物商城平台需要用户模块一样,商城项目也需要注册登录等与用户相关的模块,而在实现登录模块的时候,界面的效果都差不多,无非是输入用户信息,手机号、密码等,然后进行登录操作,下面是商城项目的登录界面效果。
上图是菜鸟商城项目中登录效果页面,其中的输入文本框带有清除的功能,而带清楚功能的 EditText 因为它给用户的便利性以及用户体验的良好而在很多的项目实际中都有应用,本文的重点也就是要实现自定义的带清除功能的 EditText。
实现自定义带清除功能的 EditText
按照上文中的效果图来一步步实现自定义带清除功能的 EditText。
1. 新建自定义控件
新建 class 文件,命名为 ClearEditText,让它继承于最新一代的 AppCompatEditText,同时文本框会根据输入的内容来变化后面的删除内容的图标的显示或者是隐藏,自然要对 EditText 的一些事件进行实现。
public class ClearEditText extends AppCompatEditText implements View.OnTouchListener, View.OnFocusChangeListener, TextWatcher {
public ClearEditText(final Context context) {
super(context);
}
public ClearEditText(final Context context, final AttributeSet attrs) {
super(context, attrs);
}
public ClearEditText(final Context context, final AttributeSet attrs, final int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
//具体实现
}
新建好了自定义的控件,然后开始为其实现功能。
2. 初始化删除按钮
删除按钮的样式可以自己定义,使用什么样的图标自己随意了,这都不重要的,重要的是要按照自己的想法初始化好删除按钮的样式以及隐藏显示的状态。
final Drawable drawable = ContextCompat.getDrawable(context, R.mipmap.icon_delete);
final Drawable wrappedDrawable = DrawableCompat.wrap(drawable); //Wrap the drawable so that it can be tinted pre Lollipop
DrawableCompat.setTint(wrappedDrawable, getCurrentHintTextColor());
mClearTextIcon = wrappedDrawable;
mClearTextIcon.setBounds(0, 0, mClearTextIcon.getIntrinsicHeight(), mClearTextIcon.getIntrinsicHeight());
setClearIconVisible(false);
其中的 setClearIconVisible(final boolean visible) 方法是用来控制删除按钮的显示和隐藏,初始状态下,删除按钮是不显示的,所以设置为了 false。
private void setClearIconVisible(final boolean visible) {
mClearTextIcon.setVisible(visible, false);
final Drawable[] compoundDrawables = getCompoundDrawables();
setCompoundDrawables(
compoundDrawables[0],
compoundDrawables[1],
visible ? mClearTextIcon : null,
compoundDrawables[3]);
}
根据传入的 boolean 类型的参数来控制删除图标的显示和隐藏。
3. 焦点变化的处理
EditText 控件输入文本之前需要先获取到焦点,获取到焦点之后,就可以输入文本,而当输入的文本长度大于0时,也就是有文本输入时,删除按钮就要处于显示的状态,否则就是要隐藏起来。
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
setClearIconVisible(getText().length() > 0);
} else {
setClearIconVisible(false);
}
if (mOnFocusChangeListener != null) {
mOnFocusChangeListener.onFocusChange(v, hasFocus);
}
}
获取焦点是第一步,下面还要对文本的变化监听进行实现。
4. 实现文本改变监听事件
输入框内文本改变时,删除按钮的状态也要随之变化。
@Override
public final void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {
if (isFocused()) {
setClearIconVisible(text.length() > 0);
}
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void afterTextChanged(Editable s) {
}
要先判断下是否获取到了焦点,获取到焦点后,然后再处理删除按钮的状态变化。
5. 实现清除功能
删除按钮和 EditText 是一体的,这里需要通过实现触摸事件的监听来实现删除按钮的清除功能。
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
final int x = (int) motionEvent.getX();
if (mClearTextIcon.isVisible() && x > getWidth() - getPaddingRight() - mClearTextIcon.getIntrinsicWidth()) {
if (motionEvent.getAction() == MotionEvent.ACTION_UP) {
setError(null);
setText("");
}
return true;
}
return mOnTouchListener != null && mOnTouchListener.onTouch(view, motionEvent);
}
当删除按钮处于显示状态,并且手势触摸的位置是删除按钮的位置,并且手势抬起时,设置 EditText 的内容为空,也就是清除了输入框中的文本内容。
登录界面使用 ClearEditText
ClearEditText 也就是上文中自定义的带清除功能的 EditText,现在要把它实际运用到登录界面中,使用方法很简单,只要把 ClearEditText添加到登录界面布局文件中就可以了。
<com.liuting.cniao_shop.widget.ClearEditText
android:id="@+id/login_edt_pwd"
style="@style/editText_base"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:drawableLeft="@mipmap/icon_lock"
android:drawablePadding="20dp"
android:hint="@string/please_input_password"
android:inputType="textPassword" />
这里是使用 ClearEditText 来显示上文图中的密码输入框,左侧是密码图标,提示为“请输入密码”,而输入的文本样式是“textPassword”,也就是密码格式,同样的道理,也可以实现手机号输入框,这里就不多写了。
最终效果图
登录界面很简单了,使用上面的 ClearEditText 展示手机号和密码输入框,加上一个登录按钮 Button 以及“注册”和“忘记密码”的 TextView 文本,这么简单的布局设计不用多展示了,这里把登录界面完善,然后在 Activity/Fragment 进行加载,运行代码获取效果图。
自定义的带清除功能的 EditText 就这样实现了,具体的样式可以按照自己的想法进行调整。