简书App 是我很喜欢的一款软件。今天就模仿了一下他的登录框。先上图:
好了下面上代码,自定义ImgEditText 继承与EditText。重写一些方法。
1 package lyf.myimgedittextdemo;
2
3 import android.content.Context;
4 import android.graphics.Rect;
5 import android.graphics.drawable.Drawable;
6 import android.text.Editable;
7 import android.text.TextWatcher;
8 import android.util.AttributeSet;
9 import android.view.MotionEvent;
10 import android.widget.EditText;
11
12 /**
13 * lyf on 2016/12/6.
14 * 自定义的EditText右边带图片,可以设置点击事件
15 */
16 public class ImgEditText extends EditText implements TextWatcher {
17
18
19 //控件左边的图片
20 private Drawable leftDrawable = null;
21 //控件右边的图片
22 private Drawable rightDrawable = null;
23
24 // 控件是否有焦点
25 private boolean hasFoucs;
26
27 private IMyRightDrawableClick mightDrawableClick;
28
29 public ImgEditText(Context context) {
30 this(context, null);
31 }
32
33 public ImgEditText(Context context, AttributeSet attrs) {
34 //这里构造方法也很重要,不加这个很多属性不能再XML里面定义
35 this(context, attrs, android.R.attr.editTextStyle);
36 }
37
38 public ImgEditText(Context context, AttributeSet attrs, int defStyleAttr) {
39 super(context, attrs, defStyleAttr);
40 init();
41 }
42
43
44 //初始化基本图片
45 private void init() {
46 //获取RadioButton的图片集合
47 Drawable[] drawables = getCompoundDrawables();
48
49 leftDrawable = drawables[0];
50 rightDrawable = drawables[2];
51
52 setCompoundDrawablesWithIntrinsicBounds(leftDrawable, null, null, null);
53
54 //设置输入框里面内容发生改变的监听
55 addTextChangedListener(this);
56 }
57
58 //设置显示图片的大小
59 public void setCompoundDrawablesWithIntrinsicBounds(Drawable left, Drawable top, Drawable right, Drawable bottom) {
60 super.setCompoundDrawablesWithIntrinsicBounds(left, top, right, bottom);
61
62 //这里只要改后面两个参数就好了,一个宽一个是高,如果想知道为什么可以查找源码
63 if (left != null) {
64 left.setBounds(0, 0, 50, 50);
65 }
66 if (right != null) {
67 right.setBounds(0, 0, 50, 50);
68 }
69 if (top != null) {
70 top.setBounds(0, 0, 100, 100);
71 }
72 if (bottom != null) {
73 bottom.setBounds(0, 0, 100, 100);
74 }
75 setCompoundDrawables(left, top, right, bottom);
76 }
77
78 //光标选中时判断
79 @Override
80 protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
81 super.onFocusChanged(focused, direction, previouslyFocusedRect);
82 this.hasFoucs = focused;
83 if (focused) {
84 setImageVisible(getText().length() > 0);
85 } else {
86 setImageVisible(false);
87 }
88 }
89
90 //设置清除图标的显示与隐藏,调用setCompoundDrawables为EditText绘制上去
91 protected void setImageVisible(boolean flag) {
92 //如果当前右侧有图片则覆盖右侧的图片,如果没有还是显示原来的图片
93 if (getCompoundDrawables()[2] != null) {
94 rightDrawable = getCompoundDrawables()[2];
95 }
96 if (flag) {
97 setCompoundDrawables(getCompoundDrawables()[0], null, rightDrawable, null);
98 } else {
99 setCompoundDrawables(getCompoundDrawables()[0], null, null, null);
100 }
101 }
102
103 //文本框监听事件
104 @Override
105 public void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {
106 if (hasFoucs) {
107 if (text.length() > 0) {
108 setImageVisible(true);
109 } else {
110 setImageVisible(false);
111 }
112 }
113 }
114
115 public void beforeTextChanged(CharSequence s, int start, int count, int after) {
116
117 }
118
119 public void afterTextChanged(Editable s) {
120
121 }
122
123
124 /**
125 * 因为我们不能直接给EditText设置点击事件,所以我们用记住我们按下的位置来模拟点击事件
126 * 当我们按下的位置 在 EditText的宽度 - 图标到控件右边的间距 - 图标的宽度 和
127 * EditText的宽度 - 图标到控件右边的间距之间我们就算点击了图标,竖直方向就没有考虑
128 * (参考 )
129 */
130 @Override
131 public boolean onTouchEvent(MotionEvent event) {
132 if (event.getAction() == MotionEvent.ACTION_UP) {
133 if (getCompoundDrawables()[2] != null) {
134
135 boolean touchable = event.getX() > (getWidth() - getTotalPaddingRight())
136 && (event.getX() < ((getWidth() - getPaddingRight())));
137 if (touchable) {
138 //调用点击事件(外部实现)
139 mightDrawableClick.rightDrawableClick();
140 }
141 }
142 }
143
144 return super.onTouchEvent(event);
145 }
146
147 //设置右侧按钮的点击事件,外部调用的时候实现该方法
148 public void setDrawableClick( IMyRightDrawableClick myMightDrawableClick){
149 this.mightDrawableClick = myMightDrawableClick;
150 }
151
152 //自定义接口(实现右边图片点击事件)
153 public interface IMyRightDrawableClick {
154 void rightDrawableClick();
155 }
156
157 //允许外部修改右侧显示的图片
158 public void setRightDrawable(Drawable drawable){
159 rightDrawable = drawable;
160 setCompoundDrawablesWithIntrinsicBounds(leftDrawable, null, rightDrawable, null);
161 }
162
163 }
View Code
以上就是自定义类的主要代码了,注释比较清楚。
布局布局文件里直接引用就好。
1 <lyf.myimgedittextdemo.ImgEditText
2 android:id="@+id/pwdIet"
3 android:layout_width="0dp"
4 android:layout_height="wrap_content"
5 android:layout_weight="1"
6 android:background="@null"
7 android:drawableLeft="@mipmap/mm_image"
8 android:drawableRight="@mipmap/eye_normal"
9
10 android:paddingLeft="15dp"
11 android:paddingRight="15dp"
12 android:paddingTop="5dp"
13 android:drawablePadding="15dp"
14 android:layout_marginTop="10dp"
15 android:layout_marginBottom="10dp"
16 android:hint="密码"
17 android:inputType="numberPassword" />
View Code
下面看代码中的设置
1 pwdIet = (ImgEditText) this.findViewById(R.id.pwdIet);
2
3 pwdIet.setDrawableClick(new ImgEditText.IMyRightDrawableClick() {
4 @Override
5 public void rightDrawableClick() {
6 if (isHidden) {
7 //设置EditText文本为可见的
8 pwdIet.setTransformationMethod(HideReturnsTransformationMethod.getInstance());
9 pwdIet.setRightDrawable(getResources().getDrawable(R.mipmap.eye_selected));
10 } else {
11 //设置EditText文本为隐藏的
12 pwdIet.setTransformationMethod(PasswordTransformationMethod.getInstance());
13 pwdIet.setRightDrawable(getResources().getDrawable(R.mipmap.eye_normal));
14 }
15 isHidden = !isHidden;
16 pwdIet.postInvalidate();
17 //切换后将EditText光标置于末尾
18 CharSequence charSequence = pwdIet.getText();
19 if (charSequence instanceof Spannable) {
20 Spannable spanText = (Spannable) charSequence;
21 Selection.setSelection(spanText, charSequence.length());
22 }
23
24 }
25 });
View Code
这样我们的例子就完成了。
不懂的可以下载看源码,很简单。
源码下载