У меня есть пользовательский вид, который выполняет некоторые сетевые операции. Из результата этой операции в представлении создается пользовательский интерфейс.Выполнять операцию из фрагмента после 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
}
}
ОК, теперь, когда пользователь переключается из моего приложения к другому, мой фрагмент мог быть уничтожен. И я хочу сохранить состояние своего пользовательского представления. Таким образом, мне не нужно снова получать информацию из Интернета. Поэтому я прилагаю мой 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: частный SavedState (участок в) {
- SavedState: общественная пустота writeToParcel (дробить, ИНТ флаги) {
- CardHelper: общественного недействительными инициализации (данные Data) {
- CardHelper: общественная пустота onRestoreInstanceState (Parcelable состояние) {
Как вы видите onRestoreInstanceState
выполняется только после onActivityCreated
. Но мне нужно знать, должен ли я выполнять сетевую операцию в методе init
до этого. Поэтому я хочу выполнить onRestoreInstanceState
и только тогда init
. Но нет фрагментов LifeCycle, которые можно было бы сделать после этого.
Как переформатировать мой код, который я могу назвать некоторой операцией внутри моего фрагмента после того, как onRestoreInstanceState
на CardHelper
получил вызов? Еще одна вещь, что onRestoreInstanceState
не будет вызываться в первый раз, когда создается CardHelper
. Но в этом случае мне также нужно инициализировать CardHelper.
Да, это работает. Наверное, есть более элегантное решение. – deathangel908
Проблема в вашем коде заключается в том, что 'View' знает о бизнес-логике. Обычно этого не должно быть. Элегантным решением было бы не сохранить данные в поле зрения, подумайте об изменении своей архитектуры. – azizbekian
Не могли бы вы предложить, как это должно быть сделано? Идея заключалась в том, чтобы инкапсулировать логику, чтобы ее рассматривать. Поэтому людям, которые используют мой взгляд, не нужно будет беспокоиться ни о чем, кроме проспекта «layout.xml». Если я переведу логику в сторону от своего представления, пользователь должен знать, что он ДОЛЖЕН сохранить пакет вручную. – deathangel908