Tenía problemas para usar la nueva barra de herramientas de Material Design en la biblioteca de soporte en una pantalla de Preferencias.
Tengo un archivo settings.xml como se muestra a continuación:
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory
android:title="@string/AddingItems"
android:key="pref_key_storage_settings">
<ListPreference
android:key="pref_key_new_items"
android:title="@string/LocationOfNewItems"
android:summary="@string/LocationOfNewItemsSummary"
android:entries="@array/new_items_entry"
android:entryValues="@array/new_item_entry_value"
android:defaultValue="1"/>
</PreferenceCategory>
</PreferenceScreen>
Las cadenas se definen en otro lugar.
Respuestas:
Encuentre el repositorio de GitHub: aquí
Un poco tarde para la fiesta, pero esta es mi solución que estoy usando como una solución para continuar usando
PreferenceActivity
:settings_toolbar.xml :
SettingsActivity.java :
Result :
ACTUALIZACIÓN (compatibilidad con pan de jengibre):
Según los comentarios, los dispositivos Gingerbread están devolviendo NullPointerException en esta línea:
REPARAR:
SettingsActivity.java :
¡Cualquier problema con lo anterior, avíseme!
ACTUALIZACIÓN 2: SOLUCIÓN DE TINTADO
Como se señaló en muchas notas de desarrollo,
PreferenceActivity
no es compatible con el tinte de elementos, sin embargo, al utilizar algunas clases internas, PUEDE lograrlo. Eso es hasta que se eliminen estas clases. (Funciona con appCompat support-v7 v21.0.3).Agregue las siguientes importaciones:
Luego anule el
onCreateView
método:Result:
AppCompat 22.1
AppCompat 22.1 introdujo nuevos elementos tintados, lo que significa que ya no es necesario utilizar las clases internas para lograr el mismo efecto que la última actualización. En su lugar, siga esto (aún anulando
onCreateView
):PANTALLAS DE PREFERENCIAS ANIDADAS
Mucha gente está experimentando problemas al incluir la barra de herramientas en un
<PreferenceScreen />
, sin embargo, he encontrado una solución. - ¡Después de mucho ensayo y error!Agregue lo siguiente a su
SettingsActivity
:La razón que
PreferenceScreen
son tan molestos es porque se basan como un diálogo contenedor, por lo que necesitamos capturar el diseño del diálogo para agregarle la barra de herramientas.Sombra de la barra de herramientas
Por diseño, la importación
Toolbar
no permite la elevación y el sombreado en dispositivos anteriores a la v21, por lo que si desea tener elevación en suToolbar
, debe envolverlo en unAppBarLayout
:settings_toolbar.xml
:Sin olvidar agregar la biblioteca Add the Design Support como una dependencia en el
build.gradle
archivo:Android 6.0
Investigué el problema de superposición informado y no puedo reproducirlo.
El código completo en uso como arriba produce lo siguiente:
Si me falta algo, hágamelo saber a través de este repositorio e investigaré.
fuente
Puede utilizar a
PreferenceFragment
, como alternativa aPreferenceActivity
. Entonces, aquí está elActivity
ejemplo de envoltura :Y aquí está el archivo de diseño (pref_with_actionbar):
Y finalmente el
PreferenceFragment
:Espero que esto ayude a alguien.
fuente
ActionBarActivity
para obtener la barra de herramientas y las funciones relacionadas, no habrá ningún tipoonBuildHeaders()
de anulación ni soporte de preferencias reales en la actividad. Si usa el antiguoPreferenceActivity
, no tiene la barra de herramientas y las funciones relacionadas (sí, puede tener unToolbar
diseño y pero no puede llamarsetSupportActionBar()
. Entonces, ya sea con encabezados de preferencia o pantallas de preferencia anidadas, parece que estamos atascados.Actualización completamente nueva.
Con algo de experimentación, parece que he encontrado la solución AppCompat 22.1+ funcional para pantallas de preferencias anidadas.
Primero, como se menciona en muchas respuestas (incluida una aquí), deberá usar el nuevo
AppCompatDelegate
. Utilice elAppCompatPreferenceActivity.java
archivo de las demostraciones de soporte ( https://android.googlesource.com/platform/development/+/58bf5b99e6132332afb8b44b4c8cedf5756ad464/samples/Support7Demos/src/com/example/android/supportv7/app/app/AppCompatPva simplemente referencia) de él, o copie las funciones relevantes en la suyaPreferenceActivity
. Mostraré el primer enfoque aquí:El diseño adjunto es bastante simple y habitual (
layout/settings_page.xml
):Las preferencias en sí mismas se definen como de costumbre (
xml/settings.xml
):No hay una diferencia real con las soluciones en la red hasta este momento. En realidad, puede usar esto incluso si no tiene pantallas anidadas, ni encabezados, solo una pantalla.
Usamos un común
PreferenceFragment
para todas las páginas más profundas, diferenciado por losextra
parámetros en los encabezados. Cada página tendrá un XML separado con unPreferenceScreen
interior común (xml/settings_page1.xml
et al.). El fragmento utiliza el mismo diseño que la actividad, incluida la barra de herramientas.Finalmente, un breve resumen de cómo funciona esto realmente. Lo nuevo
AppCompatDelegate
nos permite usar cualquier actividad con las funciones de AppCompat, no solo las que se extienden desde las actividades que se encuentran realmente en AppCompat. Esto significa que podemos convertir lo buenoPreferenceActivity
en uno nuevo y agregar la barra de herramientas como de costumbre. A partir de ese momento, podemos ceñirnos a las viejas soluciones en cuanto a pantallas de preferencias y encabezados, sin desviarse de la documentación existente. Solo hay un punto importante: no lo useonCreate()
en la actividad porque dará lugar a errores. UtilizaronBuildHeaders()
para todas las operaciones, como agregar la barra de herramientas.La única diferencia real es que, y eso es lo que lo hace funcionar con pantallas anidadas, es que puede usar el mismo enfoque con los fragmentos. Puede usarlos de
onCreateView()
la misma manera, inflando su propio diseño en lugar del sistema, agregando la barra de herramientas de la misma manera que en la actividad.fuente
R.drawable.abc_ic_ab_back_mtrl_am_alpha
PreferenceFragmentCompat
lugar dePreferenceFragment
. Configurar unpreference-header
conxmlns:app="http://schemas.android.com/apk/res-auto"
y luego enapp:fragment
lugar deandroid:fragment
no carga ninguna nueva pantalla de preferencias. Entonces, ¿tiene problemas con la compatibilidad con versiones anteriores ... sugerencias?Si desea utilizar PreferenceHeaders, puede utilizar el siguiente enfoque:
layout / activity_settings.xml
Puede usar el diseño que prefiera aquí, solo asegúrese de ajustarlo también en el código Java.
Y finalmente, su archivo con encabezados (xml / pref_headers.xml)
fuente
android.R.id.content
, considerando que solíamos pasar unListView
conandroid.R.id.list
para la lista de preferencias en sí (y aún lo hacemos si usamos la forma sin fragmentos, sin encabezado) en su lugar.Con el lanzamiento de Android Support Library 22.1.0 y el nuevo AppCompatDelegate, aquí puede encontrar una buena muestra de una implementación de PreferenceActivity con soporte de material con compatibilidad con versiones anteriores.
Actualizar también funciona en pantallas anidadas.
https://android.googlesource.com/platform/development/+/marshmallow-mr3-release/samples/Support7Demos/src/com/example/android/supportv7/app/AppCompatPreferenceActivity.java
fuente
Si bien las respuestas anteriores parecen elaboradas, si desea una solución de solución rápida para usar la barra de herramientas con soporte API 7 y superior mientras se extiende
PreferenceActivity
, obtuve ayuda de este proyecto a continuación.https://github.com/AndroidDeveloperLB/ActionBarPreferenceActivity
activity_settings.xml
SettingsActivity.java
fuente
Yo también he estado buscando una solución para agregar la barra de herramientas de soporte v7 ( API 25 ) a AppCompatPreferenceActivity (que es creada automáticamente por AndroidStudio al agregar una SettingsActivity). Después de leer varias soluciones y probar cada una de ellas, luché para que los ejemplos de PreferenceFragment generados se mostraran también con una barra de herramientas.
Una solución modificada que funcionó fue de " Gabor ".
Una de las advertencias a las que me enfrenté fue que 'onBuildHeaders' solo se activa una vez. Si gira un dispositivo (como un teléfono) hacia los lados, la vista se vuelve a crear y PreferenceActivity se vuelve a dejar sin una barra de herramientas, sin embargo, PreferenceFragments conservaría la suya.
Intenté usar 'onPostCreate' para llamar a 'setContentView', mientras que esto funcionaba para recrear la barra de herramientas cuando cambiaba la orientación, PreferenceFragments se mostraba en blanco.
Lo que se me ocurrió aprovecha casi todos los consejos y respuestas que pude leer sobre este tema. Espero que otros también lo encuentren útil.
Empezaremos con Java
Primero en (el generado) AppCompatPreferenceActivity.java modifiqué 'setSupportActionBar' así:
En segundo lugar , creé una nueva clase llamada AppCompatPreferenceFragment.java (actualmente es un nombre sin usar, ¡aunque puede que no permanezca así!):
Esta es la parte de la respuesta de Gabor que funcionó.
Por último , para obtener coherencia, debemos realizar algunos cambios en SettingsActivity.java :
Se ha dejado algún código fuera de la actividad por brevedad. Los componentes clave aquí son ' onAttachedFragment ', ' onPostCreate ', y que 'GeneralPreferenceFragment' ahora extiende el ' AppCompatPreferenceFragment ' personalizado en lugar de PreferenceFragment.
Resumen de código : si hay un fragmento, el fragmento inyecta el nuevo diseño y llama a la función modificada 'setSupportActionBar'. Si el fragmento no está presente, SettingsActivity inyecta el nuevo diseño en 'onPostCreate'
Ahora pasemos al XML (muy simple):
activity_settings.xml :
app_bar_settings.xml :
content_settings.xml :
Resultado final :
fuente
Tengo una solución nueva (posiblemente más ordenada), que utiliza las
AppCompatPreferenceActivity
muestras de Support v7. Con este código en la mano, creé mi propio diseño que incluye una barra de herramientas:Luego, en mi
AppCompatPreferenceActivity
, modifiquésetContentView
para crear mi nuevo diseño y coloqué el diseño proporcionado dentro de miFrameLayout
:Luego simplemente extiendo
AppCompatPreferenceActivity
, permitiéndome llamarsetSupportActionBar((Toolbar) findViewById(R.id.toolbar))
e inflar los elementos del menú en la barra de herramientas también. Todo ello manteniendo los beneficios de aPreferenceActivity
.fuente
Mantengamos las cosas simples y limpias aquí, sin romper ningún diseño incorporado
fuente
root.getChildAt(0);
regresanull
.Encontré esta solución simple mientras trabajaba en esto. Primero necesitamos crear un diseño para la actividad de configuración.
activity_settings.xml
Asegúrese de agregar una vista de lista con
android:id="@android:id/list"
, de lo contrario arrojaráNullPointerException
El siguiente paso es agregar el
onCreate
método (Anular) en su actividad de configuraciónSettings.java
Asegúrese de importar
android.suppoer.v7.widget.Toolbar
. Esto debería funcionar prácticamente en todas las API por encima de 16 (Jelly Bean y superiores)fuente
Me gustaría continuar con la solución marcada de James Cross, ya que después de eso hay un problema de cerrar solo la pantalla anidada activa (PreferenceFragment) en la forma de no cerrar la SettingsActivity también.
En realidad funciona en todas las pantallas anidadas (así que no entiendo la solución de Gábor que probé sin éxito, bueno, funciona hasta cierto punto pero es un lío de múltiples barras de herramientas), porque cuando el usuario hace clic en una pantalla de subpreferencia , solo se cambia el fragmento (ver
<FrameLayout android:id="@+id/content_frame" .../>
) no la barra de herramientas que permanece siempre activa y visible, sino debe implementar un comportamiento personalizado para cerrar cada fragmento en consecuencia.En la clase principal
SettingsActivity
que se extiendeActionBarActivity
, se deben implementar los siguientes métodos. Tenga en cuenta quesetupActionBar()
se llama a privado desdeonCreate()
Para el título de la pantalla anidada elegida, debe obtener la referencia de su barra de herramientas y establecer el título apropiado con
toolbar.setTitle(R.string.pref_title_general);
(por ejemplo).No es necesario implementar el
getSupportActionBar()
en todo el PreferenceFragment ya que solo se cambia la vista del fragmento en cada confirmación, no la barra de herramientas;No es necesario crear una clase ToolbarPreference falsa para agregar en cada preferencia.xml (ver la respuesta de Gábor).
fuente
Aquí hay una biblioteca que hice que se basa en el código AOSP, que agrega tinte tanto a las preferencias como a los cuadros de diálogo, agrega una barra de acción y es compatible con todas las versiones de API 7:
https://github.com/AndroidDeveloperLB/MaterialPreferenceLibrary
fuente
PreferenceScreen
interiorPreferenceScreen
como esteBueno, esto sigue siendo un problema para mí hoy (18 de noviembre de 2015). Probé todas las soluciones de este hilo, pero hubo dos cosas principales que no pude resolver:
Así que terminé creando una biblioteca con una solución más complicada. Básicamente, tuve que aplicar estilos internamente a las preferencias si estamos usando un dispositivo anterior a Lollipop y también manejé las pantallas anidadas usando un fragmento personalizado (restaurando toda la jerarquía anidada aprovechando la clave PreferenceScreen ).
La biblioteca es esta: https://github.com/ferrannp/material-preferences
Y si está interesado en el código fuente (demasiado largo para publicarlo aquí), este es básicamente el núcleo del mismo: https://github.com/ferrannp/material-preferences/blob/master/library/src/main/ java / com / fnp / materialpreferences / PreferenceFragment.java
fuente