MyException - 我的异常网
当前位置:我的异常网» Android » Android使用TabLayout与ViewPager组合以及TabItem自

Android使用TabLayout与ViewPager组合以及TabItem自定义

www.MyException.Cn  网友分享于:2013-09-19  浏览:0次
Android使用TabLayout与ViewPager结合以及TabItem自定义

使用android的design支持包中的android.support.design.widget.TabLayout结合ViewPager/Fragment来写多Tab的应用,只需要一句代码,就可以完成Tab与ViewPager切换的联动,免除很多麻烦。

mTabLayout.setupWithViewPager(mViewPager);

 

先写个主布局文件,只需要加入ViewPager和TabLayout即可,Tab可在ViewPager上方,也可在下方,看各自需求:

<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:clipToPadding="true"
    android:orientation="vertical">

    <android.support.v4.view.ViewPager
        android:id="@+id/container_viewpager"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:background="@color/color_white" />

    <android.support.design.widget.TabLayout
        android:id="@+id/tab_layout"
        android:layout_width="match_parent"
        android:layout_height="@dimen/tabbar_def_height"
        app:tabBackground="@color/color_f7f7f7"
        app:tabIndicatorHeight="@dimen/margin_0"
        app:tabMode="fixed" />
</LinearLayout>

 

在java代码中,ViewPager按常规设置个PagerAdapter就有效果了,但需要和Tab关联,需要加上setupWithViewPager()的调用:

 

mViewPager = (ViewPager) findViewById(R.id.container_viewpager);
mTabLayout = (TabLayout) findViewById(R.id.tab_layout);

...

mViewPager.setAdapter(pagerAdapter);
mTabLayout.setupWithViewPager(mViewPager);
 

 

如此之后发现,ViewPager可以正常使用,TabLayout的标题却没有显示,这时,如果TabLayout上只需要显示文字标题,就很容易了,在我们自定义的PagerAdapter里重写getPageTitle方法,TabLayout与ViewPager结合以后它会从这里读取内容去显示:

 

public class MainPagerAdapter extends FragmentPagerAdapter {

    ...    

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

 

Tab的标题显示出来了,联动也可以了,样式的话,在TabLayout控件的属性里设置就行了。什么?标题光有文字还不够?那也可以,只想在上方加个图标,弄个仿微信样式的话也不需要自定义布局文件,主要有两种办法,第一是在setupWithViewPager之后,把循环给单个Tab设置icon:

 

mTabLayout.setupWithViewPager(mViewPager);

mTabLayout.getTabAt(0).setIcon(R.mipmap.ic_launcher);
mTabLayout.getTabAt(1).setIcon(R.mipmap.ic_launcher);
mTabLayout.getTabAt(2).setIcon(R.mipmap.ic_launcher);

 

另一种办法可以直接把Tab布局写死,使用控件android.support.design.widget.TabItem即可,形如:

 

<android.support.design.widget.TabLayout
        android:id="@+id/tablayout"
        android:background="@color/colorPrimary"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <android.support.design.widget.TabItem
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Android"/>

        <android.support.design.widget.TabItem
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:icon="@mipmap/ic_launcher"/>
    </android.support.design.widget.TabLayout>
 

 

如此操作,效果也是可以给TabItem设置一个图标和一个文字标题。当然,如果想要定制更加复杂的TabLayout,同样是先获取Tab,给它设置自定义View即可:

 

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

 

自定义的完整代码如下:

首先我自定义了一个结构TabItemInfo,用于方便用代码添加Tab和ViewPager的Item,一看便明了:

 

public class TabItemInfo {
    private Class<? extends Fragment> fragmentClass;
    private int nameResource;
    private int iconResource;

    public TabItemInfo(Class<? extends Fragment> fragmentClass, @StringRes int nameResource,
                       @DrawableRes int iconResource) {
        this.fragmentClass = fragmentClass;
        this.nameResource = nameResource;
        this.iconResource = iconResource;
    }

    public Class<? extends Fragment> getFragmentClass() {
        return fragmentClass;
    }

    public int getNameResource() {
        return nameResource;
    }

    public int getIconResource() {
        return iconResource;
    }
}
 

 

PagerAdapter,无奇特之处,只是多加了一个根据position来获取自定义TabView的方法,以便在Activity里设置TabLayout的时候可以方便获取:

 

public class MainPagerAdapter extends FragmentPagerAdapter {

    private Context mContext;
    private List<TabItemInfo> mTabItems;

    public MainPagerAdapter(Context context, FragmentManager fm, List<TabItemInfo> tabItems) {
        super(fm);
        mContext = context;
        mTabItems = tabItems;
    }

    @Override
    public Fragment getItem(int position) {
        try {
            return mTabItems.get(position).getFragmentClass().newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return null;
    }

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

    public View getTabView(int position) {
        TabItemInfo itemInfo = mTabItems.get(position);
        View view = LayoutInflater.from(mContext).inflate(R.layout.custom_view_tab_item, null);
        TextView tv = (TextView) view.findViewById(R.id.tab_text);
        tv.setText(itemInfo.getNameResource());
        ImageView img = (ImageView) view.findViewById(R.id.tab_image);
        img.setImageResource(itemInfo.getIconResource());
        return view;
    }
}
 

 

 在Activity里设置ViewPager和TabLayout:

mViewPager = (ViewPager) findViewById(R.id.container_viewpager);
mTabLayout = (TabLayout) findViewById(R.id.tab_layout);

List<TabItemInfo> tabItems = new LinkedList<>();
tabItems.add(new TabItemInfo(CashLoanFragment.class, R.string.cash_loan, R.drawable.apply_tab_icon_drawable));
tabItems.add(new TabItemInfo(GoodsLoanFragment.class, R.string.apply_credit, R.drawable.phone_tab_icon_drawable));
tabItems.add(new TabItemInfo(UserCenterNewFragment.class, R.string.user_center, R.drawable.my_tab_icon_drawable));

MainPagerAdapter pagerAdapter = new MainPagerAdapter(this, getSupportFragmentManager(), tabItems);
mViewPager.setAdapter(pagerAdapter);
mTabLayout.setupWithViewPager(mViewPager);
for (int i = 0; i < mTabLayout.getTabCount(); i++) {
    TabLayout.Tab tab = mTabLayout.getTabAt(i);
    if (tab != null) {
        tab.setCustomView(pagerAdapter.getTabView(i));
    }
}

 

这样之后,自定义的TabItemView就设置好了,注意,自定义的布局里,background,textColor之类的,可以用selector指定好选中状态和非选中状态的不同资源,这样TabLayout左右切换的时候,才会有效果。

 

文章评论

一个程序员的时间管理
一个程序员的时间管理
Java程序员必看电影
Java程序员必看电影
2013年中国软件开发者薪资调查报告
2013年中国软件开发者薪资调查报告
中美印日四国程序员比较
中美印日四国程序员比较
我跳槽是因为他们的显示器更大
我跳槽是因为他们的显示器更大
科技史上最臭名昭著的13大罪犯
科技史上最臭名昭著的13大罪犯
不懂技术不要对懂技术的人说这很容易实现
不懂技术不要对懂技术的人说这很容易实现
看13位CEO、创始人和高管如何提高工作效率
看13位CEO、创始人和高管如何提高工作效率
每天工作4小时的程序员
每天工作4小时的程序员
那些性感的让人尖叫的程序员
那些性感的让人尖叫的程序员
如何成为一名黑客
如何成为一名黑客
程序员眼里IE浏览器是什么样的
程序员眼里IE浏览器是什么样的
Web开发者需具备的8个好习惯
Web开发者需具备的8个好习惯
亲爱的项目经理,我恨你
亲爱的项目经理,我恨你
团队中“技术大拿”并非越多越好
团队中“技术大拿”并非越多越好
Google伦敦新总部 犹如星级庄园
Google伦敦新总部 犹如星级庄园
Java 与 .NET 的平台发展之争
Java 与 .NET 的平台发展之争
10个帮程序员减压放松的网站
10个帮程序员减压放松的网站
什么才是优秀的用户界面设计
什么才是优秀的用户界面设计
十大编程算法助程序员走上高手之路
十大编程算法助程序员走上高手之路
5款最佳正则表达式编辑调试器
5款最佳正则表达式编辑调试器
老程序员的下场
老程序员的下场
程序员都该阅读的书
程序员都该阅读的书
聊聊HTTPS和SSL/TLS协议
聊聊HTTPS和SSL/TLS协议
初级 vs 高级开发者 哪个性价比更高?
初级 vs 高级开发者 哪个性价比更高?
代码女神横空出世
代码女神横空出世
 程序员的样子
程序员的样子
60个开发者不容错过的免费资源库
60个开发者不容错过的免费资源库
旅行,写作,编程
旅行,写作,编程
“懒”出效率是程序员的美德
“懒”出效率是程序员的美德
“肮脏的”IT工作排行榜
“肮脏的”IT工作排行榜
程序员和编码员之间的区别
程序员和编码员之间的区别
我是如何打败拖延症的
我是如何打败拖延症的
总结2014中国互联网十大段子
总结2014中国互联网十大段子
程序员最害怕的5件事 你中招了吗?
程序员最害怕的5件事 你中招了吗?
当下全球最炙手可热的八位少年创业者
当下全球最炙手可热的八位少年创业者
编程语言是女人
编程语言是女人
写给自己也写给你 自己到底该何去何从
写给自己也写给你 自己到底该何去何从
我的丈夫是个程序员
我的丈夫是个程序员
老美怎么看待阿里赴美上市
老美怎么看待阿里赴美上市
Web开发人员为什么越来越懒了?
Web开发人员为什么越来越懒了?
程序员周末都喜欢做什么?
程序员周末都喜欢做什么?
2013年美国开发者薪资调查报告
2013年美国开发者薪资调查报告
做程序猿的老婆应该注意的一些事情
做程序猿的老婆应该注意的一些事情
那些争议最大的编程观点
那些争议最大的编程观点
漫画:程序员的工作
漫画:程序员的工作
要嫁就嫁程序猿—钱多话少死的早
要嫁就嫁程序猿—钱多话少死的早
10个调试和排错的小建议
10个调试和排错的小建议
程序猿的崛起——Growth Hacker
程序猿的崛起——Growth Hacker
软件开发程序错误异常ExceptionCopyright © 2009-2015 MyException 版权所有