Tablayout+Viewpager+Fragment组合使用以及懒加载机制

下面这个界面在日常开发中简直太常见不过了,viewpager+fragment组合出来的效果!

                              Tablayout+Viewpager+Fragment组合使用以及懒加载机制_第1张图片

首先介绍一下使用方法:

xml文件

 
    

属性说明:
android:background="#EF8D11" 背景色
app:tabIndicatorColor="#EF4A11" tab文字下方的那条线的颜色
app:tabMode="scrollable" 如果tab过多超出屏幕宽度可以水平滚动
app:tabSelectedTextColor="#FFFFFF" tab被选中的时候文字的颜色
app:tabTextColor="#FFFFFF" tab未被选中时文字的颜色
app:tabTextAppearance="@style/MyTabLayoutTextAppearance" 自定义字体大小(一般使用默认即可)

1
2
3
<style name="MyTabLayoutTextAppearance" parent="TextAppearance.AppCompat.Widget.ActionBar.Title.Inverse">
    <item name="android:textSize">12spitem>
style>

java 代码

    private void initView(View view) {

        mTablayout = (TabLayout) view.findViewById(R.id.tab_layout);
        //mTablayout.setTabMode(TabLayout.MODE_SCROLLABLE);//挤在一起显示
        viewpager = (ViewPager) view.findViewById(R.id.viewpager);
        setupViewPager(viewpager);
        mTablayout.addTab(mTablayout.newTab().setText("头条"));
        mTablayout.addTab(mTablayout.newTab().setText("NBA"));
        mTablayout.addTab(mTablayout.newTab().setText("汽车"));
        mTablayout.addTab(mTablayout.newTab().setText("笑话"));

        mTablayout.setupWithViewPager(viewpager);

    }

    private void setupViewPager(ViewPager viewpager) {
        MyPagerAdapter adapter=new MyPagerAdapter(getChildFragmentManager());
        adapter.addFragment(FirstListFragment.newInstance(ONE),"头条");
        adapter.addFragment(FirstListFragment.newInstance(TWO),"NBA");
        adapter.addFragment(FirstListFragment.newInstance(THREE),"汽车");
        adapter.addFragment(FirstListFragment.newInstance(FOUR),"笑话");
        viewpager.setAdapter(adapter);
    }
MyPagerAdaper

 public  static class MyPagerAdapter extends FragmentPagerAdapter{
        private final List mFragment=new ArrayList();
        private final List mFragmentTitle=new ArrayList();

        public void addFragment(Fragment  fragment,String title){
            mFragment.add(fragment);
            mFragmentTitle.add(title);
        }
        public MyPagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int position) {
            return mFragment.get(position);
        }

        @Override
        public int getCount() {
            return mFragment.size();

        }
        @Override
        public CharSequence getPageTitle(int position) {
            return mFragmentTitle.get(position);
        }
    }

懒加载定义

Fragment的UI界面对用户可见的时候才加载数据。

怎么判断什么是否对用户可见呢?

public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if (getUserVisibleHint()) {
            //可见
        } else {
            //不可见
        }
    }

注意:fragment的缓加载,优先于oncreate方法执行,且每次切换fragment都会执行此方法!

代码

为了方便,封装一个基类 LazyLoadFragment,提供一个 loadData() 方法供调用去加载数据

public abstract class LazyLoadFragment extends Fragment {

    /**
     * 控件是否初始化完成
     */
    private boolean isViewCreated;
    /**
     * 数据是否已加载完毕
     */
    private boolean isLoadDataCompleted;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(getLayout(), container, false);
        initViews(view);
        isViewCreated = true;
        return view;
    }

    public abstract int getLayout();
    public abstract void initViews(View view);

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if (isVisibleToUser && isViewCreated && !isLoadDataCompleted) {
            isLoadDataCompleted = true;
            loadData();
        }
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        if (getUserVisibleHint()) {
            isLoadDataCompleted = true;
            loadData();
        }
    }

    /**
     * 子类实现加载数据的方法
     */
    public abstract  void loadData();
注:

      为什么 loadData() 会在两个地方执行?在 setUserVisibleHint 方法里执行我还能理解,为什么 onActivityCreated 也要执行呢?

        因为,ViewPager 默认显示第一页,第一页肯定要先加载数据,而且 setUserVisibleHint 的执行顺序又是在 onCreatView 之前,同时 onCreatView 需要初始化界面和修改 isViewCreated 的值。所以就需要在 onActivityCreated 里执行一次。

 

上面图片项目源码:点击打开链接

你可能感兴趣的:(Android)