una todas responde qué porque permisos ninguna las hacer detienen desea cerrarla celular aplicación aplicaciones aplicacion abre android android-support-library android-styles appcompat-v7-r22.1

android - todas - qué hacer si una aplicación no responde



La herencia de AppCompat 22.1.1 Dialog colorAccent del tema de la aplicación no funciona (4)

Estoy intentando configurar los diálogos de AppCompat para que los botones usen el mismo color que el color de acento de la aplicación, sin repetir el color en sí. Esto funcionó perfectamente con AppCompat v22 (solo para Lollipop, obviamente) usando este archivo de estilos en values-v21 :

<style name="AppTheme" parent="@style/Theme.AppCompat"> <item name="colorAccent">#FF9800</item> <item name="android:alertDialogTheme">@style/AlertDialogTheme</item> </style> <style name="AlertDialogTheme" parent="android:Theme.Material.Dialog.Alert"> <item name="android:colorAccent">?attr/colorAccent</item> </style>

Cuando se publicó AppCompat v22.1 , traté de configurarlo para todas las versiones de Android, así que moví estos estilos a la carpeta de values base y básicamente reemplacé todos los atributos específicos de android: y v21 por sus contrapartes de AppCompat.

<style name="AppTheme" parent="Theme.AppCompat"> <item name="colorAccent">#FF9800</item> <item name="alertDialogTheme">@style/AlertDialogTheme</item> </style> <style name="AlertDialogTheme" parent="Theme.AppCompat.Dialog.Alert"> <item name="colorAccent">?attr/colorAccent</item> </style>

Sin embargo, no funciona: la aplicación se bloquea cuando intenta mostrar un cuadro de diálogo de alerta. Hay algunas advertencias en logcat que sospecho que están relacionadas con el problema:

05-08 16:55:44.863 W/ResourceType﹕ Too many attribute references, stopped at: 0x7f01009e

Y la excepción es:

05-08 16:55:44.900 21301-21301/com.example.test.testaccentcolor E/AndroidRuntime﹕ FATAL EXCEPTION: main Process: com.example.test.testaccentcolor, PID: 21301 android.view.InflateException: Binary XML file line #124: Error inflating class Button at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:763) at android.view.LayoutInflater.rInflate(LayoutInflater.java:806) at android.view.LayoutInflater.rInflate(LayoutInflater.java:809) at android.view.LayoutInflater.inflate(LayoutInflater.java:504) at android.view.LayoutInflater.inflate(LayoutInflater.java:414) at android.view.LayoutInflater.inflate(LayoutInflater.java:365) at android.support.v7.app.AppCompatDelegateImplV7.setContentView(AppCompatDelegateImplV7.java:249) at android.support.v7.app.AppCompatDialog.setContentView(AppCompatDialog.java:75) at android.support.v7.app.AlertController.installContent(AlertController.java:216) at android.support.v7.app.AlertDialog.onCreate(AlertDialog.java:240) at android.app.Dialog.dispatchOnCreate(Dialog.java:373) at android.app.Dialog.show(Dialog.java:274) at android.support.v7.app.AlertDialog$Builder.show(AlertDialog.java:902) at com.example.test.testaccentcolor.MainActivity.onOptionsItemSelected(MainActivity.java:37) at android.app.Activity.onMenuItemSelected(Activity.java:2885) at android.support.v4.app.FragmentActivity.onMenuItemSelected(FragmentActivity.java:353) at android.support.v7.app.AppCompatActivity.onMenuItemSelected(AppCompatActivity.java:144) at android.support.v7.internal.view.WindowCallbackWrapper.onMenuItemSelected(WindowCallbackWrapper.java:99) at android.support.v7.app.AppCompatDelegateImplV7.onMenuItemSelected(AppCompatDelegateImplV7.java:538) at android.support.v7.internal.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:802) at android.support.v7.internal.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:153) at android.support.v7.internal.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:949) at android.support.v7.internal.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:939) at android.support.v7.internal.view.menu.MenuPopupHelper.onItemClick(MenuPopupHelper.java:187) at android.widget.AdapterView.performItemClick(AdapterView.java:305) at android.widget.AbsListView.performItemClick(AbsListView.java:1146) at android.widget.AbsListView$PerformClick.run(AbsListView.java:3053) at android.widget.AbsListView$3.run(AbsListView.java:3860) at android.os.Handler.handleCallback(Handler.java:739) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:135) at android.app.ActivityThread.main(ActivityThread.java:5254) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698) Caused by: java.lang.RuntimeException: Failed to resolve attribute at index 5 at android.content.res.TypedArray.getColorStateList(TypedArray.java:425) at android.widget.TextView.<init>(TextView.java:991) at android.widget.Button.<init>(Button.java:111) at android.widget.Button.<init>(Button.java:107) at android.support.v7.widget.AppCompatButton.<init>(AppCompatButton.java:60) at android.support.v7.widget.AppCompatButton.<init>(AppCompatButton.java:56) at android.support.v7.internal.app.AppCompatViewInflater.createView(AppCompatViewInflater.java:97) at android.support.v7.app.AppCompatDelegateImplV7.createView(AppCompatDelegateImplV7.java:782) at android.support.v7.app.AppCompatDelegateImplV7.onCreateView(AppCompatDelegateImplV7.java:810) at android.support.v4.view.LayoutInflaterCompatHC$FactoryWrapperHC.onCreateView(LayoutInflaterCompatHC.java:44) at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:725)             at android.view.LayoutInflater.rInflate(LayoutInflater.java:806)             at android.view.LayoutInflater.rInflate(LayoutInflater.java:809)             at android.view.LayoutInflater.inflate(LayoutInflater.java:504)             at android.view.LayoutInflater.inflate(LayoutInflater.java:414)             at android.view.LayoutInflater.inflate(LayoutInflater.java:365)             at android.support.v7.app.AppCompatDelegateImplV7.setContentView(AppCompatDelegateImplV7.java:249)             at android.support.v7.app.AppCompatDialog.setContentView(AppCompatDialog.java:75)             at android.support.v7.app.AlertController.installContent(AlertController.java:216)             at android.support.v7.app.AlertDialog.onCreate(AlertDialog.java:240)             at android.app.Dialog.dispatchOnCreate(Dialog.java:373)             at android.app.Dialog.show(Dialog.java:274)             at android.support.v7.app.AlertDialog$Builder.show(AlertDialog.java:902)             at com.example.test.testaccentcolor.MainActivity.onOptionsItemSelected(MainActivity.java:37)             at android.app.Activity.onMenuItemSelected(Activity.java:2885)             at android.support.v4.app.FragmentActivity.onMenuItemSelected(FragmentActivity.java:353)             at android.support.v7.app.AppCompatActivity.onMenuItemSelected(AppCompatActivity.java:144)             at android.support.v7.internal.view.WindowCallbackWrapper.onMenuItemSelected(WindowCallbackWrapper.java:99)             at android.support.v7.app.AppCompatDelegateImplV7.onMenuItemSelected(AppCompatDelegateImplV7.java:538)             at android.support.v7.internal.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:802)             at android.support.v7.internal.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:153)             at android.support.v7.internal.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:949)             at android.support.v7.internal.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:939)             at android.support.v7.internal.view.menu.MenuPopupHelper.onItemClick(MenuPopupHelper.java:187)             at android.widget.AdapterView.performItemClick(AdapterView.java:305)             at android.widget.AbsListView.performItemClick(AbsListView.java:1146)             at android.widget.AbsListView$PerformClick.run(AbsListView.java:3053)             at android.widget.AbsListView$3.run(AbsListView.java:3860)             at android.os.Handler.handleCallback(Handler.java:739)             at android.os.Handler.dispatchMessage(Handler.java:95)             at android.os.Looper.loop(Looper.java:135)             at android.app.ActivityThread.main(ActivityThread.java:5254)             at java.lang.reflect.Method.invoke(Native Method)             at java.lang.reflect.Method.invoke(Method.java:372)             at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)             at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)

Por supuesto, duplicar el valor del color (o crear un recurso de color y hacer referencia a él) funciona ... pero debido a la estructura del proyecto, lo necesito de esta manera.

En resumen: supongo que la referencia a ?attr/colorAccent está creando de alguna manera un ciclo ... pero no puedo averiguar por qué o cómo solucionarlo.

¿Algunas ideas?

Actualización: ¿Por qué necesito / quiero configurar accentColor solo en el tema?

Tenemos una biblioteca que es común a muchas aplicaciones, que define los temas "básicos" de los cuales se debe derivar el tema de la aplicación real. Así que el ejemplo anterior, que está simplificado, es en realidad más parecido a algo como esto:

<!-- Styles that are inherited by application-generated styles. --> <style name="Theme.Library.Dark" parent="@style/Theme.AppCompat"> <item name="alertDialogTheme">@style/Theme.Library.Dark.AlertDialog</item> <!-- more properties --> </style> <style name="Theme.Library.Dark.AlertDialog" parent="@style/Theme.AppCompat.Dialog.Alert"> <item name="colorAccent">?attr/colorAccent</item> <!-- more properties --> </style>

(más las variantes correspondientes para Light and Light con Dark Action Bar).

Después de esto, el proyecto de la aplicación solo debe seleccionar un tema base de la lista provista, y luego tener algo como:

<!-- Application theme --> <style name="ApplicationTheme" parent="Theme.Library.Dark"> <-- Ohter material colors --> <item name="colorAccent">#FF9800</item> </style>

Al menos, esta es la situación ideal, que funcionó antes (como @Vikram señala en su respuesta, aparentemente solo porque hay dos atributos de colorAccent diferentes).

La ventaja de este esquema es que no estoy obligado a proporcionar valores predeterminados para colorAccent en los temas de la biblioteca, ya que estos se heredan de los de base de AppCompat.

Además, si necesito crear recursos de color, necesitaría dos de ellos (para las variantes claras y oscuras) ya que los colores predeterminados no son los mismos.

Entonces, idealmente, estoy buscando una solución similar (siempre que exista una).


Basándome en la excelente respuesta de @ Vikram, terminé con esto (lo pondré para futuras referencias, en caso de que alguien esté interesado en la solución real).

Para el archivo de estilos base, en values ( nota: son preferibles diferentes archivos XML para los atributos, colores, etc. ): aquí están todos juntos para la compacidad ):

<?xml version="1.0" encoding="utf-8"?> <resources> <style name="BaseAppTheme" parent="Theme.AppCompat.Light.DarkActionBar" /> <attr name="dialogColorAccent" /> <color name="myAccentColor">#FF9800</color> <style name="AppTheme" parent="BaseAppTheme"> <item name="dialogTheme">@style/DialogTheme</item> <item name="alertDialogTheme">@style/AlertDialogTheme</item> <item name="colorAccent">@color/myAccentColor</item> <item name="dialogColorAccent">@color/myAccentColor</item> </style> <style name="DialogTheme" parent="Theme.AppCompat.Light.Dialog"> <item name="colorAccent">?attr/dialogColorAccent</item> </style> <style name="AlertDialogTheme" parent="Theme.AppCompat.Light.Dialog.Alert"> <item name="colorAccent">?attr/dialogColorAccent</item> </style> </resources>

El nuevo atributo dialogColorAccent es necesario para que pueda ser referenciado desde los estilos de diálogo. Desafortunadamente, no puede hacer referencia a colorAccent (y tampoco es posible lo contrario), por lo que ambos deben tener el mismo valor (en este caso, una referencia a un recurso de color).

Esto asegura que AlertDialogs construido con android.support.v7.app.AlertDialog.Builder use el color de acento para los botones positivo / negativo para todas las versiones de Android.

Sin embargo, se necesita un archivo adicional para algunos cuadros de diálogo (como DatePickerDialog , TimePickerDialog y ProgressDialog ) que tienen versiones de material en Lollipop pero no tienen equivalente de AppCompat hasta el momento. Por lo tanto, el siguiente archivo de estilo va en values-v21 :

<?xml version="1.0" encoding="utf-8"?> <resources> <style name="BaseAppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <item name="android:dialogTheme">@style/DialogTheme</item> </style> </resources>

Esto hará que estos nuevos diálogos tengan el color de acento también (pero solo en Lollipop, obviamente).

La solución puede parecer un poco complicada (hacer referencia a @myAccentColor del estilo AlertDialogTheme es mucho más simple :)) pero fue necesario porque se definieron varios temas en una biblioteca, y la idea era que estos temas se pueden heredar y usar con cambios mínimos.


Configuré android:textColor a @null en mi tema de diálogo y ayuda.

styles.xml

<style name="AlertDialogTheme" parent="@style/Theme.AppCompat.Light.Dialog.Alert"> <!-- Used for the buttons --> <item name="colorAccent">@color/colorAccent</item> <item name="android:textColor">@null</item> </style>

También este trick me ayuda a solucionar el problema de android:textColor para otros botones.

<style name="Button.Base.Borderless" parent="Widget.AppCompat.Button.Borderless.Colored"> <item name="android:textColor">@null</item> </style>

some_layout.xml

<Button style="@style/Button.Base.Borderless" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hint" />

Ahora el color del texto del botón es colorAccent definido en AppTheme

<style name="AppTheme" parent="@style/Theme.AppCompat.Light.NoActionBar"> <item name="colorAccent">@color/colorAccent</item> <item name="borderlessButtonStyle">@style/Button.Base.Borderless</item> <item name="alertDialogTheme">@style/AlertDialog</item> </style>


Creo que ?attr/colorAccent aquí se refiere al mismo que está intentando configurar:

<item name="colorAccent">?attr/colorAccent</item>

Puede extraer el color de acento a un atributo @color y luego usarlo tanto para el tema de la aplicación como para el tema de diálogo.

colores.xml

<color name="accent">#FF9800</color>

styles.xml

<style name="AppTheme" parent="Theme.AppCompat"> <item name="colorAccent">@color/accent</item> <item name="alertDialogTheme">@style/AlertDialogTheme</item> </style> <style name="AlertDialogTheme" parent="Theme.AppCompat.Dialog.Alert"> <item name="colorAccent">@color/accent</item> </style>


<item name="colorAccent">?attr/colorAccent</item>

Ya sabes que esto no funciona. Este es el por qué:

ssize_t ResTable::Theme::getAttribute(uint32_t resID, Res_value* outValue, uint32_t* outTypeSpecFlags) const { int cnt = 20; if (outTypeSpecFlags != NULL) *outTypeSpecFlags = 0; do { .... .... if (type == Res_value::TYPE_ATTRIBUTE) { if (cnt > 0) { cnt--; resID = te.value.data; continue; } ALOGW("Too many attribute references, stopped at: 0x%08x/n", resID); return BAD_INDEX; } .... .... } while (true); return BAD_INDEX; }

El fragmento es autoexplicativo. Tu puedes tener:

<item name="colorZ" >?attr/colorY</item>

y entonces:

<item name="colorY" >?attr/colorX</item>

.... ....

Pero encadenar atributos como este no puede tener más de 20 niveles de profundidad. Android se rinde debido a Too many attribute references...

En su caso, está configurando el valor de un atributo al intentar leer su valor actual. Android va buscando, pero encuentra otra referencia en su lugar: búsqueda interminable.

¿Por qué funcionó antes?

<style name="AppTheme" parent="@style/Theme.AppCompat"> <item name="colorAccent">#FF9800</item> <item name="android:alertDialogTheme">@style/AlertDialogTheme</item> </style> <style name="AlertDialogTheme" parent="android:Theme.Material.Dialog.Alert"> <item name="android:colorAccent">?attr/colorAccent</item> </style>

En AppTheme , está configurando el atributo colorAccent la biblioteca de colorAccent (no android: namespace). Bajo AlertDialogTheme , configura android:colorAccent para que sea compatible con android:colorAccent de la biblioteca . Es por esto que un bucle sin fin no toma forma.

?attr/colorAccent se resuelve dentro del Context que pasa al crear el AlertDialog . Por este motivo, se resuelve con <item name="colorAccent">#FF9800</item> .

Una posible solución sería definir un attr personalizado en res/values/attrs.xml :

<attr name="alertDialogColorAccent" format="reference|color"/>

Ahora, podemos inicializar este atributo bajo AppTheme :

<style name="AppTheme" parent="@style/Theme.AppCompat"> <item name="colorAccent">#FF9800</item> <item name="alertDialogColorAccent" >?attr/colorAccent</item> <item name="android:alertDialogTheme">@style/AlertDialogTheme</item> </style>

y usarlo en AlertDialogTheme :

<style name="AlertDialogTheme" parent="android:Theme.Material.Dialog.Alert"> <item name="colorAccent">?attr/alertDialogColorAccent</item> </style>

PERO, esto todavía no funcionará. Todavía crea un ciclo: colorAccent es alertDialogColorAccent y alertDialogColorAccent es colorAccent . En algún lugar a lo largo de la cadena, se debe establecer un valor de color real:

<style name="AppTheme" parent="@style/Theme.AppCompat"> <item name="colorAccent">#FF9800</item> <item name="alertDialogColorAccent" >#FF9800</item> <item name="android:alertDialogTheme">@style/AlertDialogTheme</item> </style>

Ahora, puede inicializar colorAccent con alertDialogColorAccent ya que se refiere a un valor de color real:

<style name="AlertDialogTheme" parent="android:Theme.Material.Dialog.Alert"> <item name="colorAccent">?attr/alertDialogColorAccent</item> </style>