【问题标题】:Dialog Builder in PreferenceFragmentPreferenceFragment 中的对话框生成器
【发布时间】:2014-12-31 10:48:47
【问题描述】:

我正在为我的应用创建设置部分。这作为 PreferenceFragment 加载到导航抽屉布局中。

我有一个 ListPreference,我将使用它来切换应用程序主题。从列表视图中选择主题后,我会设置一个确认对话框,询问用户是否希望重新启动应用程序以应用新主题。如果是,我使用以下命令重新启动在 Utils.java 中定义的应用程序:

public static void changeTheme(Activity activity, int theme)
{
    if (null != activity) {
        activity.finish();
        activity.startActivity(new Intent(activity, activity.getClass()));
    }
}

除了 1 个问题外,这很完美。在用户更改主题并且应用程序自行重新启动后,如果用户尝试再次选择新主题而没有先手动退出并打开应用程序,则对 AlertDialog.Builder 的调用将失败,我不确定原因。我在 logcat 中收到此错误:

android.view.WindowManager$BadTokenException: 无法添加窗口——令牌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 的调用才会失败(如果您手动关闭应用程序然后再次打开它,则不会发生这种情况)。任何想法如何解决这个问题?

【问题讨论】:

    标签: android dialog listpreference preferencefragment


    【解决方案1】:

    所以我决定只实现一个扩展的 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);
                }
            }
        }
    }
    

    希望这可能会在未来对其他人有所帮助;-)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-07-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-06
      • 1970-01-01
      • 1970-01-01
      • 2012-07-11
      相关资源
      最近更新 更多