0

Я знаю, что это простая вещь, но я не могу найти способ сделать это правильно. Возможно, я разработал это неправильно для всего, что я знаю.Показать переменную диалога sharedPreference на экране настроек

У меня есть PreferenceFragment, который пользователь может перейти к использованию меню опций основного фрагмента в моем приложении. (Мое приложение имеет только 1 активность и 3 фрагмента.) Этот PreferenceFragment - это экран настроек, который имеет только 1 вариант. Нажатие этой опции показывает пользователю диалог с TimePicker. Я использую DialogPreference для отображения диалогового окна TimePicker. Когда пользователь выбирает время, я хочу показать выбранное время на экране настроек.

Код ниже вместе со скриншотами.

Класс предпочтений, который показывает экран настроек.

public class SettingsFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener { 
private static final String TAG = SettingsFragment.class.getSimpleName(); 
private static String mDisplayTime; 

@Override 
public void onCreate(final Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    // Load the preferences from an XML resource 
    addPreferencesFromResource(R.xml.preferences); 
} 

@Override 
public void onActivityCreated(final Bundle savedInstanceState) { 
    super.onActivityCreated(savedInstanceState); 
    mDisplayTime = Utils.getAlarmTime(getActivity()).toString(); 
} 

@Override 
public void onResume() { 
    super.onResume(); 
    final Preference preferenceFragment = getPreferenceScreen().findPreference("pref_set_time"); 
    setDisplayTime(); 
    preferenceFragment.setSummary(mDisplayTime); 
} 

@Override 
public void onSharedPreferenceChanged(final SharedPreferences sharedPreferences, final String key) { 
    Log.d(TAG, "SharedPreferences changed"); 
    if (key.equals(Utils.PREFERENCE_TIME_KEY)) { 
     mDisplayTime = sharedPreferences.getString(Utils.PREFERENCE_TIME_KEY, null); 
     setDisplayTime(); //CALL TO THIS METHOD CAUSES EXCEPTION BELOW 
    } 
} 

private void setDisplayTime() { 
    final DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern("HH:mm"); 
    final String time = TextUtils.isEmpty(mDisplayTime) ? getString(R.string.not_set) : dateTimeFormatter.print(
      new DateTime(mDisplayTime)); 
    //EXCEPTION THROWN in the below line 
    //java.lang.IllegalStateException: Fragment SettingsFragment{200ac3eb} not attached to Activity 
    mDisplayTime = getString((R.string.pref_set_reminder_time_summary), time); 
} 
} 
класс

TimePreference, который показывает TimePicker

public class TimePreference extends DialogPreference implements TimePicker.OnTimeChangedListener { 
private DateTime mTime; 

@Override 
public View onCreateDialogView() { 
    mTime = Utils.getAlarmTime(getContext()); //Gets the time from the sharedPreferences 
    final int hour; 
    final int min; 
    if (mTime == null) { 
     hour = DateTime.now().getHourOfDay(); 
     min = DateTime.now().getMinuteOfHour(); 
    } else { 
     hour = mTime.getHourOfDay(); 
     min = mTime.getMinuteOfHour(); 
    } 

    final TimePicker mTimePicker = new TimePicker(getContext()); 
    mTimePicker.setOnTimeChangedListener(this); 
    mTimePicker.setCurrentHour(hour); 
    mTimePicker.setCurrentMinute(min); 

    return mTimePicker; 
} 

@Override 
public void onDialogClosed(final boolean positiveResult) { 
    if (positiveResult) { 
     persistString(mTime.toString()); 
    } 
} 

@Override 
public void onTimeChanged(final TimePicker timePicker, final int hourOfDay, final int minute) { 
    mTime = new DateTime(DateTime.now().getYear(), DateTime.now().getMonthOfYear(), DateTime.now().getDayOfMonth(), 
      hourOfDay, minute); 
} 
} 

я получаю следующее исключение на линии, указанной в коде:

java.lang.IllegalStateException: Fragment SettingsFragment{200ac3eb} not attached to Activity 

Сценарий: я нажимаю опцию настройки экран -> Диалоговое окно (TimePicker) открывается -> Установить время -> ОК ->Все хорошее -> Repe в процессе -> щелкните по опции на экране настроек -> Диалоговое окно (TimePicker) откроется -> Установить время -> Сбой с превышением исключения !!!

Я думаю, что он пытается вызвать getString() в контексте, и поскольку getActivity возвращает null, он генерирует исключение, но как еще установить значение, выбранное пользователем в TimePicker в поле SettingsFragment?

Это уже прослушивало пару дней. Может ли кто-нибудь помочь мне в этом?

ответ

0

Я думаю, что могу указать вам на решение, иначе вам нужно будет отправить мне код, в котором вы обновляете свой sharedpref. Я могу догадаться, что когда вы обновляете prefs, слушатель получит обратный вызов, пока фрагмент не будет присоединен к активности. В любом случае, вы можете избежать проблем с этим:

private void setDisplayTime() { 
    if (isMenuVisible()) { 
     final DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern("HH:mm"); 
     final String time = TextUtils.isEmpty(mDisplayTime) ? getString(R.string.not_set) : dateTimeFormatter.print(
      new DateTime(mDisplayTime)); 
     mDisplayTime = getString((R.string.pref_set_reminder_time_summary), time); 
    } 
} 
+0

благодарит за отзыв. Код, который я опубликовал, содержит код, в котором я обновляю sharedPrefs. onSharedPreferenceChanged вызывается, когда пользователь меняет время на TimePicker и нажимает OK, что, в свою очередь, вызывает setDisplayTime, о котором вы правильно говорите, не привязано к активности. Но почему это отделилось, когда все, что я делаю, это вызвать диалог, что меня озадачивает. Во-вторых, в предложенном вами решении, что такое isMenuVisible()? Это метод, который вы хотите мне создать и проверить видимость диалога? Если это так, оно всегда будет ложным, так как диалог уже закрыт на этом этапе. – LeoNeo

+0

метод, который я опубликовал, представляет собой метод по умолчанию для фрагмента, чтобы проверить, отображается ли в данный момент меню пользователю (возврат false, если фрагмент обработан). Фрагмент отделяется от активности, как только он больше не нужен, но он будет храниться на сервере-фрагментаторе. – iGio90

Смежные вопросы