J'ai essayé d'utiliser un Android.preference.DialogPreference
gonflé à partir de XML, mais la documentation semble manquer de quelques bits essentiels, et je ne trouve aucun exemple de travail nulle part. Mon XML ressemble maintenant à ceci (j'ai essayé de nombreuses permutations mais cela semble être un minimum raisonnable):
<DialogPreference
Android:key="funThing" Android:title="Fun Thing"
Android:dialogLayout="@layout/fun_layout"
Android:positiveButtonText="OK"
Android:negativeButtonText="Cancel"
/>
Ma supposition à ce stade est qu'il est nécessaire de sous-classer DialogPreference
et de ne pas l'utiliser directement. D'une part, je ne peux pas trouver un moyen d'associer la valeur de préférence réelle à un élément dans la boîte de dialogue elle-même, qui à la réflexion est une sorte de cadeau. Et aussi, en regardant la source de DialogPreference.Java
semble le confirmer. Et je viens également de remarquer que la documentation officielle le désigne comme une "classe de base". Mais au moins, ce serait bien d'établir une source définitive sur le net qui aiderait les prochains N à comprendre cela plus rapidement que moi.
Pour mémoire, le fichier journal ressemble à ceci:
I/ActivityManager( 61): Starting: Intent { cmp=org.jeremy.Android/.PreferencesActivity } from pid 2755
W/Resources( 2755): Converting to string: TypedValue{t=0x10/d=0x4b0 a=-1}
W/Resources( 2755): Converting to string: TypedValue{t=0x10/d=0x20 a=-1}
D/AndroidRuntime( 2755): Shutting down VM
W/dalvikvm( 2755): threadid=1: thread exiting with uncaught exception (group=0x40015560)
E/AndroidRuntime( 2755): FATAL EXCEPTION: main
E/AndroidRuntime( 2755): Java.lang.RuntimeException: Unable to start activity ComponentInfo{org.jeremy.Android/org.jeremy.Android.PreferencesActivity}: Android.view.InflateException: Binary XML file line #28: Error inflating class Java.lang.reflect.Constructor
E/AndroidRuntime( 2755): at Android.app.ActivityThread.performLaunchActivity(ActivityThread.Java:1647)
E/AndroidRuntime( 2755): at Android.app.ActivityThread.handleLaunchActivity(ActivityThread.Java:1663)
E/AndroidRuntime( 2755): at Android.app.ActivityThread.access$1500(ActivityThread.Java:117)
E/AndroidRuntime( 2755): at Android.app.ActivityThread$H.handleMessage(ActivityThread.Java:931)
E/AndroidRuntime( 2755): at Android.os.Handler.dispatchMessage(Handler.Java:99)
E/AndroidRuntime( 2755): at Android.os.Looper.loop(Looper.Java:123)
E/AndroidRuntime( 2755): at Android.app.ActivityThread.main(ActivityThread.Java:3683)
E/AndroidRuntime( 2755): at Java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime( 2755): at Java.lang.reflect.Method.invoke(Method.Java:507)
E/AndroidRuntime( 2755): at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:839)
E/AndroidRuntime( 2755): at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:597)
E/AndroidRuntime( 2755): at dalvik.system.NativeStart.main(Native Method)
E/AndroidRuntime( 2755): Caused by: Android.view.InflateException: Binary XML file line #28: Error inflating class Java.lang.reflect.Constructor
E/AndroidRuntime( 2755): at Android.preference.GenericInflater.createItem(GenericInflater.Java:397)
E/AndroidRuntime( 2755): at Android.preference.GenericInflater.onCreateItem(GenericInflater.Java:417)
E/AndroidRuntime( 2755): at Android.preference.GenericInflater.createItemFromTag(GenericInflater.Java:428)
E/AndroidRuntime( 2755): at Android.preference.GenericInflater.rInflate(GenericInflater.Java:481)
E/AndroidRuntime( 2755): at Android.preference.GenericInflater.rInflate(GenericInflater.Java:493)
E/AndroidRuntime( 2755): at Android.preference.GenericInflater.inflate(GenericInflater.Java:326)
E/AndroidRuntime( 2755): at Android.preference.GenericInflater.inflate(GenericInflater.Java:263)
E/AndroidRuntime( 2755): at Android.preference.PreferenceManager.inflateFromResource(PreferenceManager.Java:251)
E/AndroidRuntime( 2755): at Android.preference.PreferenceActivity.addPreferencesFromResource(PreferenceActivity.Java:262)
E/AndroidRuntime( 2755): at org.jeremy.Android.PreferencesActivity.onCreate(PreferencesActivity.Java:40)
E/AndroidRuntime( 2755): at Android.app.Instrumentation.callActivityOnCreate(Instrumentation.Java:1047)
E/AndroidRuntime( 2755): at Android.app.ActivityThread.performLaunchActivity(ActivityThread.Java:1611)
E/AndroidRuntime( 2755): ... 11 more
E/AndroidRuntime( 2755): Caused by: Java.lang.InstantiationException: Android.preference.DialogPreference
E/AndroidRuntime( 2755): at Java.lang.reflect.Constructor.constructNative(Native Method)
E/AndroidRuntime( 2755): at Java.lang.reflect.Constructor.newInstance(Constructor.Java:415)
E/AndroidRuntime( 2755): at Android.preference.GenericInflater.createItem(GenericInflater.Java:383)
E/AndroidRuntime( 2755): ... 22 more
W/ActivityManager( 61): Force finishing activity org.jeremy.Android/.PreferencesActivity
W/ActivityManager( 61): Force finishing activity org.jeremy.Android/.SplashActivity
Celui-ci est bizarre, vous devez sous-classer DialogPreference
. La sous-classe n'a rien à faire. Alors
public class MyDialogPreference extends DialogPreference {
public MyDialogPreference(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
}
peut être instancié. Alors qu'un avion ancien DialogPreference
ne peut pas. Très bizarre, ils devraient être exactement la même chose.
Voici un exemple d'utilisation de la préférence de dialogue (sous-classement comme vous l'avez mentionné).
package dk.myapp.views;
import Android.content.Context;
import Android.preference.DialogPreference;
import Android.util.AttributeSet;
/**
* The OptionDialogPreference will display a dialog, and will persist the
* <code>true</code> when pressing the positive button and <code>false</code>
* otherwise. It will persist to the Android:key specified in xml-preference.
*/
public class OptionDialogPreference extends DialogPreference {
public OptionDialogPreference(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onDialogClosed(boolean positiveResult) {
super.onDialogClosed(positiveResult);
persistBoolean(positiveResult);
}
}
Le fichier preferences.xml doit contenir
<dk.myapp.views.OptionDialogPreference
Android:key="@string/prefKeyResetQuests"
Android:dialogIcon="@Android:drawable/ic_dialog_alert"
Android:title="Reset Quests"
Android:summary="Reset all quest-progress."
Android:dialogMessage="Are you sure you wish to reset your quest progress? This action cannot be undone!"
Android:positiveButtonText="Clear Quests"
Android:negativeButtonText="Cancel"/>
J'ai un res/value contenant (bien que le nom de clé puisse également être déclaré explicitement ci-dessus).
<string name="prefKeyResetQuests">resetQuests</string>
My PreferenceActivity effectue la réinitialisation réelle de onPause. Notez que l'onStop peut être trop tard car onStop ne sera pas toujours appelé immédiatement après avoir appuyé sur:
@Override
public void onPause() {
SharedPreferences prefs = Android.preference.PreferenceManager.
getDefaultSharedPreferences(getBaseContext());
if(prefs.getBoolean(
getResources().getString(R.string.prefKeyResetQuests), false)) {
// apply reset, and then set the pref-value back to false
}
}
Ou de manière équivalente puisque nous sommes toujours dans la PreferenceActivity:
@Override
protected void onPause() {
Preference prefResetQuests =
findPreference(getResources().getString(R.string.prefKeyResetQuests));
if(prefResetQuests.getSharedPreferences().
getBoolean(prefResetQuests.getKey(), false)){
// apply reset, and then set the pref-value back to false
}
}
Créez votre propre classe qui étend DialogPreference
comme ci-dessous:
package com.test.view;
import Android.preference.DialogPreference;
public class DialogExPreference extends DialogPreference
{
public DialogExPreference(Context oContext, AttributeSet attrs)
{
super(oContext, attrs);
}
}
Modifiez le fichier xml comme ci-dessous:
<PreferenceScreen
xmlns:Android="http://schemas.Android.com/apk/res/Android">
<com.test.view.DialogExPreference
Android:title="@string/title"
Android:dialogMessage="@string/lite"
Android:negativeButtonText="test"/>
</PreferenceScreen>
Alors c'est bon.