在 onRestoreInstanceState 之后从片段执行操作
Execute operation from fragment after onRestoreInstanceState
我有一个执行某些网络操作的自定义视图。根据该操作结果,视图构建 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
}
}
好的,现在当用户从我的应用程序切换到另一个应用程序时,我的片段可能会被破坏。我想保存自定义视图的状态。因此我的观点不需要再次从互联网上获取信息。因此,我将 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];
}
};
}
}
为了争论,我想从这个视图本身保存视图的数据。所以 fragments/activities 或 w/e 使用它不需要知道它在内部是如何工作的。如果我从多个地方使用它,我就不需要复制 stores\restores 这个视图的代码。
好了,现在进入正题:
第一次创建 CardHelper 时,我执行 init
用一些 data
手动初始化视图。当我的片段被销毁并且应用程序进入后台然后恢复时,方法将按以下优先级执行:
- SavedState:私有 SavedState(包裹在){
- SavedState: public void writeToParcel(Parcel out, int flags) {
- CardHelper: public void init(数据数据) {
- CardHelper: public void onRestoreInstanceState(Parcelable state) {
如您所见,onRestoreInstanceState
仅在 onActivityCreated
之后执行。但是我需要知道我是否应该在此之前在 init
方法中执行网络操作。所以我想 onRestoreInstanceState
先执行,然后才执行 init
。但是片段 LifeCycle 中没有可以在此之后完成的方法。
如何重新格式化我的代码,以便在 CardHelper
上的 onRestoreInstanceState
被调用后可以在我的片段中调用某些操作?还有一件事是 onRestoreInstanceState
在创建 CardHelper
时不会第一次被调用。但是在这种情况下我也需要初始化我的 CardHelper。
简单的解决方法应该是在布局 cardHelper
之后发布 init()
步骤,因此 onRestoreInstanceState
已经被调用。为此,您只需执行 init()
in post(...)
:
cardHelper.post(new Runnable() {
public void run() {
cardHelper.init();
}
});
还没有测试过,我想它会起作用。
我有一个执行某些网络操作的自定义视图。根据该操作结果,视图构建 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
}
}
好的,现在当用户从我的应用程序切换到另一个应用程序时,我的片段可能会被破坏。我想保存自定义视图的状态。因此我的观点不需要再次从互联网上获取信息。因此,我将 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];
}
};
}
}
为了争论,我想从这个视图本身保存视图的数据。所以 fragments/activities 或 w/e 使用它不需要知道它在内部是如何工作的。如果我从多个地方使用它,我就不需要复制 stores\restores 这个视图的代码。
好了,现在进入正题:
第一次创建 CardHelper 时,我执行 init
用一些 data
手动初始化视图。当我的片段被销毁并且应用程序进入后台然后恢复时,方法将按以下优先级执行:
- SavedState:私有 SavedState(包裹在){
- SavedState: public void writeToParcel(Parcel out, int flags) {
- CardHelper: public void init(数据数据) {
- CardHelper: public void onRestoreInstanceState(Parcelable state) {
如您所见,onRestoreInstanceState
仅在 onActivityCreated
之后执行。但是我需要知道我是否应该在此之前在 init
方法中执行网络操作。所以我想 onRestoreInstanceState
先执行,然后才执行 init
。但是片段 LifeCycle 中没有可以在此之后完成的方法。
如何重新格式化我的代码,以便在 CardHelper
上的 onRestoreInstanceState
被调用后可以在我的片段中调用某些操作?还有一件事是 onRestoreInstanceState
在创建 CardHelper
时不会第一次被调用。但是在这种情况下我也需要初始化我的 CardHelper。
简单的解决方法应该是在布局 cardHelper
之后发布 init()
步骤,因此 onRestoreInstanceState
已经被调用。为此,您只需执行 init()
in post(...)
:
cardHelper.post(new Runnable() {
public void run() {
cardHelper.init();
}
});
还没有测试过,我想它会起作用。