在 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 手动初始化视图。当我的片段被销毁并且应用程序进入后台然后恢复时,方法将按以下优先级执行:

  1. SavedState:私有 SavedState(包裹在){
  2. SavedState: public void writeToParcel(Parcel out, int flags) {
  3. CardHelper: public void init(数据数据) {
  4. 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();
                   }
               });

还没有测试过,我想它会起作用。