2010-01-24 8 views
17

Así que he mirado alrededor y descubrí que android.R.styleable ya no forma parte del SDK aunque todavía está documentado here.¿Cómo utilizo getStyledAttributes (int []) con Temas internos de Android

Eso realmente no sería un problema si se documentara claramente cuál es la alternativa. Por ejemplo, la aplicación Calendario AOSP sigue utilizando el 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(); 

Entonces, ¿cómo podría uno obtener la backgroundDimAmount sin obtener el int[] de android.R.styleable.Theme?

¿Qué debo incluir en obtainStyledAttributes(int []) para que funcione con el SDK?

+0

El mismo problema existe con el tutorial Galería Ver, he visto soluciones que hacen el trabajo tutorial, pero ninguna explicación de por qué el tutorial tendría que ser fijado usando sólo las clases SDK y no añadir su propio xml con el estilo en él. El tutorial se encuentra en http://developer.android.com/resources/tutorials/views/hello-gallery.html el código está en el constructor "ImageAdapter (Context c)" – AGrunewald

+0

Aquí hay una discusión similar http://stackoverflow.com/q/8793183/1307690 – Lemberg

Respuesta

12

La demo API CustomView muestra cómo recuperar los atributos de estilo. El código para la vista está aquí:

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

La matriz styleable utilizado para recuperar el texto, el color y el tamaño se define en la sección <declare-styleable> aquí:

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

Se puede utilizar <declare-styleable> para definir cualquier lista de atributos que desee recuperar como grupo, que contenga tanto los suyos como los definidos por la plataforma.

En cuanto a estas cosas que figuran en la documentación, hay una gran cantidad de documentación de Java alrededor de las matrices de estilo que los hace útiles para tener en la documentación, por lo que se han dejado allí. Sin embargo, a medida que las matrices cambian, como cuando se agregan nuevos atributos, los valores de las constantes pueden cambiar, por lo que los de la plataforma no pueden estar en el SDK (y no use ningún truco para intentar acceder a ellos). No debería haber necesidad de usar los de plataforma de todos modos, porque están allí solo para la implementación de partes del marco, y es trivial crear uno propio como se muestra aquí.

+2

Gracias por la información, ayuda bastante. Por lo que tengo entendido, uno crea Xml Styleable con, por ejemplo, un atributo es "android: backgroundDimAmount" que permite a la aplicación recuperar los datos correctos. Con respecto a las cosas que están en el SDK. Entiendo que hay una gran cantidad de documentación valiosa, pero una explicación de por qué la clase está en el documento SDK y no en el SDK real en la referencia de API podría aclarar las cosas para los desarrolladores en el futuro, ya que todavía hay tutoriales que lo hacen incorrecto: http://developer.android.com/intl/zh-CN/resources/tutorials/views/hello-gallery.html – AGrunewald

+0

@hackbod El primer enlace en la respuesta está desactualizado. – Pang

4

Esto parece ser un error en el SDK. He archivado un issue en él, que es posible que desee destacar para recibir actualizaciones al respecto.

Como worksaround, se puede utilizar la reflexión para acceder al campo:

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

Bueno, según Dianne Hackborn, fue intencionalmente eliminado del SDK escondiéndolo. Aquí la discusión al respecto 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 Entonces, ¿hay alguna manera de hacerlo correctamente sin usar el reflejo? – AGrunewald

+0

Si se ha ido intencionalmente, no deberías estar usándolo. Las aplicaciones internas (por ejemplo, Calendario) pueden usarlo, ya que no están restringidas al uso del SDK. Más allá de eso, no tengo ningún consejo, lo siento. He actualizado el problema para tratar de obtener algunas respuestas. – CommonsWare

+2

Gracias, ya acepto que no debería usarlo, pero debería haber una alternativa. Y el tutorial de vista de galería debería haberse actualizado hace mucho tiempo, ya que todavía muestra ese código. – AGrunewald

13

En el ejemplo, que quedan fuera de la referencia al contexto '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(); 
} 

Cambio obtainStyledAttributes a c.obtainStyledAttributes deben trabajar

+2

Sé que llega tarde, ¡pero esta es la respuesta correcta! –

7

Ejemplo de sacar atributo estándar (fondo) en una vista personalizada que tiene su propio estilo predeterminado. En este ejemplo, la vista personalizada PasswordGrid se extiende a GridLayout. Especifiqué un estilo para PasswordGrid que establece una imagen de fondo con el atributo android estándar 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(); 
      } 
     } 
    } 

Aquí hay parte de mis estilos.archivo 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> 
Cuestiones relacionadas