TabLayout+ViewPager常用操作

导航栏+滑动页的组合算是目前Android开发最常用的套路之一,最经典的就是微信主界面。

我整理了一下TabLayout+ViewPager的最常用操作,方便以后使用(自己记忆力不好,每次都要查)。

整套布局主要由四个部分组成:
- TabLayout
- Viewpager
- PagerAdapter (FragmentPagerAdapter)
- ViewPager内容(通常为fragment或ListView)

xml布局和实例化控件

<android.support.design.widget.TabLayout
            android:id="@+id/tab"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@color/white"
            app:tabIndicatorHeight="1dp"
            app:tabIndicatorColor="@color/orange"
            app:tabSelectedTextColor="@color/orange"
            app:tabMode="fixed"
            app:tabBackground="@color/white"
            app:tabTextColor="@color/dark"/>

        <android.support.v4.view.ViewPager
            android:id="@+id/viewpager"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@color/white"
            android:layout_marginTop="1px"/>
TabLayout mTabLayout = (TabLayout)findViewById(R.id.tab);
ViewPager mViewPager = (ViewPager)findViewById(R.id.viewpager);

这里面比较有用的是TabLayout的几个自定义命名空间“app”的属性,大部分人属性的作用从名字就可以看出来。(tabIndicator是指标签的下划线)

app:tabMode有两个值:fixed和scrollable。fixed是所有标签平分整个tabLayout,scrollable让tabLayout可滚动以显示超出屏幕的部分。

调用比较多的方法

TabLayout常用到的方法:

1.绑定ViewPager:

mTabLayout.setupWithViewPager(mViewPager,true);
官方API强调,如果传入的第一个参数viewpager不为空,这个viewpager必须已经设置好PagerAdapter。

2.获取每个Tab标签对象
mTabLayout.getTabAt(position);

position从0开始,代表从左到右每个位置的Tab。获取了每个Tab对象之后,我们可以接着对这些Tab进行更多的操作:

2.1自定义Tab的布局

如果需要开发复杂的或者动态的tab,我们需要给tab传入自定义布局(比如:当有未读消息的时候,tab标签上会展示一个红点)

mTabLayout.getTabAt(position).setCustomView(view);

后面想要对某个tab中的某一控件进行具体操作也就简单了:

View view = mTabLayout.getTabAt(position).getCustomView().findViewById(R.id.xxx);


2.2 设置Tab的图标

虽然说对tab使用自定义布局可以解决大部分需求,不过有的时候我们并不需要这么复杂,而是仅仅需要插入一个图标。

mTabLayout.getTabAt(0).setIcon(drawable);

这样就可以在指定的tab中直接插入一个图标。图标默认显示在文字的上方。




ViewPager常用到的方法:

1. 给viewpager绑定换页的监听器。
mViewPager.addOnPageChangeListener(this);

注意这里不能使用setOnPageChangeListener,而要使用addOnPageChangeListener
ViewPager.OnPageChangeListener接口有三个方法:

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

    }

    @Override
    public void onPageSelected(int position) {

    }

    @Override
    public void onPageScrollStateChanged(int state) {

    }

这三个回调方法都好理解,其中用的最多的就是onPageSelected,position是第几个view,从0开始计算。


2.设置viewpager的预加载页数
mViewPager.setOffscreenPageLimit(3);

这个方法是设置viewpager当前view的左右两边的预加载的页面的个数,默认值是1
在源码中,这个值不能小于1,如果需要让viewpager不预加载,可能需要自定义viewpager并修改默认值。

3.设置适配器
mViewPager.setAdapter(adapter);

setAdapter是必不可少的,也很好理解,和ListView,RecyclerView设置adapter差不多。



PagerAdapter

和别的适配器一样,ViewPager通过PagerAdapter来获取每一页的内容。
下面是一个PagerAdapter的例子,我们只在ViewPager中展示RecyclerView

private List<String> title = new ArrayList<>();
        title.add("微信");
        title.add("通讯录");
        title.add("发现");
        title.add("我");
private List<RecyclerView> recyclerViewList = new ArrayList<>();


    class RecyclerViewPagerAdapter extends PagerAdapter{

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

        @Override
        public boolean isViewFromObject(View view, Object object) {
            return view == object;
        }

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

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            container.addView(recyclerViewList.get(position));
            return recyclerViewList.get(position);
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            container.removeView(recyclerViewList.get(position));
        }
    }

这里面比较重要的是getPageTitle,注意标题传入的顺序。别的都比较套路(Android里面控件的Adapter都是一些比较模式化的东西)。


FragmentPagerAdapter

FragmentPagerAdapter是PagerAdapter的子类,专门用于ViewPager内容全部为fragment的情况(这也是使用ViewPagerr的大部分场景)。

FragmentPagerAdapter有一个自己的方法getItem(int position),用于生成新的fragment。我们可以在这个函数中返回position处的fragment。

class MyAdapter extends FragmentPagerAdapter {
    public MyAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int position) {
        return null;
    }

    @Override
    public int getCount() {
        return 0;
    }
}

上面是一个崭新的FragmentPagerAdapter,可以看到FragmentPagerAdapter 必须有一个带参数的构造方法,参数为FragmentManager实例。

FragmentManager并不是陌生的东西,只要用到fragment的地方都会用到FragmentManager。通常获取FragmentManager的方法为getSupportFragmentManager(),但是,如果你是在一个fragment中使用FragmentPagerAdapter,这里就要使用getChildFragmetManager()



ViewPager中放置一个View

在ViewPager中放入fragment,只需要把所有Fragment的实例存入List<Fragment>,再将List传入FragmentPagerAdapter就行。

如果想在ViewPager中仅仅放入一个View,比如RecyclerView,也是一样的,将RecyclerView的实例存入List<RecyclerView>

如何获取RecyclerView的实例,我通常这么做:

RecyclerView recyclerView = (RecyclerView)getLayoutInflater().inflate(R.layout.xxx,null,false);

自定义RecyclerView的layout,然后通过LayoutInflater()传入空的recyclerView实例。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值