2012-01-09 8 views
33

Mam scenariusz, w którym chcę ustawić Drawable w zależności od zdefiniowanego motywu.Uzyskaj dostęp do zasobu zdefiniowanego w kompozycji i pliku attrs.xml android

Aby to wyjaśnić dalej, Oto co mam w kodzie:

\ res \ Wartości \ attrs.xml

<resources> 
    <declare-styleable name="AppTheme"> 
     <attr name="homeIcon" format="reference" /> 
    </declare-styleable> 
</resources> 

res \ Wartości \ styles.xml

<resources> 
    <style name="AppTheme" parent="android:style/Theme"> 
     <item name="attr/homeIcon">@drawable/ic_home</item> 
    </style> 
</resources> 

AndroidManifest.xml

<application android:label="@string/app_name" 
     android:theme="@style/AppTheme"> 
     <activity android:name=".MainActivity" android:label="@string/app_name"> 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 
       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 
    </application> 

Tak jak zauważyłeś, definiuję niestandardowy attr home i ustawiam wartość atrybutu w AppTheme.

Kiedy zdefiniowania tego atrybutu w układzie XML i spróbuj do niego dostęp to działa płynnie

<ImageView android:id="@+id/img" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_gravity="center" 
     android:src="?attr/homeIcon" /> 

i renderuje Drawable ic_home w ImageView.

Ale nie jestem w stanie dowiedzieć się, jak uzyskać dostęp do Drawable programowo.

Próbowałem to zrobić z pracy wokół, definiując uchwyt LayerList Drawable, co prowadzi do zasobu nie znaleziono wyjątku:

<?xml version="1.0" encoding="utf-8"?> 
<layer-list 
    xmlns:android="http://schemas.android.com/apk/res/android" > 
    <item 
     android:drawable="?attr/homeIcon" /> 
</layer-list> 

Podsumowanie Chcę otworzyć Drawable zdefiniowane w zdefiniowane niestandardowo Theme programowo.

Odpowiedz

64

Myślę, że można uzyskać rozciągliwej z tym kodem:

TypedArray a = getTheme().obtainStyledAttributes(R.style.AppTheme, new int[] {R.attr.homeIcon});  
int attributeResourceId = a.getResourceId(0, 0); 
Drawable drawable = getResources().getDrawable(attributeResourceId); 
a.recycle(); 
+0

Proszę ocenić to, jeśli to dla Ciebie działa. – dmaxi

+0

Dziękuję :) zadziałało! – Shardul

+0

Pracowałem dla mnie, aby ..! Dzięki! :) – DroidBee

9

Innym możliwym sposobem, aby to zrobić:

public static int getResIdFromAttribute(final Activity activity,final int attr) 
    { 
    if(attr==0) 
     return 0; 
    final TypedValue typedvalueattr=new TypedValue(); 
    activity.getTheme().resolveAttribute(attr,typedvalueattr,true); 
    return typedvalueattr.resourceId; 
    } 

ma potrzeby recyklingu niczego tutaj ...

użycie:

int drawableResId=getResIdFromAttribute(this,R.attr.homeIcon); 
Drawable drawable = getResources().getDrawable(drawableResId); 
+0

to zadziałało dla mnie. , ale dlaczego nie ma potrzeby recyklingu? –

+1

@OumideOyetoke Sprawdź dokumentację: http://developer.android.com/reference/android/util/TypedValue.html. Nie ma tam funkcji recyklingu ... –

2

Użyłem poniżej metody, aby uzyskać zasobów formularz id atrybut stylu. Następnie może być używany do przeciągania, ciąg, wymiar tak dalej.

TypedArray typedArray = context.getTheme().obtainStyledAttributes(new int[] { R.attr.attrName }); 
int resourceId = typedArray.getResourceId(0, defaultResourceId); 
typedArray.recycle(); 

okrzyki :-)

0

Oto wyniki mojego śledztwa, dotyczące tego tematu. Jeśli mamy declare-stylable, możemy przesłonić te wartości w tematach.

Do tej pory najlepszym sposobem, w jaki udało mi się je zdobyć, jest:

TypedArray a = context.getTheme().obtainStyledAttributes(R.styleable.AppTheme); 
a.getDrawable(R.styleable.AppTheme_homeIcon); 

Korzystając R.styleable.AppTheme_homeIcon jesteśmy przedstawieniu dokładnie to atrybut, który chcemy. Na przykład, jeśli mamy musiałby kilka więcej atrybutów niż możemy odwoływać się do nich w sposób następujący:

a.getColor(R.styleable.AppTheme_color,defaultValue); 
a.getDimension(R.styleable.AppTheme_width,defaultWidth); 

A jeśli w aktualnym tematem te atrybuty nie zostały zdefiniowane dostaniesz wartości domyślne i bez wyjątków.

Powiązane problemy