2010-01-24 8 views
17

Così mi sono guardato intorno e ho scoperto che android.R.styleable non fa più parte dell'SDK anche se è ancora documentato here.Come utilizzare getStyledAttributes (int []) con Temi interni di Android

Questo non sarebbe davvero un problema se fosse chiaramente documentato quale sia l'alternativa. Per esempio il Calendario AOSP App è ancora utilizzando il android.R.styleable

// Get the dim amount from the theme 
TypedArray a = obtainStyledAttributes(com.android.internal.R.styleable.Theme); 
lp.dimAmount = a.getFloat(android.R.styleable.Theme_backgroundDimAmount, 0.5f); 
a.recycle(); 

Così come si potrebbe ottenere il backgroundDimAmount senza ottenere il int[] da android.R.styleable.Theme?

Cosa devo inserire in obtainStyledAttributes(int []) per farlo funzionare con l'SDK?

+0

Lo stesso problema esiste con il tutorial Galleria, ho visto soluzioni che rendono il lavoro tutorial, ma nessuna spiegazione di come il tutorial dovrebbe essere fissata utilizzando solo le classi SDK e non aggiungendo il proprio xml con lo stylable in esso. Il tutorial è su http://developer.android.com/resources/tutorials/views/hello-gallery.html il codice è nel "ImageAdapter (Context c)" Costruttore – AGrunewald

+0

Ecco una discussione simile http://stackoverflow.com/q/8793183/1307690 – Lemberg

risposta

12

Il CustomView API demo mostra come recuperare gli attributi stile. Il codice per la vista è qui:

https://github.com/android/platform_development/blob/master/samples/ApiDemos/src/com/example/android/apis/view/LabelView.java

L'array styleable utilizzato per recuperare il testo, il colore e la dimensione è definita nella sezione <declare-styleable> qui:

https://github.com/android/platform_development/blob/master/samples/ApiDemos/res/values/attrs.xml#L24

È possibile utilizzare <declare-styleable> per definire qualsiasi elenco di attributi che si desidera recuperare come gruppo, contenente sia i propri che quelli definiti dalla piattaforma.

Per quanto riguarda questi elementi nella documentazione, c'è molto java doc attorno agli array di stili che li rende utili nella documentazione, quindi sono stati lasciati lì. Tuttavia, man mano che gli array cambiano, ad esempio aggiungendo nuovi attributi, i valori delle costanti possono cambiare, quindi quelli della piattaforma non possono essere nell'SDK (e per favore non usare trucchi per tentare di accedervi). Non ci dovrebbe essere alcun bisogno di usare quelli della piattaforma, perché sono tutti lì solo per l'implementazione di parti del framework, ed è banale creare il proprio come mostrato qui.

+2

Grazie per le informazioni, aiuta un bel po '. Per quanto ne capisca uno crea, Xml Styleable con es. un attributo è "android: backgroundDimAmount" che consente all'app di recuperare i dati corretti. Riguardo alle cose presenti nell'SDK. Capisco che ci sia un sacco di documentazione preziosa, ma una spiegazione del perché la classe sia nel documento SDK e non nel vero e proprio SDK nel riferimento API potrebbe chiarire le cose per gli sviluppatori in futuro, dal momento che ci sono ancora tutorial che lo fanno sbagliato: http://developer.android.com/intl/zh-CN/resources/tutorials/views/hello-gallery.html – AGrunewald

+0

@hackbod Il primo link nella risposta è obsoleto. – Pang

4

Questo sembra essere un bug nell'SDK. Ho archiviato uno issue su di esso, che si potrebbe desiderare di stelle in modo da ricevere aggiornamenti su di esso.

Come worksaround, è possibile utilizzare la reflection per accedere al campo:

Class clazz=Class.forName("android.R$styleable"); 
int i=clazz.getField("Theme_backgroundDimAmount").getInt(clazz); 
+0

Bene, secondo Dianne Hackborn, è stato intenzionalmente rimosso dall'SDK nascondendolo. Qui la discussione su di esso http://groups.google.com/group/android-developers/tree/browse_frm/thread/6554c6688f3ca6d9/8d018aa3f5c2beb9?rnum=1&_done=%2Fgroup%2Fandroid-developers%2Fbrowse_frm%2Fthread%2F6554c6688f3ca6d9% 3Ftvc% 3D1% 26 # doc_72f29c1df624bbed Quindi c'è un modo per farlo correttamente senza usare la riflessione? – AGrunewald

+0

Se intenzionalmente è andato, non dovresti usarlo. Le applicazioni interne (ad es. Calendar) possono usarlo, perché non sono limitate all'utilizzo dell'SDK. Oltre a questo, non ho consigli, mi dispiace. Ho aggiornato il problema per cercare di ottenere delle risposte. – CommonsWare

+2

Grazie, sono d'accordo che non dovrei usarlo ma poi dovrebbe esserci un'alternativa. E il Tutorial di Gallery View avrebbe dovuto essere aggiornato molto tempo fa, dal momento che mostra ancora quel codice. – AGrunewald

13

Nell'esempio, hanno lasciato il riferimento alla Context 'c':

public ImageAdapter(Context c) { 
    mContext = c; 
    TypedArray a = c.obtainStyledAttributes(R.styleable.GalleryPrototype); 
    mGalleryItemBackground = a.getResourceId(
      R.styleable.GalleryPrototype_android_galleryItemBackground, 0); 
    a.recycle(); 
} 

Modifica obtainStyledAttributes a c.obtainStyledAttributes dovrebbero lavorare

+2

So che questo arriva tardi, ma questa è la risposta giusta !!! –

7

Esempio di tirare fuori attributo standard (sfondo) in un vista personalizzata che ha il suo stile predefinito. In questo esempio la vista personalizzata PasswordGrid estende GridLayout. Ho specificato uno stile per PasswordGrid che imposta un'immagine di sfondo usando l'attributo android standard android: background.

public class PasswordGrid extends GridLayout { 

    public PasswordGrid(Context context) { 
     super(context); 
     init(context, null, 0); 
    } 

    public PasswordGrid(Context context, AttributeSet attrs) { 
     super(context, attrs, R.attr.passwordGridStyle); 
     init(context, attrs, 0); 
    } 

    public PasswordGrid(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
     init(context, attrs, defStyle); 
    } 

    private void init(Context context, AttributeSet attrs, int defStyle) { 
     if (!isInEditMode()) { 

      TypedArray stdAttrs = context.obtainStyledAttributes(attrs, 
        new int[] { android.R.attr.background }, // attribute[s] to access 
        defStyle, 
        R.style.PasswordGridStyle); // Style to access 

      // or use any style available in the android.R.style file, such as 
      //  android.R.style.Theme_Holo_Light 

      if (stdAttrs != null) { 
       Drawable bgDrawable = stdAttrs.getDrawable(0); 
       if (bgDrawable != null) 
        this.setBackground(bgDrawable); 
       stdAttrs.recycle(); 
      } 
     } 
    } 

Ecco parte dei miei stili.file xml:

<declare-styleable name="passwordGrid"> 
    <attr name="drawOn" format="color|reference" /> 
    <attr name="drawOff" format="color|reference" /> 
    <attr name="pathWidth" format="integer" /> 
    <attr name="pathAlpha" format="integer" /> 
    <attr name="pathColor" format="color" /> 
</declare-styleable> 



    <style name="PasswordGridStyle" parent="@android:style/Widget.GridView" > 
     <!-- Style custom attributes. --> 
     <item name="drawOff">@drawable/ic_more</item> 
     <item name="drawOn">@drawable/ic_menu_cut</item> 
     <item name="pathWidth">31</item> 
     <item name="pathAlpha">129</item> 
     <item name="pathColor">@color/green</item> 

     <!-- Style standard attributes --> 
     <item name="android:background">@drawable/pattern_bg</item> 
</style>