私はAndroid.preference.DialogPreference
をXMLからインフレートしようと試みましたが、ドキュメントにはいくつかの重要な部分が欠けているようで、実際の例はどこにも見つかりません。 XMLは次のようになります(多くの順列を試しましたが、これは妥当な最小値のようです)。
<DialogPreference
Android:key="funThing" Android:title="Fun Thing"
Android:dialogLayout="@layout/fun_layout"
Android:positiveButtonText="OK"
Android:negativeButtonText="Cancel"
/>
この時点での私の推測は、DialogPreference
をサブクラス化する必要があり、直接使用しないことです。たとえば、実際の設定値をダイアログ自体の要素に関連付ける方法を見つけることができません。また、 DialogPreference.Java
へのソース を見ると、それを確認しているようです。そして、私はちょうど 公式ドキュメント がそれを「基本クラス」と呼んでいることに気づきました。しかし、少なくとも、次のN人が私よりも早くこれを理解するのに役立つ決定的な十分なソースをネット上に確立することは素晴らしいことです。
レコードの場合、ログファイルは次のようになります。
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
これは奇妙です。DialogPreference
をサブクラス化する必要があります。サブクラスは何もする必要はありません。そう
public class MyDialogPreference extends DialogPreference {
public MyDialogPreference(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
}
インスタンス化できます。古い飛行機DialogPreference
はできませんが。非常に奇妙な、彼らはまったく同じものでなければなりません。
以下に、ダイアログプリファレンスの使用方法の例を示します(前述のサブクラス化)。
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);
}
}
Preferences.xmlには以下を含める必要があります
<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"/>
含むres/valueがあります(ただし、キー名は上記で明示的に宣言することもできます)。
<string name="prefKeyResetQuests">resetQuests</string>
私のPreferenceActivityは、onPauseから実際のリセットを行います。 onStopは、押すとすぐに呼び出されるとは限らないため、遅すぎる場合があることに注意してください。
@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
}
}
または同等に、まだ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
}
}
DialogPreference
を以下のように拡張する独自のクラスを作成します。
package com.test.view;
import Android.preference.DialogPreference;
public class DialogExPreference extends DialogPreference
{
public DialogExPreference(Context oContext, AttributeSet attrs)
{
super(oContext, attrs);
}
}
以下のようにxmlファイルを変更します。
<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>
それで大丈夫です。