国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統(tǒng) > Android > 正文

Android UI設(shè)計系列之自定義EditText實現(xiàn)帶清除功能的輸入框(3)

2019-12-12 06:15:21
字體:
供稿:網(wǎng)友

最近公司的產(chǎn)品在陸續(xù)做升級,上級領(lǐng)導(dǎo)給的任務(wù)是優(yōu)化代碼結(jié)構(gòu)以及項目架構(gòu),力爭把項目寫的精巧簡練,于是我們滿工程找冗余...

我們都知道每一個項目基本上都是有登陸頁的,在登陸頁中肯定是少不了輸入框了,當(dāng)我們在輸入框中輸入數(shù)據(jù)后如果輸入的內(nèi)容不正確或者是錯誤的或者是想重新輸入,如果嗯鍵盤上的刪除鍵就得一個一個的去刪除,這時候我們或許就想要是能有一個標(biāo)記當(dāng)點擊了這個標(biāo)記能把我們剛剛輸入的內(nèi)容清空就好了。這樣可以極大的提升用戶體驗,就拿QQ的登陸來說吧,效果如下:

當(dāng)點擊密碼框右側(cè)的小×圖標(biāo)時輸入的內(nèi)容就都清空了,真的很方便,我之前在項目中也自定義過這種效果的輸入框并且在項目中一直使用它,在此期間并沒有發(fā)現(xiàn)什么Bug,之前的自定義結(jié)構(gòu)如下:

實現(xiàn)方式是使用一個RelativeLayout,它包含了三個控件,兩邊是ImageView控件,中間是EditText控件,當(dāng)點擊右側(cè)清除按鈕后就可以清除輸入框的內(nèi)容了,但是最近在做產(chǎn)品優(yōu)化的時候感覺之前寫的這個自定義控件在代碼量上來說有點浪費,明明Android的EditText有drawableLeft和drawableRight屬性,為什么不去直接使用呢?于是用筆在草稿紙上畫了畫,花點時間又重新寫了一個具有同樣效果的輸入框,并且在代碼量上來說簡化了不少。

好了,還是老規(guī)矩,先來看看項目結(jié)構(gòu)吧:


工程中ClearEditText就是我又從新定義的帶清除功能的輸入框,主要是繼承了EditText為了利用它的drawableLeft和drawableRight屬性,那么趕緊看看它的實現(xiàn)吧

public class ClearEditText extends EditText implements TextWatcher,     OnFocusChangeListener {    /**    * 左右兩側(cè)圖片資源    */   private Drawable left, right;   /**    * 是否獲取焦點,默認(rèn)沒有焦點    */   private boolean hasFocus = false;   /**    * 手指抬起時的X坐標(biāo)    */   private int xUp = 0;      public ClearEditText(Context context) {     this(context, null);   }    public ClearEditText(Context context, AttributeSet attrs) {     this(context, attrs, android.R.attr.editTextStyle);   }    public ClearEditText(Context context, AttributeSet attrs, int defStyle) {     super(context, attrs, defStyle);     initWedgits();   }    /**    * 初始化各組件    * @param attrs    *      屬性集    */   private void initWedgits() {     try {       // 獲取drawableLeft圖片,如果在布局文件中沒有定義drawableLeft屬性,則此值為空       left = getCompoundDrawables()[0];       // 獲取drawableRight圖片,如果在布局文件中沒有定義drawableRight屬性,則此值為空       right = getCompoundDrawables()[2];       initDatas();     } catch (Exception e) {       e.printStackTrace();     }   }    /**    * 初始化數(shù)據(jù)    */   private void initDatas() {     try {       // 第一次顯示,隱藏刪除圖標(biāo)       setCompoundDrawablesWithIntrinsicBounds(left, null, null, null);       addListeners();     } catch (Exception e) {       e.printStackTrace();     }   }    /**    * 添加事件監(jiān)聽    */   private void addListeners() {     try {       setOnFocusChangeListener(this);       addTextChangedListener(this);     } catch (Exception e) {       e.printStackTrace();     }   }    @Override   public void beforeTextChanged(CharSequence s, int start, int count,       int after) {   }    @Override   public void onTextChanged(CharSequence s, int start, int before, int after) {     if (hasFocus) {       if (TextUtils.isEmpty(s)) {         // 如果為空,則不顯示刪除圖標(biāo)         setCompoundDrawablesWithIntrinsicBounds(left, null, null, null);       } else {         // 如果非空,則要顯示刪除圖標(biāo)         if (null == right) {           right = getCompoundDrawables()[2];         }         setCompoundDrawablesWithIntrinsicBounds(left, null, right, null);       }     }   }    @Override   public boolean onTouchEvent(MotionEvent event) {     try {       switch (event.getAction()) {       case MotionEvent.ACTION_UP:         // 獲取點擊時手指抬起的X坐標(biāo)         xUp = (int) event.getX();         // 當(dāng)點擊的坐標(biāo)到當(dāng)前輸入框右側(cè)的距離小于等于getCompoundPaddingRight()的距離時,則認(rèn)為是點擊了刪除圖標(biāo)         // getCompoundPaddingRight()的說明:Returns the right padding of the view, plus space for the right Drawable if any.         if ((getWidth() - xUp) <= getCompoundPaddingRight()) {           if (!TextUtils.isEmpty(getText().toString())) {             setText("");           }         }         break;       default:         break;       }     } catch (Exception e) {       e.printStackTrace();     }     return super.onTouchEvent(event);   }    @Override   public void afterTextChanged(Editable s) {   }    @Override   public void onFocusChange(View v, boolean hasFocus) {     try {       this.hasFocus = hasFocus;     } catch (Exception e) {       e.printStackTrace();     }   } } 

解釋一下ClearEditText的執(zhí)行順序,它首先繼承了EditText也就是說具有了EditText的所有功能,然后又實現(xiàn)了TextWatcher和OnFocusChangeListener接口,其中接口OnFocusChangeListener是用來監(jiān)聽當(dāng)前輸入框是否獲取到焦點的,我們把當(dāng)前輸入框獲取到的焦點的狀態(tài)值賦給hasFocus成員變量,如果獲取到了焦點則hasFocus的值為true,當(dāng)在輸入框中輸入內(nèi)容的時候會觸發(fā)TextWatcher監(jiān)聽器,就會順序執(zhí)行beforeTextChanged,onTextChanged和afterTextChanged方法,而我們僅僅需要在onTextChanged方法中對輸入框的值進行判斷就行了,如果輸入框框的值非空就顯示清空按鈕小圖標(biāo)否則不顯示,設(shè)置圖標(biāo)隱藏和顯示的方法就是直接調(diào)用setCompoundDrawablesWithIntrinsicBounds方法就行了,這個方法的具體使用就不詳解了,大體就是說按照我們給定的圖片尺寸把圖片畫到輸入框的四個方向上,如果傳入值為null就表示不繪制。

接下來就是對清空小圖標(biāo)進行監(jiān)聽了,我首先想到的是如果清空小圖標(biāo)是顯示的,就給他設(shè)置事件監(jiān)聽比如onClickListener或者是onTouchListener,但是遺憾的是找了API并沒有發(fā)現(xiàn)EditText提供對drawLeft或者是drawRight的事件監(jiān)聽,又來又打算自定義一個監(jiān)聽器但仔細(xì)想想又把代碼復(fù)雜化了,其實EditText是間接繼承View的而View中有個onTouchEvent方法,我們可以重寫onTouchEvent方法并在它里邊根據(jù)我們手指摁下或者是抬起的坐標(biāo)進行判斷,如果點擊的位置到當(dāng)前控件右側(cè)的距離小于等于當(dāng)前控件右側(cè)小圖標(biāo)的寬度加上paddingRight的值,則我們可以直接認(rèn)為是點擊了清除小圖標(biāo),就可以對當(dāng)前控件進行清空操作了,幸好EditText給我們提供了一個我現(xiàn)在認(rèn)為是非常實在的方法:getCompoundPaddingRight(),文檔的解釋就是:Returns the right padding of the view, plus space for the right Drawable if any.它的值就是清空小圖標(biāo)的寬度加上paddingRight的值,呵呵,有了它就好辦多了,(*^__^*) 嘻嘻……

好了,接下來我們來看看在布局文件中怎么使用它吧(其實很簡單,就是和EditText的使用方法一樣的,(*^__^*) 嘻嘻……)

<?xml version="1.0" encoding="utf-8"?> <LinearLayout   xmlns:android="http://schemas.android.com/apk/res/android"   android:orientation="vertical"   android:layout_width="fill_parent"   android:layout_height="fill_parent"   android:background="#ffffff">   <TextView     android:layout_width="fill_parent"     android:layout_height="wrap_content"     android:layout_margin="10dip"     android:text="@string/hello"     android:gravity="center"     android:textSize="20sp"     android:textColor="#000000" />      <com.llew.e.clear.view.wedgit.ClearEditText     android:id="@+id/clearEditText"     android:layout_width="fill_parent"     android:layout_height="wrap_content"     android:layout_margin="10dip"     android:paddingRight="8dip"     android:paddingTop="5dip"     android:paddingBottom="5dip"     android:hint="請輸入QQ號碼"     android:background="@drawable/pay_widget_input"     android:drawableLeft="@drawable/super_qq"     android:drawableRight="@drawable/clear_normal_list" />  </LinearLayout> 

就是寫完整我們自定義的包名就行了,屬性用的全是父類中的,再次感謝Java給我們提供的繼承特性,呵呵,
在運行之前還是貼出來MainActivity代碼吧,其實真的很簡單:

public class MainActivity extends Activity {   /** Called when the activity is first created. */   @Override   public void onCreate(Bundle savedInstanceState) {     super.onCreate(savedInstanceState);     setContentView(R.layout.main);   } } 

簡單吧?創(chuàng)建工程的時候自動生成的,壓根不用進行任何操作,呵呵
好了,我們運行一下,看看效果圖吧O(∩_∩)O~

輸入前:

輸入后:

點擊清除圖標(biāo)后:



呵呵,這種效果和之前自定義的一樣,并且在代碼量上來說卻是比之前的減少了不少,高興一下

好了,今天的自定義ClearEditText就講到這里,感謝收看。

源碼下載:Android UI實現(xiàn)帶清除功能的輸入框

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持武林網(wǎng)。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 鹤岗市| 刚察县| 博罗县| 晴隆县| 乐陵市| 庆安县| 赫章县| 郧西县| 昭平县| 航空| 德化县| 开阳县| 修水县| 宜昌市| 盘山县| 育儿| 垦利县| 通州市| 北京市| 敖汉旗| 蒙阴县| 纳雍县| 涞水县| 筠连县| 准格尔旗| 化隆| 普兰店市| 巩义市| 防城港市| 新竹市| 抚宁县| 垣曲县| 海盐县| 通州市| 东丽区| 思南县| 定边县| 正蓝旗| 泰宁县| 观塘区| 黄骅市|