美文网首页
Fragment懒加载

Fragment懒加载

作者: 码圣 | 来源:发表于2016-10-05 13:17 被阅读50次

在ViewPager与Fragment一起使用时,由于ViewPager的特性,Fragment会预加载,但是我们希望只在当前界面时才加载数据。


基类:

public abstract class LazyFragment extends Fragment {
    //当前Fragment是否可见
    protected boolean isVisible;
    /**
     * 在这里实现Fragment数据的缓加载.
     * @param isVisibleToUser
     */
    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if(getUserVisibleHint()) {
            isVisible = true;
            onVisible();
        } else {
            isVisible = false;
            onInvisible();
        }
    }

    protected void onVisible(){
        lazyLoad();
    }

    protected abstract void lazyLoad();

    protected void onInvisible(){}
}

子类Fragment:

//思想:当不可见时只inflate布局(且只inflate一次),
// 可见时去加载数据,只加载一次,滑动下一个再回来时就不去加载数据了,除非手动刷新(或者Fragment被回收)
public class MyFragment1 extends LazyFragment {
    //布尔的默认值是false

    // 标志位,标志已经初始化完成。(是否已经inflat布局以及findviewById了)
    private boolean isPrepared;
    private TextView rootView;
    /**
     * 是否已加载过一次数据(可能走网络),第二次就不再去请求数据了
     */
    private boolean mHasLoadedDataOnce;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        Log.d("alan", "MyFragment1  oncreateView");
        if (rootView == null) {
            Log.d("alan", "init rootView");
            rootView = new TextView(getActivity());
            //... 初始化各种控件(findViewById)

            isPrepared = true;
            lazyLoad();
        }
        //因为共用一个Fragment视图,所以当前这个视图已被加载到Activity中,必须先清除后再加入Activity
        ViewGroup parent = (ViewGroup) rootView.getParent();
        if (parent != null) {
            parent.removeView(rootView);
        }
        return rootView;
    }

    //必须先inflate过布局,才能去加载数据,注意顺序
    @Override
    protected void lazyLoad() {//加载数据,主要操作都在这里,三个判断条件
        Log.d("alan", "isPrepared----->" + isPrepared);
        if (!isPrepared || !isVisible || mHasLoadedDataOnce) {
            return;
        }

        //虚拟一个加载网络数据的任务
        new AsyncTask<Void, Void, Boolean>() {

            private AlertDialog alertDialog;

            @Override
            protected void onPreExecute() {
                super.onPreExecute();
                //显示加载进度对话框
                UIHelper.showDialogForLoading(getActivity(),"正在加载...",true);
            }

            @Override
            protected Boolean doInBackground(Void... params) {
                try {
                    Thread.sleep(2000);
                    //走网络
                    //doSomething()
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return true;
            }

            @Override
            protected void onPostExecute(Boolean isSuccess) {
                if (isSuccess) {// 加载成功
                    UIHelper.hideDialogForLoading();
                    mHasLoadedDataOnce = true;//加载成功之后才算加载好了一次数据

                    //加载数据完成后,填充各个控件
                    rootView.setText(getClass().getName());
                } else {
                    // 加载失败
                    UIHelper.hideDialogForLoading();

                }
            }
        }.execute();
    }
}

思想梳理:Fragment预加载时只加载布局,并且只加载一次,加载完布局并且可见时才去加载填充数据(也只做一次)。
源码
参考文章

相关文章

网友评论

      本文标题:Fragment懒加载

      本文链接:https://www.haomeiwen.com/subject/mijsyttx.html