简体   繁体   中英

Show the sharedPreference dialog variable on settings screen

I know this is a simple thing but I can't find a way to do this right. I might have designed it wrong for all I know.

I have a PreferenceFragment that the user can navigate to using the options menu on the main fragment in my app. (My app has only 1 activity and 3 fragments.) This PreferenceFragment is the settings screen which has only 1 option. Clicking that option shows the user a dialog with the TimePicker. I use DialogPreference to show the TimePicker dialog. When the user selects a time I want to show the selected time in the settings screen.

Code below along with screenshots.

PreferenceFragment class that shows the settings screen.

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 class that shows the 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);
}
}

I get the following exception on the line mentioned in the code :

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

Scenario : I click the option on the settings screen --> DialogPreference (TimePicker) dialog opens --> Set time --> Ok --> All good --> Repeat the process --> click the option on the settings screen --> DialogPreference (TimePicker) dialog opens --> Set time --> Crash with above exception!!!

I think it tries to call getString() on the context and since the getActivity returns null it throws an exception but how else do I set the value chose by the user in the TimePicker on the SettingsFragment field?

It's been bugging me for a couple of days now. Can anyone guide me on this?

I think i can point you to the solution, otherwise you will need to post me the code in which you are updating your sharedpref. I can guess that when you are updating the prefs the listener will receive the callback while the fragment is not attached to the activity. Anyway, you can avoid the problem with this:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM