TabLayout-ViewPager填充Fragment和懒加载

Tablayout+ViewPager填充Fragment和懒加载

这里写图片描述

使用Fragment来填充ViewPager

TabLayout+ViewPager+Fragmenet是使用非常多的控件组合。

TabLayout组件的简单介绍

  • TabLayout是Material Design组件开发中的一种,使用时需要先导入design库的依赖。
  • TabLayout做出的效果是一排可以滑动的Tab,相当于一排指示器。
  • 在布局中申明控件
<android.support.design.widget.TabLayout
        android:id="@+id/tablayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:tabBackground="@color/colorPrimaryDark"
        app:tabIndicatorColor="#ff0000"
        app:tabIndicatorHeight="2dp"
        app:tabTextColor="@color/colorAccent"
        app:tabSelectedTextColor="#FFFFFF"
        app:tabMode="scrollable"
        app:tabPadding="5dp">

    </android.support.design.widget.TabLayout>
  • 基本属性介绍,布局和代码都可以使用

  • 列表内容

    • tabBackground 背景色
    • tabIndicatorColor:指示器颜色,横线
    • tabIndicatorHeight 指示器高度
    • tabTextColor 指示器,文字 没有选择时正常的颜色
    • tabSelectedTextColor 指示器,文字 选择时颜色
    • tabPadding 指示器 内边距
    • app:tabMode=”scrollable” 模式,有scrollable和fixed两种,分别表示可以滑动和固定的意思

  • 代码中绑定ViewPager

    • 在ViewPager设置Adapter之后,调用tabLayout的setupWithViewPager方法绑定ViewPager
    • 设置显示的内容
    • 可以调用tabLayout的addTab方法添加
      -也可以重写ViewPager适配器的getPagerTitle方法返回显示的内容

FragmentPagerAdapter与FragmentStatePagerAdapter的区别

FragmentPagerAdapter
  • FragmentPagerAdapter类默认会对getItem()方法返回的Fragment做缓存处理,只有当第一次打开ViewPager的页面才会去创建Fragment的对象,后面再打开页面时就会直接从缓存中获取Fragment对象的引用,这样getItem方法就不会调用了。

  • 因为FragmentPagerAdapter做了缓存处理,所有当创建很多的Fragment时内存就会吃不消,应用程序有可能会崩掉,所以呢,FragmentPagerAdapter不适合做大量数据的Fragment显示,比较适合数据不变的静态Fragment显示。

FragmentStatePagerAdapter
  • FragmentStatePagerAdapter正好与之相反,每次进入页面时都会创建Fragment对象,每次滑出时都会销毁对应的Fragment对象,没有做一点的缓存,这样内存就完全的解放出来了。

  • FragmentStatePagerAdapter在销毁Fragment时会调用onSaveInstanceState方法保存一些数据信息,然后下一次创建Fragment时会将这些数据读取出来

ViewPager的预加载

ViewPager天生会加载左右两侧的页面,这是通过一个叫做DEFAULT_OFFSCREEN_PAGES的属性指定的,通过setOffscreenPageLimit(int)可以指定这个属性的值。

 private static final int DEFAULT_OFFSCREEN_PAGES = 1;

public void setOffscreenPageLimit(int limit) {
        if (limit < DEFAULT_OFFSCREEN_PAGES) {
            Log.w(TAG, "Requested offscreen page limit " + limit + " too small; defaulting to "
                    + DEFAULT_OFFSCREEN_PAGES);
            limit = DEFAULT_OFFSCREEN_PAGES;
        }
        if (limit != mOffscreenPageLimit) {
            mOffscreenPageLimit = limit;
            populate();
        }
    }

发现要是给的值小于1,那还是默认为1,也就是说这个方法只能指定加载更多的页面。并不能解决问题,设置为0,还是不设置都一样默认为1,只有大于1时才有作用

Fragment实现懒加载

Fragment的生命周期中,我们一般在onCreateView方法初始化视图,onActivityCreated方法初始化数据

  • 通过setUserVisibleHint和getUserVisibleHint方法来设置和获取Fragment的显示状态,当显示了才去加载数据。因为每一个Fragment都是这样,所以在BaseFragment中完成操作。
 /**
     * setUserVisibleHint是在onCreateView之前调用的
     *
     * @param isVisibleToUser
     */
    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {

        super.setUserVisibleHint(isVisibleToUser);

        /**
         * 判断是否可见
         */
        if(getUserVisibleHint()) {

            isVisible = true;
            //执行可见方法-初始化数据之类
            onVisible();

        } else {

            isVisible = false;
            //不可见
            onInvisible();
        }

    }
  • onActivityCreated中也做判断
 @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {

        super.onActivityCreated(savedInstanceState);
        //这里 初始化view的各控件 数据
        isPrepared = true;
        lazyLoad();

    }
  • lazyLoad
/**
     * 可见做懒加载
     */
    private void onVisible() {
        lazyLoad();
    }

    /**
     * 懒加载
     */
    private void lazyLoad() {
        /**
         * 判断是否可见,或者 初始化view的各控件
         */
        if(!isVisible || !isPrepared) {
            return;
        }
        //可见 或者 控件初始化完成 就 加载数据
        initData();

    }
第二种 将lazyLoad抽象方法 在子类在实现

子Fragment继承BaseFramentTabLayout

// 标志位,标志已经初始化完成。
    private boolean isPrepared;
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        Log.d(LOG_TAG, "onCreateView");
        View view = inflater.inflate(R.layout.fragment_open_result, container, false);
        //XXX初始化view的各控件
    isPrepared = true;
        lazyLoad();
        return view;
    }
    @Override
    protected void lazyLoad() {
        if(!isPrepared || !isVisible) {
            return;
        }
        //填充各控件的数据
    }

个人主页
https://ln0491.github.io/
http://ln0491.coding.me/
源码:
https://github.com/ln0491/ViewPagerDemo

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值