Estoy buscando escribir preferencias que se puedan aplicar a dispositivos 3.0 y pre-3.0. Descubriendo que PreferenceActivity
contiene métodos obsoletos (aunque estos se usan en el código de muestra adjunto), miré PreferenceFragement
y el paquete de compatibilidad para resolver mis problemas.
Sin embargo, parece que PreferenceFragment
no está en el paquete de compatibilidad. ¿Alguien puede decirme si esto fue intencional? Si es así, ¿puedo apuntar fácilmente a un rango de dispositivos (es decir, <3.0 y> = 3.0) o tendré que saltar a través de aros? Si no se excluyó intencionalmente, ¿podemos esperar una nueva versión del paquete de compatibilidad? ¿O hay otra solución alternativa que sea segura de usar?
Salud
James
PreferenceFragment
que olvidará incluso está allí. Mira mi respuesta ."Because most of Preferences' implementation is hidden, therefore impossible to backport without lots of hackery."
PreferenceFragmentCompat
fue agregado recientemente a la biblioteca de soporte.Respuestas:
Los métodos en desuso están en desuso a partir de Android 3.0. Están perfectamente bien en todas las versiones de Android, pero la dirección es usarlo
PreferenceFragment
en Android 3.0 y superior.Supongo que es una cuestión de tiempo de ingeniería, pero eso es solo una suposición.
Considero que se hace "fácilmente". Tenga dos
PreferenceActivity
implementaciones separadas , una con encabezados de preferencia yPreferenceFragments
otra con el enfoque original. Elija el correcto en el punto que necesita (por ejemplo, cuando el usuario hace clic en el elemento del menú de opciones). Aquí hay un proyecto de muestra que demuestra esto. O bien, tenga un únicoPreferenceActivity
que maneje ambos casos, como en este proyecto de muestra .Lo descubrirá cuando el resto de nosotros lo sepa, es decir, si se envía.
Véase más arriba.
fuente
<include>
funcione con XML de preferencia. Por cierto, si está suscrito, la actualización del libro que hace referencia a este proyecto se anunció hace unos minutos.La sutil implicación de la respuesta de @CommonsWare es que su aplicación debe elegir entre la API de compatibilidad o la API de fragmentos incorporada (desde SDK 11 más o menos). De hecho, eso es lo que ha hecho la recomendación "fácilmente". En otras palabras, si desea usar PreferenceFragment, su aplicación debe usar la API de fragmentos incorporada y tratar con los métodos obsoletos en PreferenceActivity. Por el contrario, si es importante que su aplicación use la compatibilidad. API se enfrentará a no tener una clase PreferenceFragment en absoluto. Por lo tanto, la orientación de dispositivos no es un problema, pero el salto de aro ocurre cuando tiene que elegir una u otra API y, por lo tanto, enviar su diseño a soluciones imprevistas. Necesito el compat. API, así que voy a crear mi propia clase PreferenceFragment y ver cómo funciona. En el peor de los casos, yo '
EDITAR: ¿Después de intentar y mirar el código en http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.0.1_r1/android/preference/PreferenceFragment.java? av = h - crear mi propio PreferenceFragment no va a suceder. Parece que el uso liberal de package-private en PreferenceManager en lugar de 'protegido' es el bloqueador principal. Realmente no parece que haya seguridad o una buena motivación para haberlo hecho, y no es genial para las pruebas unitarias, pero bueno ... menos escribir, supongo ...
EDITAR v2: En realidad sucedió y funcionó. Definitivamente fue un dolor de cabeza hacer que el código funcionara con el JAR de API de compatibilidad. Tuve que copiar alrededor del 70% del paquete com.android.preference del SDK a mi aplicación y luego luchar con un código Java típicamente de calidad mediocre en Android. Usé la v14 del SDK. Hubiera sido mucho más fácil para un ingeniero de Goog hacer lo que hice, al contrario de lo que escuché decir algunos ingenieros líderes de Android sobre este tema.
Por cierto, ¿dije "apuntar a dispositivos no es un problema"? Es totalmente ... si usa com.android.preference no podrá cambiar con la API de compatibilidad sin una refactorización importante. Registro de diversión!
fuente
Sobre la base de la respuesta de CommonsWare, así como las observaciones de Tenacious, se me ocurrió una única solución de clase descendiente capaz de apuntar a todas las versiones actuales de la API de Android con un mínimo alboroto y sin duplicación de código o recurso. Consulte mi respuesta a la pregunta relacionada aquí: PreferenceActivity Android 4.0 y versiones anteriores
o en mi blog: http://www.blackmoonit.com/2012/07/all_api_prefsactivity/
Probado en dos tabletas con 4.0.3 y 4.0.4, así como en un teléfono con 4.0.4 y 2.3.3 y también en un emulador con 1.6.
fuente
Ver PreferenceFragment-Compat de Machinarius. Fue fácil entrar con gradle y olvido que incluso está allí.
compile 'com.github.machinarius:preferencefragment:0.1.1'
Actualización importante: la última revisión del
v7 support library
ahora tiene un PreferenceFragmentCompat nativo .fuente
En agosto de 2015, Google lanzó la nueva Biblioteca de soporte de preferencias v7 .
Ahora puede usar PreferenceFragmentCompat con cualquiera
Activity
oAppCompatActivity
Tienes que configurar
preferenceTheme
tu tema:De esta forma, puede personalizar el
preferenceTheme
estilo de los diseños utilizados para cada tipo de preferencia sin afectar otras partes de su Actividad.fuente
La respuesta de Tenacious es correcta, pero aquí hay algunos detalles más.
La razón por la que no puede "crear un diseño normal y vincular los componentes de la vista a las preferencias compartidas manualmente" es que hay algunas omisiones sorprendentes en la API android.preferences. PreferenceActivity y PreferenceFragment tienen acceso a métodos críticos de PreferenceManager no públicos, sin los cuales no puede implementar una IU de preferencias propia.
En particular, para construir una jerarquía de Preferencias a partir de un archivo XML, debe usar un PreferenceManager, pero todos los constructores de PreferenceManager son privados de paquetes u ocultos. El método de adjuntar los oyentes Preference onClick a su actividad también es privado de paquete.
Y no puede evitar esto poniendo disimuladamente su implementación en el paquete android.preferences, porque los métodos no públicos en las API de Android en realidad se omiten del SDK. Con un poco de creatividad que implica reflexión y proxies dinámicos, aún puede llegar a ellos. La única alternativa, como dice Tenacious, es bifurcar todo el paquete android.preference, que incluye al menos 15 clases, 5 diseños y una cantidad similar de elementos style.xml y attrs.xml.
Entonces, para responder la pregunta original, la razón por la que Google no incluyó PreferenceFragment en el paquete de compatibilidad es que habrían tenido exactamente la misma dificultad que Tenacious y yo. Incluso Google no puede retroceder en el tiempo y hacer públicos esos métodos en las plataformas antiguas (aunque espero que lo hagan en futuras versiones).
fuente
El objetivo de mi aplicación es API +14, pero debido al uso de la biblioteca de soporte para una navegación sofisticada, no pude usarlo
android.app.Fragment
y tuve que usarloandroid.support.v4.app.Fragment
, pero también necesitaba tenerloPreferenceFragment
sin grandes cambios en el código.Entonces, mi solución fácil para tener ambos mundos de biblioteca de soporte y
PreferenceFragment
:fuente
Necesitaba integrar las preferencias en el diseño de la aplicación y mantener el soporte para Android 2.3. Entonces todavía necesitaba PreferencesFragment.
Después de algunas búsquedas encontré android-support-v4-preferenciafragment lib. Esta lib ahorra mucho tiempo para copiar y refactorizar el PreferencesFragment original como dijo Tenacious. Funciona bien y los usuarios disfrutan de sus preferencias.
fuente