Android PreferenceFragment中的对话框生成器
我正在为我的应用程序创建一个设置部分。这将作为PreferenceFragment加载到导航抽屉布局中 我有一个ListPreference,我将使用它来切换应用程序主题。一旦你从listview中选择了一个主题,我会设置一个确认对话框,询问用户是否希望重新启动应用程序以应用新主题。如果是,我将使用以下命令重新启动Utils.java中定义的应用程序:Android PreferenceFragment中的对话框生成器,android,dialog,listpreference,preferencefragment,Android,Dialog,Listpreference,Preferencefragment,我正在为我的应用程序创建一个设置部分。这将作为PreferenceFragment加载到导航抽屉布局中 我有一个ListPreference,我将使用它来切换应用程序主题。一旦你从listview中选择了一个主题,我会设置一个确认对话框,询问用户是否希望重新启动应用程序以应用新主题。如果是,我将使用以下命令重新启动Utils.java中定义的应用程序: public static void changeTheme(Activity activity, int theme) { if (n
public static void changeTheme(Activity activity, int theme)
{
if (null != activity) {
activity.finish();
activity.startActivity(new Intent(activity, activity.getClass()));
}
}
除了一个问题外,它工作得非常完美。在用户更改主题且应用程序自行重新启动后,如果用户尝试再次选择新主题而未首先手动退出并打开应用程序,则调用AlertDialog.Builder失败,我不确定原因。我在logcat中得到这个错误:
android.view.WindowManager$BadTokenException:无法添加Windows-token android.os。BinderProxy@41eec418无效;你的活动正在进行吗
创建对话框时失败:
new AlertDialog.Builder(mContext)...
我在onCreate方法中设置了mContext=getActivity,对对话框生成器的调用在onSharedPreferenceChanged中:
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
Log.e(TAG, "Preference Change!");
Log.e(TAG, "Key: " + key);
if (preferenceManager.contains(key)) {
if (key.equals(PrivateGalleryConstants.KEY_THEME)) {
final int theme = Integer.parseInt(preferenceManager.getString(key, "0"));
Log.e(TAG, "Value: " + preferenceManager.getString(key, "0"));
new AlertDialog.Builder(mContext)
.setIcon(android.R.drawable.ic_dialog_alert)
.setTitle(R.string.confirm_restart_title)
.setMessage(R.string.confirm_restart_message)
.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Utils.changeTheme(getActivity(), theme);
}
})
.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
})
.show();
}
if (key.equals(PrivateGalleryConstants.KEY_ENABLE_SECURITY))
Log.e(TAG, "Value: " + preferenceManager.getBoolean(key, false));
}
}
我不明白为什么调用AlertDialog.Builder仅在应用程序自行重新启动后才会失败。如果手动关闭应用程序,然后再次打开它,则不会发生这种情况。有没有办法解决这个问题?所以我决定只实现一个扩展的ListPreference,它处理创建确认对话框的问题,瞧,它现在工作得很好
public class ThemeListPreference extends ListPreference {
private int mClickedDialogEntryIndex;
private Context mContext;
public ThemeListPreference(Context ctxt) {
this(ctxt, null);
}
public ThemeListPreference(Context ctxt, AttributeSet attrs) {
super(ctxt, attrs);
mContext = ctxt;
setNegativeButtonText(ctxt.getString(R.string.no));
}
@Override
protected void onPrepareDialogBuilder(Builder builder) {
if (getEntries() == null || getEntries() == null) {
throw new IllegalStateException(
"ListPreference requires an entries array and an entryValues array.");
}
mClickedDialogEntryIndex = findIndexOfValue(getValue());
builder.setSingleChoiceItems(getEntries(), mClickedDialogEntryIndex,
new DialogInterface.OnClickListener() {
public void onClick(final DialogInterface dialog, final int which) {
// Save preference and close dialog
mClickedDialogEntryIndex = which;
ThemeListPreference.this.onClick(dialog, DialogInterface.BUTTON_POSITIVE);
dialog.dismiss();
new AlertDialog.Builder(mContext)
.setIcon(android.R.drawable.ic_dialog_alert)
.setTitle(R.string.confirm_restart_title)
.setMessage(R.string.confirm_restart_message)
.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
Utils.changeTheme((Activity) mContext);
}
})
.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
})
.show();
}
});
builder.setPositiveButton(null, null);
}
@Override
protected void onDialogClosed(boolean positiveResult) {
CharSequence[] mEntryValues = getEntryValues();
if (positiveResult && mClickedDialogEntryIndex >= 0 && mEntryValues != null) {
String value = mEntryValues[mClickedDialogEntryIndex].toString();
if (callChangeListener(value)) {
setValue(value);
}
}
}
}
希望这能在将来帮助别人-