天天看點

自定義EditText—帶有清除功能,在顯示多行文本時清除按鈕位于整個EditText的右下角

自定義帶有清除功能的EditText不難,網上很多源碼。簡單來說,就是檢測使用者touch的位置,如果落在清除圖示裡面,則觸發清除。這個清除圖示是通過android:drawRight設定的。在EditText隻有一行文本的時候,一切正常。可是如果EditText有多行文本時,清除圖示就顯示在中間(如下圖)。

自定義EditText—帶有清除功能,在顯示多行文本時清除按鈕位于整個EditText的右下角

顯然,清除圖示顯示在右下角更加合理。我定義了一個EditText來實作這個效果。效果圖如下。實作思路是,抛棄使用drawRight來顯示清除圖示。而是直接在onDraw函數中繪制清除圖示。這麼做是因為drawRight的位置不好控制,看了下TextView的onDraw函數,想要改變drawRight的繪制位置很難。要特别說明的是,我是通過android:drawRight來獲得清除圖示的,獲得之後即把drawRight設為null了,這樣可以不用自定義屬性了。

自定義EditText—帶有清除功能,在顯示多行文本時清除按鈕位于整個EditText的右下角

完整源碼

package com.example.widget;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.text.InputType;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.EditText;

public class EditTextWithClear extends EditText {

	private Drawable drawableRight;
	private boolean showClearIcon;

	public EditTextWithClear(Context context) {
		super(context);
	}

	public EditTextWithClear(Context context, AttributeSet attrs) {
		super(context, attrs);
	}

	public EditTextWithClear(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
	}

	@Override
	protected void onFinishInflate() {
		super.onFinishInflate();
		Drawable[] drawables = getCompoundDrawables();
		// Store drawableRight
		drawableRight = drawables[2];
		setCompoundDrawablesWithIntrinsicBounds(drawables[0], drawables[1],
				null, drawables[3]);
	}
	
	@Override
	protected void onTextChanged(CharSequence text, int start,
			int lengthBefore, int lengthAfter) {
		super.onTextChanged(text, start, lengthBefore, lengthAfter);

		if (0 == text.length()) {
			showClearIcon = false;
		} else {
			showClearIcon = true;
		}
	}


	@Override
	public boolean onTouchEvent(MotionEvent event) {
		if (event.getAction() == MotionEvent.ACTION_UP
				&& showClearIcon
				&& drawableRight != null
				&& event.getX() >= (getWidth()
						- drawableRight.getIntrinsicWidth() - getPaddingRight())
				&& event.getY() >= (getHeight()
						- drawableRight.getIntrinsicHeight() - getPaddingBottom())) {

			setText("");

			int cacheInputType = getInputType();
			setInputType(InputType.TYPE_NULL);
			super.onTouchEvent(event);
			setInputType(cacheInputType);
			return true;
		}
		return super.onTouchEvent(event);
	}

	@Override
	protected void onDraw(Canvas canvas) {
		if (showClearIcon && drawableRight != null) {
			float dy = getHeight() - drawableRight.getIntrinsicHeight()
					- getPaddingBottom();
			float dx = getWidth() - drawableRight.getIntrinsicWidth()
					- getPaddingRight();
			canvas.save();
			canvas.translate(dx, dy);
			drawableRight.draw(canvas);
			canvas.restore();
		}
		super.onDraw(canvas);
	}

}