TabLayout与ViewPager同步后Tab的标题不显示
一、概述
1.1 问题描述
TabLayout+ViewPager后,TabLayout的TabItem不显示的问题:
1.2 截图

二、结论
mTabs.setupWithViewPager(mViewPager); 语句的功能是:
- 将 TabLayout、ViewPager 的监听事件同步
- 对 TabLayout 的适配器进行重置
- 对 TabLayout 的 TabItem 进行重置
- 从 ViewPager 的 Adapter 中读取到每一页的标题,并为之创建 TabItem 添加到 TabLayout 中
解决方案是:
重写在 mViewPager 的 Adapter 中的如下方法,将每页的 Title 设置好:
	mViewPager.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager()) {
        @Override
        public Fragment getItem(int position) {
			return mFragmentList.get(position);
		}
		@Override
		public int getCount() {
			return mFragmentList.size();
		}
		@Override
		public CharSequence getPageTitle(int position) {
			return mTitle[position];
		}
	});

三、问题探究
3.1 设置的代码
mFragmentList.add(longFragment);
mFragmentList.add(shortFragment);
mViewPager.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager()) {
	@Override
	public Fragment getItem(int position) {
		return mFragmentList.get(position);
	}
	@Override
	public int getCount() {
		return mFragmentList.size();
	}
});
mTabs.setupWithViewPager(mViewPager);
上面是非常常见的一段代码,主要逻辑是,将承载两个Fragment的ViewPager与TabLayout同步起来。
其中,核心语句是:
	mTabs.setupWithViewPager(mViewPager);
3.2 查看 TabLayout 的相关源码
进入源码查看到:
	public void setupWithViewPager(@Nullable final ViewPager viewPager) {
        if (mViewPager != null && mPageChangeListener != null) {
            // If we've already been setup with a ViewPager, remove us from it
            mViewPager.removeOnPageChangeListener(mPageChangeListener);
        }
        if (viewPager != null) {
            final PagerAdapter adapter = viewPager.getAdapter();
            if (adapter == null) {
                throw new IllegalArgumentException("ViewPager does not have a PagerAdapter set");
            }
            mViewPager = viewPager;
            // Add our custom OnPageChangeListener to the ViewPager
            if (mPageChangeListener == null) {
                mPageChangeListener = new TabLayoutOnPageChangeListener(this);
            }
            mPageChangeListener.reset();
            viewPager.addOnPageChangeListener(mPageChangeListener);
            // Now we'll add a tab selected listener to set ViewPager's current item
            setOnTabSelectedListener(new ViewPagerOnTabSelectedListener(viewPager));
            // Now we'll populate ourselves from the pager adapter
            setPagerAdapter(adapter, true);
        } else {
            // We've been given a null ViewPager so we need to clear out the internal state,
            // listeners and observers
            mViewPager = null;
            setOnTabSelectedListener(null);
            setPagerAdapter(null, true);
        }
    }
也比较明了,无非是先做一系列的判断,然后修改 TabLayout与ViewPager的各种监听事件。
进入 setPagerAdapter 查看到如下方法:
	private void setPagerAdapter(@Nullable final PagerAdapter adapter, final boolean addObserver) {
        if (mPagerAdapter != null && mPagerAdapterObserver != null) {
            // If we already have a PagerAdapter, unregister our observer
            mPagerAdapter.unregisterDataSetObserver(mPagerAdapterObserver);
        }
        mPagerAdapter = adapter;
        if (addObserver && adapter != null) {
            // Register our observer on the new adapter
            if (mPagerAdapterObserver == null) {
                mPagerAdapterObserver = new PagerAdapterObserver();
            }
            adapter.registerDataSetObserver(mPagerAdapterObserver);
        }
        // Finally make sure we reflect the new adapter
        populateFromPagerAdapter();
    }
该方法的主要功能是设置TabLayout的适配器,populateFromPagerAdapter();方法引人注目。
	private void populateFromPagerAdapter() {
        removeAllTabs();
        if (mPagerAdapter != null) {
            final int adapterCount = mPagerAdapter.getCount();
            for (int i = 0; i < adapterCount; i++) {
				// 从 PagerAdapter 中获取到标题,并新建 Tab 加入到空的 TabLayout 中
                addTab(newTab().setText(mPagerAdapter.getPageTitle(i)), false);
            }
            // Make sure we reflect the currently set ViewPager item
            if (mViewPager != null && adapterCount > 0) {
                final int curItem = mViewPager.getCurrentItem();
                if (curItem != getSelectedTabPosition() && curItem < getTabCount()) {
                    selectTab(getTabAt(curItem));
                }
            }
        } else {
            removeAllTabs();
        }
    }
该方法中removeAllTabs();将所有的Tabs移除了,找到问题的关键!
同时,addTab(newTab().setText(mPagerAdapter.getPageTitle(i)), false);给了我们答案。
3.4 跳转到 PagerAdapter 的源码
再仔细看看 getPageTitle 这个方法:
	public CharSequence getPageTitle(int position) {
        return null;
    }
所以,知道为什么为空了吧!
3.4 结论
综上,mTabs.setupWithViewPager(mViewPager);语句的功能是:
- 将 TabLayout、ViewPager 的监听事件同步
- 对 TabLayout 的适配器进行重置
- 对 TabLayout 的 TabItem 进行重置
- 从 ViewPager 的 Adapter 中读取到每一页的标题,并为之创建 TabItem 添加到 TabLayout 中
3.5 解决方案
重写 getPageTitle 方法:
	mViewPager.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager()) {
        @Override
        public Fragment getItem(int position) {
			return mFragmentList.get(position);
		}
		@Override
		public int getCount() {
			return mFragmentList.size();
		}
		@Override
		public CharSequence getPageTitle(int position) {
			return mTitle[position];
		}
	});
此文在我的 Github Pages 上同步发布,地址为:TabLayout与ViewPager同步后Tab的标题不显示
TabLayout与ViewPager同步后Tab的标题不显示的更多相关文章
- TabLayout+Fragment+ViewPager+FragmentStatePagerAdapter实现Tab标签
		首先来看下实现的效果吧: 最近在项目中实现这个效果的时候.尽管自己磕磕绊绊的实现了,可是知识确实模模糊糊的,今天天气异常的冷,在加上这个知识不太熟练,实在是没有心情进行接下来的计划,干脆借着这个时间, ... 
- TabLayout:另一种Tab的实现方式
		http://blog.csdn.NET/aigestudio/article/details/47155769 在5.0以前我们想要实现像网易新闻客户端那样的的Tab可以有很多种选择: 比如古老的T ... 
- TabLayout和ViewPager
		这里就说下tablayout+viewpager的实现方式:tablayout是android5.0推出来的一个MaterialDesign风格的控件,是专门用来实现tab栏效果的:功能强大,使用方便 ... 
- TabLayout和ViewPager简单实现页卡的滑动
		首先需要在当前的module中的build Gradle的 dependencies中加入以下句子 compile 'com.android.support:design:23.0.1' 因为我们用到 ... 
- TabLayout和ViewPager联动时的问题及解决方案
		问题概述 TabLayout搭配ViewPager关联使用时,在未调用TabLayout的setupWithViewPager(mViewPager)方法之前,ViewPager的内容和TabLayo ... 
- Android两种为ViewPager+Fragment添加Tab的方式
		在Android开发中ViewPager的使用是非常广泛的,而它不仅仅能够实现简单的开始引导页,还可以结合Fragment并添加Tab作为选项卡或为显示大批量页面实现强大的顺畅滑动 下面介绍两种为Vi ... 
- 关于TabLayout与ViewPager在Fragment中嵌套Fragment使用或配合使用的思考
		注意: 因为继承的是Fragment,所以getSupportFragmentManager()与getFragmentManager()方法无法使用,这里需要用到getChildFragmentMa ... 
- Android  使用TabLayout、ViewPager和Fragment实现顶部菜单可滑动切换
		效果图如下 首先,要使用控件需要添加design library,在Android Studio中添加 compile 'com.android.support:design:23.4.0' 然后是布 ... 
- 巧力避免ViewPager的预加载数据,Tablayout+Fragment+viewPager
		问题描述 最近在进行一个项目的开发,其中使用到了Tablayout+Fragment+viewPager来搭建一个基本的框架,从而出现了设置数据适配器的时候,item的位置错乱问题.我打印log日志的 ... 
随机推荐
- 在WPF中弹出右键菜单时判断鼠标是否选中该项
			和上篇在WPF的TreeView中实现右键选定一样,这仍然是一个右键菜单的问题: 这个需求是在一个实现剪贴板的功能的时候遇到的:在弹出右键菜单时,如果菜单弹出位置在ListViewItem中时,我 ... 
- JavaScript第三天 boolean和json
			布尔值 true:非零数字.非空字符串.非空对象 false:数字零.空字符串.null空对象.undefined json JSON(JavaScript Object Notation) 是一种 ... 
- Mongodb默认开启与关闭
			默认启动: $ ./mongodb 默认数据保存路径:/data/db/ 默认端口:27017 修改默认路径: --dbpath $ ./mongdb --dbpath /mongod ... 
- HDU 2159  FATE(二维全然背包)
			中文题目就不用解释了 就是裸的二维全然背包 d[i][j]表示消耗i忍耐杀j个怪最多可获得的经验 然后就用全然背包来做了 二维背包背包只是是多了一重循环 <span style=&quo ... 
- __file__
			__file__ 是 python 的内置变量它的值等于文件名本身 [root@localhost ~]$ cat test.py #!/usr/bin/env python print(__file ... 
- python中的coding的格式书写形式
			# -*- coding:utf-8 -*-可以改写成以下各种形式:1,# -*- coding=utf-8 -*-2,# _*_ coding=utf-8 _*_3,# coding:utf-84 ... 
- 【BZOJ3622】已经没有什么好害怕的了 容斥+DP
			[BZOJ3622]已经没有什么好害怕的了 Description Input Output Sample Input 4 2 5 35 15 45 40 20 10 30 Sample Output ... 
- C++编译遇到参数错误(cannot convert parameter * from 'const char [**]' to 'LPCWSTR')
			转:http://blog.sina.com.cn/s/blog_9ffcd5dc01014nw9.html 前面的几天一直都在复习着被实习落下的C++基础知识.今天在复习着上次创建的窗口程序时,出现 ... 
- 关于navicat 系列软件一点击菜单栏就闪退
			navicat 系列软件一点击菜单栏就闪退 多次卸载安装都出现了闪退的现象 后来发现,原来是启动了有道词典屏幕取词才会出现这种现象,关了有道就没事. 
- kibana5.6源码分析2
			1.启动shell脚本:/bin/kibana; js脚本:/src/cli/cli.js; 2.服务端入口:/src/server/kbn_server.js.使用的web框架为hapi.js. ... 
