TabLayout的使用分享

来源:互联网 发布:手机知乎怎么修改答案 编辑:程序博客网 时间:2024/06/03 09:50

一、概述

相信大家实际开发中会经常碰到需要实现类似于网易新闻Tab标签效果的界面,为了加快开发效率,以前会经常使用到JakeWharton大神的开源框架Viewpager Indicator,框架好是好,但是毕竟比较旧了。其实Google官方也提供了一个TabLayout控件来实现类似的效果。

TabLayout是Google提供的design包中的一个控件,其实现的效果类似于Viewpager Indicator中TabPageIndicator的效果,但是也提供了更多的功能。与TabpagerIndicator相比,TabLayout的优势:

  • 使用更加方便
  • 可以方便的自定义Tab上显示的View
  • 提供了对Tab点击事件的监听方式(单次点击监听,重复点击监听)
  • Tab的指示器带一个动画效果
使用之前我们需要添加design包:
Android Studio中在Gradle中添加:compile 'com.android.support:design:23.1.0'
Eclipse则需要手动添加SDK下\extras\android\support\design\libs中的Jar包

二、TabLayout的使用

先来看看最简单的使用。我们先写这样一个布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical">    <android.support.design.widget.TabLayout        android:id="@+id/tab_layout"        android:layout_width="match_parent"        android:layout_height="wrap_content"        app:tabIndicatorColor="#00eeff"        app:tabSelectedTextColor="#00eeff"        app:tabTextColor="#000000" />    <android.support.v4.view.ViewPager        android:id="@+id/view_pager"        android:layout_width="match_parent"        android:layout_height="match_parent" /></LinearLayout>
我们可以看到TabLayout中使用了三个属性
   tabIndicatorColor            指示器(下划线)的颜色
   tabTextColor                    Tab文字颜色
   tabSelectedTextColor      Tab被选中时文字的颜色
然后给ViewPager写一个简单的适配器
public class TabPageAdapter extends PagerAdapter {    private List<ImageView> imageViews;    private String[] titles;    public TabPageAdapter(List<ImageView> imageViews, String[] titles) {        this.imageViews = imageViews;        this.titles = titles;    }    @Override    public int getCount() {        return imageViews.size();    }    @Override    public boolean isViewFromObject(View view, Object object) {        return view == object;    }    @Override    public Object instantiateItem(ViewGroup container, int position) {        container.addView(imageViews.get(position));        return imageViews.get(position);    }    @Override    public void destroyItem(ViewGroup container, int position, Object object) {        container.removeView(imageViews.get(position));    }    @Override    public CharSequence getPageTitle(int position) {        return titles[position];    }}
然后在MainActivity中写一下几行代码就可以实现效果
        //创建适配器        TabPageAdapter adapter = new TabPageAdapter(imageViewList, titles);        viewPager.setAdapter(adapter);        //把ViewPager和TabLayout关联        tabLayout.setupWithViewPager(viewPager);



setupWithViewPager()这个方法会在内部帮我们创建Tab添加到TabLayout,当然我们也可以手动自己添加
        for (int i = 0; i < 5; i++) {            TabLayout.Tab tab = tabLayout.newTab();            //为Tab设置文字            tab.setText(titles[i]);            //为Tab设置图标            tab.setIcon(R.mipmap.ic_launcher);            //为tab设置自定义显示布局            //tab.setCustomView(customView);            tabLayout.addTab(tab);        }        //创建适配器        TabPageAdapter adapter = new TabPageAdapter(imageViewList, titles);        viewPager.setAdapter(adapter);        //设置Tab显示填满布局        tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);        //设置Tab滚动模式为默认        tabLayout.setTabMode(TabLayout.MODE_FIXED);        //设置指示器高度        tabLayout.setSelectedTabIndicatorHeight(10);
但这个时候我们就不能使用setupWithViewPager()来使TabLayout和ViewPager关联了,我们必须分别为ViewPager和TabLayout设置监听来实现关联
        tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {            @Override            public void onTabSelected(TabLayout.Tab tab) {                viewPager.setCurrentItem(tab.getPosition());            }            @Override            public void onTabUnselected(TabLayout.Tab tab) {            }            @Override            public void onTabReselected(TabLayout.Tab tab) {<span style="white-space:pre"></span>//当tab被重复选择时回调的方法            }        });        viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {            @Override            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {                //如果想要指示器随着ViewPager一起滑动就使用此方法                //第三个参数设置为true,表示滑动后更新tab的选择状态                //就不需要在onPageSelected中写代码了                tabLayout.setScrollPosition(position, positionOffset, true);            }            @Override            public void onPageSelected(int position) {//                tabLayout.getTabAt(position).select();            }            @Override            public void onPageScrollStateChanged(int state) {            }        });
那为什么自己添加tab后不能用setupWithViewPager()呢?我们先来看看源码
        public void setupWithViewPager(@NonNull ViewPager viewPager) {        final PagerAdapter adapter = viewPager.getAdapter();        if (adapter == null) {            throw new IllegalArgumentException("ViewPager does not have a PagerAdapter set");        }        // First we'll add Tabs, using the adapter's page titles        setTabsFromPagerAdapter(adapter);        // Now we'll add our page change listener to the ViewPager        viewPager.addOnPageChangeListener(new TabLayoutOnPageChangeListener(this));        // Now we'll add a tab selected listener to set ViewPager's current item        setOnTabSelectedListener(new ViewPagerOnTabSelectedListener(viewPager));        // Make sure we reflect the currently set ViewPager item        if (adapter.getCount() > 0) {            final int curItem = viewPager.getCurrentItem();            if (getSelectedTabPosition() != curItem) {                selectTab(getTabAt(curItem));            }        }    }    public void setTabsFromPagerAdapter(@NonNull PagerAdapter adapter) {        removeAllTabs();        for (int i = 0, count = adapter.getCount(); i < count; i++) {            addTab(newTab().setText(adapter.getPageTitle(i)));        }    }
这样原因就很明显了setupWithViewPager()中会调用setTabsFromPageAdapter()方法,而这个方法中会清空TabLayout中已经添加的Tab,然后再根据传入的适配器确定Tab的个数重新添加Tab和根据adapter中getPageTitle()设置Tab的标签。所以如果你为Tab设置的自定义View无法显示时,很有可能就是你在设置自定义View后误用了setupWithViewPager()或setTabsFromPageAdapter()方法。




1 0
原创粉丝点击