我有一個執行一些網絡操作的自定義視圖。從該操作結果中,視圖構建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。
是的,這個工程。那裏可能有更優雅的解決方案。 – deathangel908
你的代碼中的問題是,'View'知道業務邏輯。通常情況下,這不應該發生。優雅的解決方案不是將數據保存在視圖中,而是考慮更改架構。 – azizbekian
你能否建議它應該怎麼做?這個想法是封裝邏輯來查看自己。因此,使用我的視圖的人不需要擔心任何剛剛過去'layout.xml'的視圖。如果我將邏輯從我的視圖移開,用戶應該意識到他必須手動保存包。 – deathangel908