【问题标题】:Android - Retain objects in UI FragmentAndroid - 在 UI 片段中保留对象
【发布时间】:2015-01-22 02:45:13
【问题描述】:

在我的项目中,我最初使用的是这个方案:

Activity A (UI) > Fragment B (non-UI) > Adapter + AsyncTask

  • BsetRetainInstance(true) 一起保留并更新 A UI
  • AgetFragmentManager() 实例化 B

但是我现在需要用到UI Fragments,所以我想用这个方案:

Activity A > Fragment B (UI) > Fragment C (non-UI) > Adapter + AsyncTask

  • CsetRetainInstance(true) 一起保留并更新 B UI
  • BgetChildFragmentManager() 实例化 C

但似乎不可能:

Caused by: java.lang.IllegalStateException:
    Can't retain fragements that are nested in other fragments

我尝试用getFragmentManager() 而不是getChildFragmentManager() 来实例化C,但我遇到了一些问题。


在 Fragment 中保留对象和管理 AsyncTask 的最佳做法是什么?

【问题讨论】:

  • 如何让活动 A 成为 B 和 C 的所有者?
  • 我认为它会起作用,但 C 实例管理 B UI 所以我想将 C 嵌套在 B 或学习“最佳实践” - 也许是?跨度>

标签: android android-fragments android-asynctask


【解决方案1】:

我终于开发了一个小助手类:

public class RetainFragment<F extends Fragment> extends Fragment {

    private static <F extends Fragment> String tag(F ui, Object id) {
        return ui.getClass().getName() + id.toString();
    }

    public static <F extends Fragment> Fragment get(F ui, Object id) {
        return ui.getFragmentManager().findFragmentByTag(tag(ui, id));
    }

    public F ui;
    public Object id;

    @Override
    public void onCreate(Bundle state) {
        super.onCreate(state);
        setRetainInstance(true);
    }

    public void link(F ui, Object id) {
        this.id = id;
        this.ui = ui;
        if (get(ui, id) == null) {
            ui.getFragmentManager()
              .beginTransaction()
              .add(this, tag(ui, id))
              .commit();
        }
    }

    public void unlink() {
        if (get(ui, id) != null) {
            ui.getFragmentManager()
              .beginTransaction()
              .remove(this)
              .commit();
        }
        ui = null;
        id = null;
    }

}

现在,在 UI 片段中,我只写:

public class UiFragment extends Fragment {

    private static class Retain extends RetainFragment<UiFragment> {
        private MyAsyncTask task;   // Objects to retain over
        private MyAdapter adapter;  // configuration changes
    }

    private Retain retain;

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        retain = (Retain) Retain.get(this, 0);
        if (retain == null) {
            retain = new Retain();
            // Retained objects initialization
            retain.adapter = new MyAdapter();
        }
        retain.link(this, 0);
    }

    @Override
    public void onDetach() {
        if (isRemoving()) {
            // Retained objects terminate
            if (retain.task != null) {
                retain.task.cancel(true);
            }
            retain.unlink();
        }
        super.onDetach();
    }

    private void update() {
        if (!isDetached()) {
            // Update UI fragment
        }
    }

}

retain.task.onPostExecute():

retain.ui.update(); // Reference to the last ui fragment instance linked

并在 UI 片段启动时启动任务:

private static class Retain extends RetainFragment<UiFragment> {
    private MyAsyncTask task;   // Objects to retain over
    private MyAdapter adapter;  // configuration changes

    @Override
    public void onCreate(Bundle state) {
        super.onCreate(state);
        ui.onRetainCreated();
    }
}

private void onRetainCreated() {
    retain.task = new MyAsyncTask() {
        @Override
        protected void onPostExecute(Void result) {
            retain.ui.update();
        }
    };
    retain.task.execute();
}

【讨论】:

    猜你喜欢
    • 2018-01-21
    • 1970-01-01
    • 1970-01-01
    • 2021-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多