PreferenceActivity e il tema non applicare
-
26-09-2019 - |
Domanda
Ciao a tutti ho posto il tema nel file manifesto in questo modo:
android:theme="@android:style/Theme.Light"
Ma ho un problema nelle preferenze attività, nelle preferenze principali del tema mostra BENE, ma se riesco a un sub preferenza, il tema diventa disordinato, non è bianco come dovrebbe, è tutto buio, e il tipo di carattere è nero quindi non è possibile vedere molto, e quando inizio cliccando su un qualsiasi elemento che riceveranno volte bianco come dovrebbero, ma Ripristina presto nero dopo. Questo è solo accade su 2,1, sia il dispositivo vero e emulatore. Testato su l'emulatore in esecuzione 1.6 ed è stato lavorare correttamente. Ecco parte del codice del file delle preferenze xml:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceScreen
android:title="@string/account">
<CheckBoxPreference
android:key="enable_account"
android:title="@string/account_use"
android:summary="@string/account_summ" />
<EditTextPreference
android:key="username"
android:title="@string/login"
android:dependency="enable_account"
android:summary="@string/login_summ" />
<EditTextPreference
android:key="password"
android:title="@string/password"
android:dependency="enable_account"
android:summary="@string/password_summ"
android:password="true" />
</PreferenceScreen>
Ed ecco uno screenshot:
alcuna soluzione alternativa?
Soluzione
Qualcuno ha appena pubblicato una soluzione alternativa a http://code.google. com / p / android / temi / dettaglio? id = 4611
In poche parole, migliori schermi livello di preferenza sembra riconoscere il tema, ma non quelli annidati. Quindi la soluzione consiglia di creare livello superiore PreferenceActivity per nidificato PREFERENCE e quindi invocando questa nuova attività con intento:
<PreferenceScreen android:key="key1"
android:title="1 Item"
android:summary="">
<intent android:action="android.intent.action.VIEW"
android:targetPackage="com.example"
android:targetClass="com.example.PreferenceActivity2"/>
</PreferenceScreen>
I non ha dovuto applicare il tema ad altro che l'applicazione stessa.
Altri suggerimenti
È inoltre possibile utilizzare questa tecnica per sovrascrivere gli stili degli schermi delle preferenze interne:
@Override
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,
Preference preference) {
super.onPreferenceTreeClick(preferenceScreen, preference);
if (preference != null) {
if (preference instanceof PreferenceScreen) {
if (((PreferenceScreen) preference).getDialog() != null) {
((PreferenceScreen) preference)
.getDialog()
.getWindow()
.getDecorView()
.setBackgroundDrawable(
this
.getWindow()
.getDecorView()
.getBackground()
.getConstantState()
.newDrawable()
);
}
}
}
return false;
}
Questo codice si applica lo stile della schermata delle preferenze principale al schermata delle preferenze fatto clic.
Finalmente ho trovato il modo di cambiare il tema di "PreferenceActivity" a livello di codice (codice tramite java)
Per cambiare il tema solo fare in questo modo:
@Override
public void onCreate(Bundle savedInstanceState) {
setTheme(R.style.Holo_Theme_Light);
super.onCreate(savedInstanceState);
}
Sempre chiamata di metodo setTheme(R.style.yourtheme);
prima metodo super.onCreate(savedInstanceState);
. In questo modo si produrrà risultato, come mostrato di seguito.
Questo è tutto.
Se yo chiamata di metodo setTheme(R.style.yourtheme);
dopo che il metodo super.onCreate(savedInstanceState);
che produrrà risultato come illustrato di seguito.
Nota: i temi non sono riconoscono dai PREFERENCE nidificato. Per applicare tema che PREFERENCE nidificate si deve fare un altro PreferenceActivity per quella annidata metodo PREFERENCE e call setTheme(R.style.yourtheme);
lì.
Questo sembra essere un bug. Vedere http://code.google.com/p/android/issues/ dettaglio? id = 4611
C'è una soluzione ancora più semplice, se stai bene con l'utilizzo di quello che sembra la magia nera per ottenere questo risultato ...
Guardando la fonte di PreferenceScreen#showDialog(Bundle)
, vediamo che la finestra di dialogo viene creata usando la risorsa tema ottenuta tramite mContext.getThemeResId()
, che viene poi utilizzato in un ContextThemeWrapper
.
Questo può aiutarci in modo sostanziale, perché il Context
utilizzato nel PreferenceScreen
è in realtà il nostro PreferenceActivity
, quindi tutto quello che dobbiamo fare è l'override del metodo getThemeResId()
(che è nascosto dalla API pubblica), per fornire il nostro tema personalizzato, e il sub-PREFERENCE ora utilizza qualsiasi risorsa tema personalizzato che volevamo!
/**
* This is a hack to provide our own theme for the PreferenceScreen's dialog.
*
* @see android.preference.PreferenceScreen#showDialog(Bundle)
*/
public int getThemeResId() {
return R.style.Theme_MyApp_PreferenceScreen;
}
Si noti che poiché questo metodo viene annotato con @hide
, non possiamo usare l'annotazione @Override
che normalmente utilizzabile in questo caso; e anche noi non possiamo chiamare il metodo super.getThemeResId()
. Se davvero, davvero vuole essere in grado di ignorare condizionale presente e chiamata attraverso il super-implementazione come ripiego, si dovrà utilizzare la riflessione per ottenere il metodo del super applicazione:
try {
((Object) this).getClass().getMethod("getThemeResId").invoke(this);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}