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

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

                              

首先介绍一下使用方法:

xml文件

 <android.support.design.widget.TabLayout
        android:id="@+id/tab_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#EF8D11"
        app:tabIndicatorColor="#EF4A11"
        app:tabMode="scrollable"
        app:tabSelectedTextColor="#FFFFFF"
        app:tabTextAppearance="@style/MyTabLayoutTextAppearance"
        app:tabTextColor="#FFFFFF" />
    <android.support.v4.view.ViewPager
        android:id="@+id/view_pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

属性说明:
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">12sp</item>
</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<Fragment> mFragment=new ArrayList<Fragment>();
        private final List<String> mFragmentTitle=new ArrayList<String>();

        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 里执行一次。

 

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

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值