onRestoreInstanceState后执行片段操作
我有一个执行一些网络操作的自定义视图。从该操作结果中,视图构建UI。onRestoreInstanceState后执行片段操作
该视图包含通过互联网获取的卡片列表。这个视图在多个地方使用。可以说,其中之一是我的片段。
这是我做的片段里面:
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
}
}
OK,现在当用户切换从我的应用程序到另一个,我的部分可被销毁。我想拯救我的习俗的状态。因此我的观点不需要再从互联网上获取信息。所以我附上我的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];
}
};
}
}
为了讨论的方便,我想从这个观点本身保存视图的数据。因此,片段/活动或使用它不需要知道它是如何工作的。如果我从多个地方使用它,我不需要复制存储\恢复此视图的代码。
确定,到现在的问题:
当CardHelper创建非常第一次执行init
与一些data
手动初始化视图。当我的片段被破坏,应用程序切换到后台,然后得到恢复,方法是在以下优先执行:
- SavedState:私人SavedState(包裹中){
- SavedState:公共无效writeToParcel(包裹出来,诠释标志){
- CardHelper:公共无效的init(数据数据){
- CardHelper:公共无效onRestoreInstanceState(Parcelable状态){
正如你看到onRestoreInstanceState
仅在onActivityCreated
后执行。但在此之前,我需要知道我是否应该在init
方法中执行网络操作。所以我想onRestoreInstanceState
被执行第一个,然后只有init
。但是在LifeCycle的片段中没有可以在此之后完成的方法。
如何重新格式化我的代码,我可以在onRestoreInstanceState
CardHelper
被调用后调用我的片段中的某些操作?当CardHelper
创建时,onRestoreInstanceState
第一次不会被调用。但是我也需要在这种情况下初始化我的CardHelper。
简易修复应在发布cardHelper
后发布init()
步骤,因此onRestoreInstanceState
已被调用。要做到这一点,你只需要在post(...)
执行init()
:
cardHelper.post(new Runnable() {
public void run() {
cardHelper.init();
}
});
没有测试过,我相信它会工作。
是的,这个工程。那里可能有更优雅的解决方案。 – deathangel908
你的代码中的问题是,'View'知道业务逻辑。通常情况下,这不应该发生。优雅的解决方案不是将数据保存在视图中,而是考虑更改架构。 – azizbekian
你能否建议它应该怎么做?这个想法是封装逻辑来查看自己。因此,使用我的视图的人不需要担心任何刚刚过去'layout.xml'的视图。如果我将逻辑从我的视图移开,用户应该意识到他必须手动保存包。 – deathangel908