###### tags: `Android` # Drawable Resources https://blog.csdn.net/lmj623565791/article/details/43752383 https://www.jianshu.com/p/4cd87e3c43d6 https://developer.android.com/guide/topics/resources/drawable-resource#top_of_page ## StateListDrawable 我們常希望按鈕默認、按下、放開等動作的顏色不同,所以需要監聽狀態並設置 Drawable 最土法煉鋼的方式就是用程式設定各種監聽,不斷切換 Drawable 但使用 StateListDrawable 能簡化這個過程,它可針對元件的狀態制定不同的 Drawable ### 回饋感按鈕 它有很多的狀態可以選擇,以下使用常見的狀態與 TextView 做一個有回饋感的按鈕  首先建立兩種背景,默認與顏色變化的 Drawable ==btn_transparent== ```xml= <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"> <padding android:left="12dp" android:top="4dp" android:right="12dp" android:bottom="4dp" /> <stroke android:width="1dp" android:color="#F3F3F3" /> <corners android:radius="10dp" /> </shape> ``` ==bg_level_easy== ```xml= <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"> <padding android:left="12dp" android:top="4dp" android:right="12dp" android:bottom="4dp" /> <stroke android:width="1dp" android:color="@color/gray_light" /> <corners android:radius="10dp" /> <solid android:color="@color/level_easy"/> </shape> ``` 再來建立一個 StateListDrawable 並輸入程式碼 ==btn_level_easy== ```xml= <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_selected="true" android:drawable="@drawable/bg_level_easy"/> <item android:state_focused="true" android:drawable="@drawable/bg_level_easy"/> <item android:state_pressed="true" android:drawable="@drawable/bg_level_easy"/> <item android:drawable="@drawable/btn_transparent2"/> </selector> ``` 最後再將做好的 StateListDrawable 放到 TextView 就完成囉! ```xml= <TextView android:id="@+id/tv_easy" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="16dp" android:layout_marginStart="16dp" android:text="@string/level_easy" android:textSize="@dimen/text_large" android:textStyle="bold" android:background="@drawable/btn_level_easy" /> ``` ### 常駐狀態按鈕 如果希望按鈕按下後放開,顏色會變化該怎麼做呢?可以使用 activated 這個狀態 這個狀態代表按鈕被激活,而如何控制激活狀態可以使用程式碼控制  將上述的範例作修改,把 state_activated 加入 StateListDrawable ==btn_level_easy== ```xml= <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_selected="true" android:drawable="@drawable/bg_level_easy"/> <item android:state_focused="true" android:drawable="@drawable/bg_level_easy"/> <item android:state_pressed="true" android:drawable="@drawable/bg_level_easy"/> <item android:state_activated="true" android:drawable="@drawable/bg_level_easy"/> <item android:drawable="@drawable/btn_transparent2"/> </selector> ``` 然後,因為按下後會變色,所以文字的顏色也要改變,這個部分需要再製作一個 Drawable 先在 res 建立 color 資料夾,再輸入程式碼  ==level_text== ```xml= <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_selected="true" android:color="@android:color/white"/> <item android:state_focused="true" android:color="@android:color/white" /> <item android:state_pressed="true" android:color="@android:color/white" /> <item android:state_activated="true" android:color="@android:color/white"/> <item android:color="#A5A5A5" /> </selector> ``` 將文字變色套用在 TextView 的 textColor 屬性 ```xml= <TextView android:id="@+id/tv_easy" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="16dp" android:layout_marginStart="16dp" android:text="@string/level_easy" android:textSize="@dimen/text_large" android:textStyle="bold" android:background="@drawable/btn_level_easy" android:textColor="@color/level_text"/> ``` 最後設定監聽事件改變激活狀態就完成囉! ```kotlin= tv_easy.setOnClickListener { it.isActivated = !it.isActivated } ``` :::danger 使用時要注意 StateListDrawable 會由上而下尋找符合的狀態,只要符合就返回 這也是為什麼默認狀態始終要放在最下面的原因 ::: ## 用檔名取得 Drawable ```kotlin= private fun getLevelImage(level: Int): Int { val name = String.format("level%d", level) return resources.getIdentifier(name, "drawable", context?.packageName) } ``` ## 程式碼修改 Drawable 顏色 利用 ColorFilter 可以做到顏色更換,在 ImageView、Drawable 類別下都有其函式 這樣就不用為了每個顏色去建立很多的 Drawable ```kotlin= val bg = context.getColor(R.color.bg) if (Build.VERSION.SDK_INT >= 29) view.background.colorFilter = BlendModeColorFilter(bg, BlendMode.SRC_ATOP) else view.background.setColorFilter(bg, PorterDuff.Mode.SRC_ATOP) ``` [Set android shape color programmatically](https://stackoverflow.com/questions/17823451/set-android-shape-color-programmatically) [搞明白PorterDuff.Mode](https://www.jianshu.com/p/d11892bbe055) ## 參考文章 [使用 Selector 改變 TextView 字體颜色](https://www.cnblogs.com/yuqf/p/5887970.html) [設定只有頂部有圓角](https://stackoverflow.com/questions/8930555/android-drawable-with-rounded-corners-at-the-top-only)
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up