para - manual de programacion android pdf
Nuevo tema incorrecto de biblioteca de soporte de preferencias en tiempo de ejecución (1)
El problema, al que se enfrentan, está relacionado con el Context
y cómo funciona su tematización. Su código recupera un contexto al pasar getActivity()
al constructor, sin embargo, este no es el contexto que desea. Aquí está la solución que aplica los estilos correctos:
final Context ctx = getPreferenceManager().getContext();
for (...) {
final ListPreference p = new ListPreference(ctx);
// [...]
category.addPreference(p);
}
Explicación
Aquí está el método onCreate(...)
de PreferenceFragmentCompat
:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TypedValue tv = new TypedValue();
this.getActivity().getTheme().resolveAttribute(attr.preferenceTheme, tv, true);
int theme = tv.resourceId;
if(theme <= 0) {
throw new IllegalStateException("Must specify preferenceTheme in theme");
} else {
this.mStyledContext = new ContextThemeWrapper(this.getActivity(), theme);
this.mPreferenceManager = new PreferenceManager(this.mStyledContext);
// [...]
this.onCreatePreferences(savedInstanceState, rootKey);
}
}
Las líneas importantes:
this.getActivity().getTheme().resolveAttribute(attr.preferenceTheme, tv, true);
int theme = tv.resourceId;
Aquí el tema de preferenceTheme
se recupera del tema de la actividad. Si existe (es decir, el theme
no es 0), PFC ( PreferenceFragmentCompat
) crea un nuevo contenedor de temas que contendrá las informaciones de estilo:
this.mStyledContext = new ContextThemeWrapper(this.getActivity(), theme);
Con este contexto estilizado, el PFC ahora puede crear el PreferenceManager
:
this.mPreferenceManager = new PreferenceManager(this.mStyledContext);
El estilo de raíz de este PFC es ahora el preferenceTheme
que contiene todos los diferentes subestilos ( preferenceStyle
por ejemplo).
El problema con su solución es que la clase Preference
está buscando un atributo preferenceStyle
en el contexto del contructor-passed. Sin embargo, solo está definido en su preferenceTheme
, no en el tema de la Actividad.
Estoy intentando usar la nueva biblioteca de soporte de Preference v14. Para dar un estilo material a las preferencias, utilizo el siguiente estilo en mi Actividad:
<style name="PreferenceTheme" parent="@style/Theme.AppCompat.Light.DarkActionBar">
<item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
</style>
Eso funciona bien Mi problema es que cuando agrego nuevas Preferencias en el tiempo de ejecución, se infla con un tema viejo. Aquí hay una captura de pantalla del resultado:
Como puede ver, la primera preferencia, agregada a través de XML, tiene el nuevo estilo Material, mientras que las otras no.
¿Tienes alguna pista sobre cómo resolver el problema?
EDITAR Aquí hay un ejemplo de código que uso para agregar la preferencia en Runtime:
import android.support.v7.preference.ListPreference;
for (...) {
final ListPreference p = new ListPreference(getActivity());
p.setTitle(name);
p.setSummary(langname);
p.setEntryValues(langEntryValues);
p.setEntries(langDisplayValues);
p.setDialogTitle(R.string.select_language);
category.addPreference(p);
}
PD: el mismo comportamiento ocurre con android.support.v7.preference.Preference