2014-12-31 2 views
1

Я в процессе создания раздела настроек для своего приложения. Это загружается в макет навигационного ящика как PreferenceFragment.Dialog Builder in 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: Невозможно добавить окно - маркер [email protected] не действует; работает ли ваша деятельность?

Это неудачу при создании диалога:

new AlertDialog.Builder(mContext)... 

я поставил mContext = getActivity() в OnCreate метод и вызов диалога строитель в 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 завершается неудачей только после того, как приложение было перезапущено само по себе (это не происходит, если вы закрываете приложение вручную, а затем открываете его снова). Есть идеи, как это исправить?

ответ

0

Итак, я решил, что я просто реализую расширенный ListPreference, который занимается созданием диалогового окна подтверждения и voila, теперь он отлично работает.

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); 
      } 
     } 
    } 
} 

Надеется, что это может помочь кому-то еще в будущем ;-)