【问题标题】:Show the sharedPreference dialog variable on settings screen在设置屏幕上显示 sharedPreference 对话框变量
【发布时间】:2015-11-16 00:57:41
【问题描述】:

我知道这是一件简单的事情,但我找不到正确的方法。据我所知,我可能设计错了。

我有一个 PreferenceFragment,用户可以使用我的应用程序主片段上的选项菜单导航到它。 (我的应用只有 1 个活动和 3 个片段。) 此 PreferenceFragment 是只有 1 个选项的设置屏幕。单击该选项会向用户显示一个带有 TimePicker 的对话框。我使用 DialogPreference 来显示 TimePicker 对话框。 当用户选择时间时,我想在设置屏幕中显示所选时间。

下面的代码以及屏幕截图。

显示设置屏幕的 PreferenceFragment 类。

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

显示 TimePicker 的 TimePreference 类

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

场景: 我单击设置屏幕上的选项 --> DialogPreference (TimePicker) 对话框打开 --> 设置时间 --> 确定 --> 一切正常 --> 重复该过程 --> 单击选项在设置屏幕上 --> DialogPreference (TimePicker) 对话框打开 --> 设置时间 --> 崩溃并出现上述异常!!!

我认为它会尝试在上下文中调用 getString() 并且由于 getActivity 返回 null 它会引发异常,但是我该如何设置用户在 SettingsFragment 字段的 TimePicker 中选择的值?

这几天一直困扰着我。有人可以指导我吗?

【问题讨论】:

    标签: android android-fragments sharedpreferences preferencefragment dialog-preference


    【解决方案1】:

    我想我可以为您指出解决方案,否则您需要将更新 sharedpref 的代码发布给我。我可以猜到,当您更新首选项时,侦听器将在片段未附加到活动时收到回调。无论如何,你可以避免这个问题:

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

    【讨论】:

    • 感谢您的回复。我发布的代码包含我正在更新 sharedPrefs 的代码。当用户在 TimePicker 上更改时间并单击“确定”时调用 onSharedPreferenceChanged,这反过来又调用了您正确提到的未附加到活动的 setDisplayTime。但是,当我所做的只是抛出一个 Dialog 时,为什么它是超然的,这让我感到困惑。其次,在您建议的解决方案中,isMenuVisible() 是什么?这是您希望我创建并检查对话框可见性的方法吗?如果是这样,那么它总是错误的,因为此时对话框已经关闭。
    • 我发布的方法是片段默认方法,用于检查菜单当前是否对用户可见(如果片段已解除,则返回 false)。一旦不再需要片段,它就会从活动中分离出来,但它会存储在片段管理器中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多