SavedInstanceState 不为空但为空

SavedInstanceState is not null but is empty

我有一个 ViewPager,其中包含用户输入不同输入的一些片段。其中一个片段包含 DatePickerTimePicker,我将其存储(当用户选择日期和时间时)作为 Joda LocalDateLocalTime.

我想保存日期和时间,以便即使用户在片段之间滑动也能保持输入。这是我的代码:

@Override
public void onSaveInstanceState(Bundle outState) {
    if (selectedDate != null && selectedTime != null) {
        outState.putString("date", selectedDate.toString());
        outState.putString("time", selectedTime.toString());
        super.onSaveInstanceState(outState);
    }
}

在我的 onCreateView 中:

if (savedInstanceState != null){
    Log.d("mylog", savedInstanceState.getString("date");
    currentDate = LocalDate.parse(savedInstanceState.getString("date"));
    currentTime = LocalTime.parse(savedInstanceState.getString("time"));
    selectedDateTv.setText(currentDate.toString("dd/MM/yyyy"));
    selectedTimeTv.setText(currentTime.toString("HH:mm"));
} else {
    //My code
}

我面临的问题是,如果用户到达这个片段但没有输入任何内容,然后滑动回到之前的片段,然后滑动到选择的日期和时间片段,我的 Log 行位于 onCreateView.

我不明白为什么如果我在 selectedDate 和 selectedTime 为 null 时试图避免保存数据,当重新创建片段时,bundle 与 null 不同(当然键值对不存在)。

你能给我一个解决这个问题的方法吗?我将不胜感激对此行为的任何解释。

像下面这样改变你的方法

@Override
public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
    if (selectedDate != null && selectedTime != null) {
        outState.putString("date", selectedDate.toString());
        outState.putString("time", selectedTime.toString());

    }
}

配置更改后 Bundle 不是 null,因为您的 Fragment 实现不是唯一使用它的实现。以下引自documentation for Activity but it is valid for Fragment as well, as stated in Handling Runtime Changes:

However, even if you do nothing and do not implement onSaveInstanceState(), some of the activity state is restored by the Activity class's default implementation of onSaveInstanceState(). Specifically, the default implementation calls the corresponding onSaveInstanceState() method for every View in the layout, which allows each view to provide information about itself that should be saved.

因此,除了确保 Bundle 不是 null 之外,您还应该检查带有键 "date" 和 "time" 的额外内容是否存在。当您保存两个密钥或 none 时,检查其中一个就足够了:

if (savedInstanceState != null
   && savedInstanceState.containsKey("date")
    ){
    Log.d("mylog", savedInstanceState.getString("date");
    currentDate = LocalDate.parse(savedInstanceState.getString("date"));
    currentTime = LocalTime.parse(savedInstanceState.getString("time"));
    selectedDateTv.setText(currentDate.toString("dd/MM/yyyy"));
    selectedTimeTv.setText(currentTime.toString("HH:mm"));
} 
else {
    //My code
}