自訂群組件------帶刪除功能的EditText,------edittext

來源:互聯網
上載者:User

自訂群組件------帶刪除功能的EditText,------edittext

以前在為EditText添加左側表徵圖,以及右側一個刪除按鈕時,經常是使用FrameLayout,當這樣代碼複用差,維護也麻煩。最好的方法是重寫EditText實現該功能。現在看看,後面再講解實現方式。

重寫之後的組件有如下功能,只有當EditText內容不為空白,而且獲得焦點,才會出現刪除按鈕,點擊刪除按鈕則清空內容。代碼如下:

public class CleanableEditText extends EditText {//回呼函數private TextWatcherCallBack mCallback;//右側刪除表徵圖private Drawable mDrawable;private Context mContext;public void setCallBack(TextWatcherCallBack mCallback) {this.mCallback = mCallback;}public CleanableEditText(Context context) {super(context);this.mContext = context;init();}public CleanableEditText(Context context, AttributeSet attrs) {super(context, attrs);this.mContext = context;init();}public CleanableEditText(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);this.mContext = context;init();}public void init() {mDrawable = mContext.getResources().getDrawable(R.drawable.ic_clear);mCallback = null;//重寫了TextWatcher,在具體實現時就不用每個方法都實現,減少代碼量TextWatcher textWatcher = new TextWatcherAdapter() {@Overridepublic void afterTextChanged(Editable s) {//更新狀態,檢查是否顯示刪除按鈕updateCleanable(length(), true);//如果有在activity中設定回調,則此處可以觸發if(mCallback != null)mCallback.handleMoreTextChanged();}};this.addTextChangedListener(textWatcher);this.setOnFocusChangeListener(new OnFocusChangeListener() {@Overridepublic void onFocusChange(View v, boolean hasFocus) {//更新狀態,檢查是否顯示刪除按鈕updateCleanable(length(), hasFocus);}});}//當內容不為空白,而且獲得焦點,才顯示右側刪除按鈕public void updateCleanable(int length, boolean hasFocus){if(length() > 0 && hasFocus)setCompoundDrawablesWithIntrinsicBounds(null, null, mDrawable, null);elsesetCompoundDrawablesWithIntrinsicBounds(null, null, null, null);}@Overridepublic boolean onTouchEvent(MotionEvent event) {final int DRAWABLE_RIGHT = 2;//可以獲得上下左右四個drawable,右側排第二。表徵圖沒有設定則為空白。Drawable rightIcon = getCompoundDrawables()[DRAWABLE_RIGHT];if (rightIcon != null && event.getAction() == MotionEvent.ACTION_UP) {//檢查點擊的位置是否是右側的刪除表徵圖//注意,使用getRwwX()是擷取相對螢幕的位置,getX()可能擷取相對父組件的位置int leftEdgeOfRightDrawable = getRight() - getPaddingRight()- rightIcon.getBounds().width();if (event.getRawX() >= leftEdgeOfRightDrawable) {setText("");}}return super.onTouchEvent(event);}@Overrideprotected void finalize() throws Throwable {mDrawable = null;super.finalize();}}

實現的關鍵有兩點,其中一點是得知道有API可以為EditText設定上下左右的表徵圖,所以,就可以避免使用FrameLayout那種笨拙的方法(此處右側表徵圖在組件的代碼中自動加入了,左側表徵圖則需要在XML代碼中聲明)。需要注意的另一點是得知道如何計算點擊事件的位置,


實現過程遇到的一個小問題,在onTouchEvent()方法中,如果消耗事件(依據情況返回true或者false),則會出現一個問題,可以點擊EditText,如果設定日誌輸出,可以發現action_down,action_move,action_up都輸出了,代表點擊事件正常,但是依然無法獲得焦點。所以不難猜測EditText獲得焦點可能和點擊事件有關。如果強制調用requestFocus()方法,則可以“解決”這個問題,但是存在不穩定現象,有時會出bug,其中原因還沒細究。於是,此處我不處理點擊事件,直接返回super.onTouchEvent(event)


編碼上用了幾個小技巧

1,addTextChangedListener時發現經常需要實現三個方法,但是我們又只需重寫一個,顯得代碼有點冗餘,解決方式是增加一個adapter。

2,此處已經addTextChangedListener了,那麼如果我在activity中也需要監聽呢,如果直接監聽,則會覆蓋CleanableEditText中的監聽。為瞭解決這個方法,我使用了一個回調介面,使使用者在addTextChangedListener中有選擇的做更多事情。實現方式如下

回調介面的代碼如下:

public interface TextWatcherCallBack {public void handleMoreTextChanged();}

activity需要實現TextWatcherCallBack,並且為CleanableEditText設定callback(如以下代碼最後兩句)


public class LoginActivity extends BaseActivity implements TextWatcherCallBack {private ClearableAutoCompleteTextView accountView;private CleanableEditText passwordText;private Button login;@Overrideprotected void onCreate(Bundle bundle) {super.onCreate(bundle);setContentView(R.layout.activity_login);accountView = (ClearableAutoCompleteTextView) findViewById(R.id.et_account);passwordText = (CleanableEditText) findViewById(R.id.et_password);login = (Button) findViewById(R.id.bt_login);accountView.setCallBack(this);passwordText.setCallBack(this);//,,,,,,,}}


該自訂群組件的用法寫到這,現在已用於我的一個XMPP即時通訊工具,託管在Github上。

傳送門:Github地址

master分支是剛入門android寫的代碼,很差很渣,我自己都看不下去,不過唯一的價值是讓我現在能參考smack開發包的API使用,當時也給我寫android入門練手了。develop分支是痛下決心重新寫的,今晚剛擼了登陸介面。接下來業餘時間主要就維護這個項目,盡量多用上android各種知識。並寫部落格記錄這些知識。歡迎fork歡迎提issue。







聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.