日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android中动态的更改selector中某张图片的属性

發布時間:2024/7/5 Android 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android中动态的更改selector中某张图片的属性 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在我們平常開發的時候會有許多狀態按鈕,比如state_pressed,android:state_checked,或者就正常狀態等等,我們做這樣的效果通常需要三個文件,一張是按下的圖片,一張是正常狀態的圖片,一張是管理它們的selector文件,如果在不斷更新迭代的過程中出現了很多這樣的按鈕,而且它們的顏色什么的都不一樣,那我們的res/drawable文件夾下就會出現很多個這樣的組合文件,導致我們的程序越來越大、越來越大,這肯定不是我們想看到的。


那么,我現在要拿出什么來解決這個問題呢?就是動態的更改它們的屬性,把所有的工作都放在代碼里面,減少selector.xml文件的產生:

我們在寫屬性的時候盡量要使用這樣的方式(如果美工給了圖的話,盡量讓提供顏色值就可以了,不要做那么多圖):

<span style="font-size:12px;"><?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"><item android:state_pressed="true"><shape><corners android:radius="5dp" /><solid android:color="#78909c" /></shape></item><item><shape><corners android:radius="5dp" /><solid android:color="#607d8b" /></shape></item></selector></span>

布局文件:

<span style="font-size:12px;"><?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/container"android:layout_width="match_parent"android:layout_height="match_parent" ><Buttonandroid:id="@+id/button"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_margin="10dp"android:text="Hello"android:textColor="#fff" /></FrameLayout></span>

這個xml文件的正常顯示效果是:


效果還是挺不錯的,接下來我們要動態改變它的效果,怎么做呢:

<span style="font-size:12px;">package com.sahadev.activitythemetest;import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method;import android.app.Activity; import android.graphics.Color; import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable.ConstantState; import android.graphics.drawable.GradientDrawable; import android.graphics.drawable.StateListDrawable; import android.os.Bundle; import android.widget.Button;public class MainActivity2 extends Activity { // Hold a reference to the current@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_zoom);Button button = (Button) findViewById(R.id.button);Drawable backgroundDrawable = getResources().getDrawable(R.drawable.xml_background);button.setBackground(backgroundDrawable);StateListDrawable sld = (StateListDrawable) backgroundDrawable;// 通過向下轉型,轉回原型,selector對應的Java類為:StateListDrawableConstantState cs = sld.getConstantState();try {Method method = cs.getClass().getMethod("getChildren", null);// 通過反射調用getChildren方法獲取xml文件中寫的drawable數組method.setAccessible(true);Object obj = method.invoke(cs, null);Drawable[] drawables = (Drawable[]) obj;for (int i = 0; i < drawables.length; i++) {// 接下來我們要通過遍歷的方式對每個drawable對象進行修改顏色值GradientDrawable gd = (GradientDrawable) drawables[i];if (gd == null) {break;}if (i == 0) {// 我們對按下的狀態做淺色處理gd.setColor(Color.rgb(155, 155, 155));} else {// 對默認狀態做深色處理gd.setColor(Color.rgb(75, 75, 75));}}// 最后總結一下,為了實現這個效果,剛開始并沒有看到setColor的方法,而是通過反射獲取GradientDrawable對象的屬性GradientState,// 再通過反射調用GradientState對象的setSolidColor方法去實現,效果不太理想。// 最后在仔仔細細一一看GradientDrawable對象的屬性,發現屬性Paint// mFillPaint,從名字就可以看出這個對象是用來繪制drawable的背景的,// 于是順著往下找,發現setColor方法,于是bingo,這個過程也是挺曲折的。} catch (NoSuchMethodException e1) {e1.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}}} </span> 方法就是這樣,我們再來看看最后的實現效果:



怎么樣,效果實現了我們需要的。

最后,貼上一個抽取出來的工具類:

import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method;import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable.ConstantState; import android.graphics.drawable.GradientDrawable; import android.graphics.drawable.StateListDrawable;public class SelectorUtils {/*** 動態修改selector中圖片的背景顏色* * @param drawable* selectorDrawable* @param rgbColors* 默認以及按下狀態的顏色值*/public static void changeViewColor(StateListDrawable drawable, int[] rgbColors) {ConstantState cs = drawable.getConstantState();if (rgbColors.length < 2) {return;}try {Method method = cs.getClass().getMethod("getChildren", null);// 通過反射調用getChildren方法獲取xml文件中寫的drawable數組method.setAccessible(true);Object obj = method.invoke(cs, null);Drawable[] drawables = (Drawable[]) obj;for (int i = 0; i < drawables.length; i++) {// 接下來我們要通過遍歷的方式對每個drawable對象進行修改顏色值GradientDrawable gd = (GradientDrawable) drawables[i];if (gd == null) {break;}if (i == 0) {// 我們對按下的狀態做淺色處理gd.setColor(rgbColors[0]);} else {// 對默認狀態做深色處理gd.setColor(rgbColors[1]);}}// 最后總結一下,為了實現這個效果,剛開始并沒有看到setColor的方法,而是通過反射獲取GradientDrawable對象的屬性GradientState,// 再通過反射調用GradientState對象的setSolidColor方法去實現,效果不太理想。// 最后在仔仔細細一一看GradientDrawable對象的屬性,發現屬性Paint// mFillPaint,從名字就可以看出這個對象是用來繪制drawable的背景的,// 于是順著往下找,發現setColor方法,于是bingo,這個過程也是挺曲折的。} catch (NoSuchMethodException e1) {e1.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}} }

有疑問歡迎留言。

總結

以上是生活随笔為你收集整理的Android中动态的更改selector中某张图片的属性的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。