0

これは簡単なことですが、これを正しく行う方法が見つかりません。私が知っている限り、私はそれを間違って設計したかもしれません。

ユーザーがアプリのメイン フラグメントのオプション メニューを使用してナビゲートできる 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) ダイアログが開きます --> 時刻を設定します --> OK --> 問題ありません -->プロセスを繰り返します --> 設定画面でオプションをクリックします - -> DialogPreference (TimePicker) ダイアログが開きます --> 時刻を設定します --> 上記の例外でクラッシュします!!!

コンテキストで getString() を呼び出そうとすると思いますが、getActivity が null を返すため、例外がスローされますが、SettingsFragment フィールドの TimePicker でユーザーが選択した値を設定するにはどうすればよいですか?

ここ数日、私を悩ませています。誰でもこれについて私を案内できますか?

4

1 に答える 1

0

解決策を教えていただけると思います。それ以外の場合は、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); 
    }
}
于 2015-11-16T04:05:33.110 に答える