Android登入介面帳號密碼輸入框選中時,選中背景變換的實現方法
關注finddreams,一起分享,一起進步:http://blog.csdn.net/finddreams/article/details/45502277
常常在網上登入的時候看到這樣一個效果,就是當我們選擇帳號或者密碼輸入框時,它的背景會變成一種選中的狀態,也就是輸入框四周會有一種選中顏色的漸層效果。就如GitHub登入介面這樣的效果:
所以很多情況下我們也希望自己的APP也能有這樣的效果,當點擊帳號和密碼輸入框時顯示成選中的狀態,這樣的效果該怎麼實現呢?
其實要實現這樣的效果,思路很簡單,只需要建一個背景selector選取器,分別在不同的狀態下配置不同的背景。
一、建一個bg_edittext_selector.xml背景選取器,具體代碼如下:
二、然後就是寫布局檔案,並把選取器設定成輸入框的背景。代碼:
從代碼中可以看出,我在布局上使用的是一個LinearLayout中包含兩個子控制項,水平的排列,一個是TextView,另一個則是帶有清除功能的自訂控制項ClearEditText。
為了實現這樣選中效果,所以要把選取器bg_edittext_selector.xml做為父容器LinearLayout的背景。
但是這裡有個小的細節需要注意一樣,我們知道選取器有很多的狀態,預設狀態,選中,聚焦等等。那我們這裡的父容器本身沒有給它聚焦和選中的狀態,我們只關心的是帳號,密碼這兩個輸入框是否被選中了,選中了則需要變成選中的背景。那怎麼樣做到子類控制項的狀態和父容器的狀態相關聯呢?
這裡父容器控制項LinearLayout有一個很好的屬性 android:addStatesFromChildren=”true”,這個屬性在Google官方Api中是這樣描述的:
本人英語水平有限,只知道大概意思是說如果屬性設定成true的話,ViewGroup的drawable狀態就可以根據子類控制項EditText或者Button的聚焦狀態發生改變。這樣它們看起來成了一個整體,父容器的狀態跟隨子控制項的狀態來變動。
最後,把ClearEditText的代碼貼一下:
/** * @Description: 帶刪除按鈕的輸入框 * @author http://blog.csdn.net/finddreams */public class ClearEditText extends EditText implements OnFocusChangeListener, TextWatcher { /** * 刪除按鈕的引用,可以自訂圖片 */ private Drawable mClearDrawable; public static int SIZE = 0; public ClearEditText(Context context) { this(context, null); } public ClearEditText(Context context, AttributeSet attrs) { // 這裡構造方法也很重要,不加這個很多屬性不能再XML裡面定義 this(context, attrs, android.R.attr.editTextStyle); } public ClearEditText(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } private void init() { // 擷取EditText的DrawableRight,假如沒有設定我們就使用預設的圖片 mClearDrawable = getCompoundDrawables()[2]; if (mClearDrawable == null) { mClearDrawable = getResources().getDrawable( R.drawable.progresscancelbtn); } mClearDrawable.setBounds(0, 0, mClearDrawable.getIntrinsicWidth() + SIZE, mClearDrawable.getIntrinsicHeight() + SIZE); setClearIconVisible(false); setOnFocusChangeListener(this); addTextChangedListener(this); // setClickable(false); } /** * 因為我們不能直接給EditText設定點擊事件,所以我們用記住我們按下的位置來類比點擊事件 當我們按下的位置 在 EditText的寬度 - * 表徵圖到控制項右邊的間距 - 表徵圖的寬度 和 EditText的寬度 - 表徵圖到控制項右邊的間距之間我們就算點擊了表徵圖,豎直方向沒有考慮 */ @Override public boolean onTouchEvent(MotionEvent event) { if (getCompoundDrawables()[2] != null) { if (event.getAction() == MotionEvent.ACTION_UP) { boolean touchable = event.getX() > (getWidth() - getPaddingRight() - mClearDrawable .getIntrinsicWidth()) && (event.getX() < ((getWidth() - getPaddingRight()))); if (touchable) { this.setText(""); } } } return super.onTouchEvent(event); } /** * 當ClearEditText焦點發生變化的時候,判斷裡面字串長度設定清除表徵圖的顯示與隱藏 */ @Override public void onFocusChange(View v, boolean hasFocus) { if (hasFocus) { setClearIconVisible(getText().length() > 0); } else { setClearIconVisible(false); } } /** * 設定清除表徵圖的顯示與隱藏,調用setCompoundDrawables為EditText繪製上去 * * @param visible */ protected void setClearIconVisible(boolean visible) { Drawable right = visible ? mClearDrawable : null; setCompoundDrawables(getCompoundDrawables()[0], getCompoundDrawables()[1], right, getCompoundDrawables()[3]); } /** * 當輸入框裡面內容發生變化的時候回調的方法 */ @Override public void onTextChanged(CharSequence s, int start, int count, int after) { setClearIconVisible(s.length() > 0); } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void afterTextChanged(Editable s) { } /** * 設定晃動動畫 */ public void setShakeAnimation() { this.setAnimation(shakeAnimation(5)); } /** * 晃動動畫 * * @param counts * 1秒鐘晃動多少下 * @return */ public static Animation shakeAnimation(int counts) { Animation translateAnimation = new TranslateAnimation(0, 10, 0, 0); translateAnimation.setInterpolator(new CycleInterpolator(counts)); translateAnimation.setDuration(1000); return translateAnimation; }}