style - ¿Cómo utilizo obtención de atributos de estilo(int[]) con temas internos de Android?
styles android studio (4)
Ejemplo de extracción de atributo estándar (fondo) en una vista personalizada que tiene su propio estilo predeterminado. En este ejemplo, la vista personalizada PasswordGrid extiende GridLayout . Especifiqué un estilo para PasswordGrid que establece una imagen de fondo usando el atributo estándar de Android 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í es parte de mi archivo styles.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>
Así que miré a mi alrededor y descubrí que android.R.styleable
ya no forma parte del SDK, aunque todavía está documentado here .
Eso realmente no sería un problema si se documentara claramente cuál es la alternativa. Por ejemplo, la aplicación de calendario AOSP todavía está utilizando 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 se podría obtener backgroundDimAmount
sin obtener el int[]
de android.R.styleable.Theme
?
¿Qué tengo que seguir en el campo de obtainStyledAttributes(int [])
para que funcione con el SDK?
En el ejemplo, omitieron 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();
}
El cambio de applyStyledAttributes por c.obtainStyledAttributes debería funcionar
Esto parece ser un error en el SDK. He presentado un issue en él, que tal vez desee iniciar para recibir actualizaciones al respecto.
Como solución, puede utilizar la reflexión para acceder al campo:
Class clazz=Class.forName("android.R$styleable");
int i=clazz.getField("Theme_backgroundDimAmount").getInt(clazz);
La demostración de CustomView API muestra cómo recuperar atributos con estilo. El código para la vista está aquí:
La matriz de estilo utilizada para recuperar el texto, el color y el tamaño se define en la sección <declare-styleable>
aquí:
Puede usar <declare-styleable>
para definir cualquier lista de atributos que desee recuperar como un grupo, que contenga los suyos y los definidos por la plataforma.
En cuanto a estas cosas en la documentación, hay una gran cantidad de documentos java en torno a los arreglos de estilo que hacen que sea útil tenerlos en la documentación, por lo que se han dejado allí. Sin embargo, a medida que cambian los arreglos, como los nuevos atributos que se agregan, los valores de las constantes pueden cambiar, por lo que los de plataforma no pueden estar en el SDK (y por favor no utilice ningún truco para intentar acceder a ellos). No debería haber necesidad de usar los de plataforma de todos modos, ya que están allí solo para la implementación de partes del marco, y es trivial crear el suyo como se muestra aquí.