Android多个fragment懒加载的坑(卡顿)

版权声明:本文为徐代龙原创文章,未经徐代龙允许不得转载。网络资源网站:xudailong.cc 福利网站:www.00reso.com 公众号:蛇崽网盘教程资源 https://blog.csdn.net/xudailong_blog/article/details/85255814

在Android开发中,有很多种情况都是viewpage+fragment左右滑动进行布局的,例如下面的今日头条
在这里插入图片描述
在今日头条app上,我们可以看到,其顶部都是一栏的类型数据源,可滑动,可联动下面的viewpage里的fragment,但是很多时候,viewpage+fragment中的fragment每次都将走onCreate方法,导致在视觉上造车一定的卡顿,而且在加载当前fragment的时候,往往会预加载下一个fragment的数据,造成视觉上的误解。

思路:

在尝试过很多方法之后,终于找到了一个比较好的解决方法。使用Fragment自带的setUserVisibleHint()来判断当前fragment是否对用户可见,根据回调的isVisibleToUser参数来进行相关的逻辑判断。创建一个变量isVisible来拿到fragment是否可见的标志。

但是直接根据isVisible判断就加载数据,很有可能很多控件在OnCreateView()方法还未执行完成的情况下出现NullPointerException空指针的情况。所以我们需要在控件初始化完成并且用户可见的时候,再去进行数据的加载。

在这里插入图片描述

最后集成一个通用的LazyloadFragment实现懒加载的fragment

public abstract class LazyloadFragment extends Fragment {
    protected View rootView;
    private boolean isInitView = false;
    private boolean isVisible = false;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        rootView = inflater.inflate(setContentView(), container, false);
        init();
        isInitView = true;
        isCanLoadData();
        return rootView;
    }

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);

        //isVisibleToUser这个boolean值表示:该Fragment的UI 用户是否可见,获取该标志记录下来
        if(isVisibleToUser){
            isVisible = true;
            isCanLoadData();
        }else{
            isVisible = false;
        }
    }

    private void isCanLoadData(){
        //所以条件是view初始化完成并且对用户可见
        if(isInitView && isVisible ){
            lazyLoad();

            //防止重复加载数据
            isInitView = false;
            isVisible = false;
        }
    }

    /**
     * 加载页面布局文件
     * @return
     */
    protected abstract int setContentView();

    /**
     * 让布局中的view与fragment中的变量建立起映射
     */
    protected abstract void init();

    /**
     * 加载要显示的数据
     */
    protected abstract void lazyLoad();

}

这里需要使用FragmentPagerAdapter,才可以显示的调用setUserVisibleHint()这个方法

子fragment的加载数据的写法:

public class PageFragment extends LazyloadFragment implements XRecyclerView.LoadingListener {
    private CommonAdapter<String> adapter;
    private ArrayList<String> datas = new ArrayList<>();
    private XRecyclerView recyclerView;
    private Handler handler = new Handler();

    @Override
    public int setContentView() {
        return R.layout.fragment_page;
    }


    @Override
    public void init() {
        recyclerView = rootView.findViewById(R.id.recyclerview);
        recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
        adapter = new CommonAdapter<String>(getActivity(),R.layout.item,datas) {
            @Override
            protected void convert(ViewHolder holder, String s, int position) {

            }
        };
        recyclerView.setAdapter(adapter);
        recyclerView.setPullRefreshEnabled(true);
        recyclerView.setLoadingListener(this);

    }

    @Override
    public void lazyLoad() {
        recyclerView.refresh();
    }

    @Override
    public void onRefresh() {
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                recyclerView.refreshComplete();
                for(int i=0;i<10;i++){
                    datas.add("");
                }
                adapter.notifyDataSetChanged();
            }
        },500);
    }

    @Override
    public void onLoadMore() {

    }
}

fragment的调用还是像以前一样的调用。

总结:

fragment+viewpage这种模式确实很消耗手机性能与内存,特别是在一些即将淘汰的手机上出现的卡顿也将特别严重,这样实现的懒加载模式可以控制只加载一个fragment,并且还是加载当前的fragment,而不会触发下一个fragment的预加载,就目前来说,我用的这个方法还是挺靠谱的。

猜你喜欢

转载自blog.csdn.net/xudailong_blog/article/details/85255814