android - textappearance - Lea los atributos del tema más nuevo en la plataforma anterior
themes android gratis (3)
Estoy operando bajo la presunción de que cuando se compilan los estilos de Android, las constantes de atributo son las que se usan para las claves y, por lo tanto, en teoría deberían poder leerse en cualquier plataforma de alguna manera.
Posiblemente, aunque no es así como estoy interpretando el código fuente de C ++ que genera el error que está viendo. Consulte ResTable::Theme::applyStyle()
en frameworks/base/libs/utils/ResourceTypes.cpp
.
Mi interpretación es que Android tiene lo que equivale a una tabla en memoria de paquetes-> tipos-> entradas posibles:
numEntries = curPI->types[t].numEntries;
Su índice de entrada es más alto que la entrada más alta conocida:
if (e >= numEntries) {
LOGE("Style contains key with bad entry: 0x%08x/n", attrRes);
bag++;
continue;
}
Es posible que manejen esto diferente para los paquetes de android
frente a otros: android
usa valores conocidos en el momento de la compilación del firmware (y su índice de entrada generado es mayor, porque proviene de una plataforma más nueva), los que no son de android
asumen que cualquier cosa es válida.
Si mi conjetura es correcta, lo que quieres hacer no funcionará. Dicho esto, mis días en C ++ están seriamente en mi espejo retrovisor, por lo que puedo estar malinterpretando lo que estoy viendo.
Estoy tratando de leer los valores de los atributos de los temas y estilos que fueron diseñados para plataformas que son más nuevas de las que ejecuto mi aplicación.
Por favor, no preguntes por qué. Si sabes algo sobre las bibliotecas que escribo, entonces ya deberías saber que me gusta impulsar las capacidades de la plataforma :)
Estoy operando bajo la presunción de que cuando se compilan los estilos de Android, las constantes de atributo son las que se usan para las claves y, por lo tanto, en teoría deberían poder leerse en cualquier plataforma de alguna manera. Esto es lo que he observado que sucede con los XML de diseño en mis otras bibliotecas sin problemas.
Aquí hay un caso de prueba de base que muestra el problema. Esto se debe compilar con Android 3.0+.
<resources>
<style name="Theme.BreakMe">
<item name="android:actionBarStyle">@style/Widget.BreakMe</item>
</style>
<style name="Widget.BreakMe" parent="android:Widget">
<item name="android:padding">20dp</item>
</style>
</resources>
El hecho de que esto use android:actionBarStyle
específicamente es irrelevante. Todo lo que debe entenderse es que es un atributo que solo estaba disponible comenzando con Android 3.0.
Esta es la forma en que he intentado acceder a estos valores hasta ahora en plataformas anteriores a Android 3.0 .
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Break Me"
style="?android:attr/actionBarStyle"
/>
y
<declare-styleable name="Whatever">
<item name="datStyle" format="reference" />
</declare-styleable>
<style name="Theme.BreakMe.Take2">
<item name="datStyle">?android:attr/actionBarSize</item>
</style>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Break Me"
style="?attr/datStyle"
/>
y
TypedValue outValue = new TypedValue();
context.getTheme().resolveAttribute(android.R.attr.actionBarStyle, outValue, true);
y
int[] Theme = new int[] { android.R.attr.actionBarSize };
int Theme_actionBarSize = 0;
TypedArray a = context.obtainStyledAttributes(attrs, Theme);
int ref = a.getResourceId(Theme_actionBarSize, 0);
y
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ActionBar, android.R.attr.actionBarStyle, 0);
Todos ellos dan como resultado este error en LogCat:
E/ResourceType(5618): Style contains key with bad entry: 0x010102ce
La constante 0x010102ce
es el valor de atributo de android.R.attr.actionBarStyle
que parece indicar que la plataforma está rechazando el atributo antes de que pueda tener la oportunidad de acceder a su valor.
Estoy buscando cualquier otra forma de leer atributos como este del tema. Estoy bastante seguro de que una vez que obtenga la referencia de estilo no tendré problemas para leer sus atributos.
¿Hay alguna forma posible de hacer esto?
Probablemente, debes definir algunos temas. Para dispositivos antiguos use la carpeta res / values-v11 / themes.xml. Consulte la sección "Uso de Holo mientras admite Android 2.x" en http://android-developers.blogspot.com/2012/01/holo-everywhere.html
Tal vez me falta el objetivo final aquí, pero armé el siguiente ejemplo que fue capaz de leer todos los atributos sin problema en cualquier dispositivo 2.x. El ejemplo fue compilado contra un 3.0 targetSdk.
styles.xml ( declara los estilos y temas)
<resources>
<style name="Theme.NewFeatures" parent="android:Theme">
<item name="android:actionBarStyle">@style/Widget.MyActionBar</item>
</style>
<style name="Widget.MyActionBar" parent="android:Widget">
<item name="android:padding">20dp</item>
</style>
</resources>
attrs.xml ( declare los grupos de atributos que desea obtener en tiempo de ejecución)
<resources>
<declare-styleable name="ActionBarNewFeatures">
<attr name="android:actionBarStyle" />
</declare-styleable>
<declare-styleable name="MyWidgetNewFeatures">
<attr name="android:padding" />
</declare-styleable>
</resources>
AndroidManifest.xml (aplicar el tema personalizado)
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/Theme.NewFeatures" >
<activity
android:name=".SomeActivity"
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>
SomeActivity.java (Ir a cavar para los atributos)
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TypedArray a = obtainStyledAttributes(R.styleable.ActionBarNewFeatures);
//Get the style ID for the widget
int resid = a.getResourceId(R.styleable.ActionBarNewFeatures_android_actionBarStyle, -1);
a.recycle();
a = obtainStyledAttributes(resid, R.styleable.MyWidgetNewFeatures);
int padding = a.getDimensionPixelSize(R.styleable.MyWidgetNewFeatures_android_padding, -1);
a.recycle();
TextView tv = new TextView(this);
tv.setText(String.format("Padding will be %d px", padding));
setContentView(tv);
}
Siempre y cuando compile el ejemplo contra 3.0 para que pueda resolver todos los nombres de atributo; en cada dispositivo / emulador 2.X tengo esto correctamente leído en el tema y luego en el estilo de widget para obtener la dimensión de relleno escalado que había establecido.
Espero no haber perdido algo grande.