Navigation 返回上一个Fragment避免重新onCreateView的方法

5,439 阅读1分钟

最近在一个平板APP项目中使用Navigation体验非常的好,这个框架在Fragment栈管理、参数传递和转场动画等方面表现地都非常好。但是最近遇到一个问题就是通过Back按钮返回上一个Fragment时,整个界面会进行刷新,重新执行onCreateView()、onViewCreated(),这就会导致用户体验非常差,尤其是对于包含大量列表等页面,重新刷新View之后还需要开发者自行保存列表焦点位置等问题。最终,在 stackoverflow 找到了答案。我们可以采用以下方法解决。

首先创建一个BaseFragment,原理就是首次进入时保存View,并在之后复用。代码如下:

public abstract class BaseFragment extends Fragment {
    public boolean isFragmentViewInit = false;
    public View lastView;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        if (lastView == null) {
            lastView = setRootView(inflater, container, savedInstanceState);
        }
        return lastView;
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        if (!isFragmentViewInit) {
            super.onViewCreated(view, savedInstanceState);
            initView(view);
            initData();
            isFragmentViewInit = true;
        }
    }

    /**
     * View初始化
     *
     * @param view 布局
     */
    public abstract void initView(View view);

    /**
     * 初始化数据
     */
    public abstract void initData();

    /**
     * 设置根view
     *
     * @param inflater           1
     * @param container          2
     * @param savedInstanceState 3
     * @return
     */
    public abstract View setRootView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState);
}

我们实现的所有Fragment只需要继承这个Fragment并实现相关方法就可以达到复用的目的。代码如下:

public class CategoryFrag extends BaseFragment {

    @Override
    public void initView(final View view) {
    }

    @Override
    public void initData() {
    }

    @Override
    public View setRootView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_category, container, false);
    }
}