【发布时间】:2017-02-18 11:09:45
【问题描述】:
我有一个执行某些网络操作的自定义视图。视图根据该操作结果构建 UI。
视图包含通过互联网获取的卡片列表。此视图在多个地方使用。假设其中一个是我的片段。
这是我在片段中所做的:
class MyFragment extends Fragment {
// same as findViewById
@BindView(R.id.card_list) CardHelper cardHelper;
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// init my element with some data before it initializes
cardHelper.init(data);
}
}
我的自定义视图如下所示:
public class CardHelper extends ListView {
// some info that is built from internet data
private List<HashMap<String, String>> cardElements = new ArrayList<>();
public void init(Data data) {
// does async network and then build a view based on results
// Network operations could depend on data param
}
}
好的,现在当用户从我的应用切换到另一个应用时,我的 Fragment 可能会被破坏。我想保存我的自定义视图的状态。因此我的观点不需要再次从互联网上获取信息。所以我在CardHelper 后面加上以下数据(基于this 答案):
public class CardHelper extends ListView {
// some info that is built from internet data
private List<HashMap<String, String>> cardElements = new ArrayList<>();
public void init(Data data) {
// does async network and then build a view based on results
}
@Override
public Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState();
SavedState ss = new SavedState(superState);
ss.cardElements = this.cardElements;
return ss;
}
@Override
public void onRestoreInstanceState(Parcelable state) {
if(state instanceof SavedState) {
SavedState ss = (SavedState)state;
super.onRestoreInstanceState(ss.getSuperState());
this.cardElements = ss.cardElements;
} else {
super.onRestoreInstanceState(state);
}
}
private static class SavedState extends BaseSavedState {
private List<HashMap<String, String>> cardElements = new ArrayList<>();
SavedState(Parcelable superState) {
super(superState);
}
private SavedState(Parcel in) {
super(in);
this.cardElements = new ArrayList<>();
in.readList(this.cardElements, null);
}
@Override
public void writeToParcel(Parcel out, int flags) {
super.writeToParcel(out, flags);
out.writeList(this.cardElements);
}
public static final Parcelable.Creator<SavedState> CREATOR =
new Parcelable.Creator<SavedState>() {
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}
}
为了争论,我想保存这个视图本身的视图数据。因此片段/活动或 w/e 使用它不需要知道它在内部是如何工作的。如果我在多个地方使用它,我就不需要复制存储\恢复此视图的代码。
好的,现在解决问题:
第一次创建 CardHelper 时,我执行 init 以使用一些 data 手动初始化视图。当我的片段被破坏并且应用程序进入后台然后被恢复时,方法将按以下优先级执行:
- SavedState: private SavedState(Parcel in) {
- SavedState: public void writeToParcel(Parcel out, int flags) {
- CardHelper: public void init(Data data) {
- CardHelper: public void onRestoreInstanceState(Parcelable state) {
如您所见,onRestoreInstanceState 仅在 onActivityCreated 之后执行。但我需要知道在此之前我是否应该在init 方法中执行网络操作。所以我想先执行onRestoreInstanceState,然后再执行init。但是在片段LifeCycle 中没有可以在此之后完成的方法。
在调用CardHelper 上的onRestoreInstanceState 后,如何重新格式化我可以在片段中调用某些操作的代码?还有一件事是onRestoreInstanceState 在创建CardHelper 时第一次不会被调用。但在这种情况下,我也需要初始化 CardHelper。
【问题讨论】:
标签: android android-fragments android-savedstate