Google官方在14年Google I/O上推出了全新的设计语言——Material Design。一并推出了一系列实现Material Design效果的控件库——Android Design Support Library。其中,有TabLayout, NavigationView,Floating labels for editing text,Floating Action Button,Snackbar, CoordinatorLayout, CollapsingToolbarLayout等等控件。在今后的学习中,我将一一介绍它们的特点和用法。

我们可以使用三方开源的PagerSlidingTabStrip去实现,或者viewpagerindicator,我一般都偏向前者。现在我们可以使用Design support library库的TabLayout去实现了。

Demo地址:https://github.com/WeiShuaiDev/TabLayout

Demo首页图:

最终的效果图:

一、TabLayout基本使用 。

1.在应用的Build.gradle中添加support.design支持库(注意:必须和v7包的版本相同)。

2.TabLayout第一种使用–Tab固定模式

1)创建布局文件activity_short_tab,在布局文件中添加TabLayout及ViewPager。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:id="@+id/activity_main"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context="com.linwei.lw.tablayoutdemo.ui.activity.MainActivity"><android.support.design.widget.TabLayoutandroid:id="@+id/tab"android:layout_width="match_parent"android:layout_height="wrap_content"app:tabIndicatorColor="@color/colorAccent"app:tabIndicatorHeight="2dp"app:tabMode="fixed"app:tabSelectedTextColor="@color/colorAccent"></android.support.design.widget.TabLayout><android.support.v4.view.ViewPagerandroid:id="@+id/viewpager"android:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="1"></android.support.v4.view.ViewPager></LinearLayout>

2)定义一个FragmentFactivity的Fragment工厂类,专门生产Fragment对象(用了工厂类,方便Fragment使用,提高了性能,在项目中很常见,记得在android5.0的Demo中也是怎么写的,可能有些读者觉得没必要,也可以每次去创建Fragment,并添加到ViewPager中也可)。

package com.linwei.lw.tablayoutdemo.ui.fragment;import java.util.HashMap;/*** Fragment工厂类。* Created by LW on 2017/4/20.*/public class FragmentFactory {private static HashMap<Integer, BaseFragment> mBaseFragments = new HashMap<Integer, BaseFragment>();public static BaseFragment createFragment(int pos) {BaseFragment baseFragment = mBaseFragments.get(pos);if (baseFragment == null) {switch (pos) {case 0:baseFragment = new TopLineFragment();//头条break;case 1:baseFragment = new NewsFragment();//要闻break;case 2:baseFragment = new EntertainmentFragment();//娱乐break;case 3:baseFragment = new SportsFragment();//体育break;case 4:baseFragment = new FinanceFragment();//财经break;case 5:baseFragment = new ScienceFragment();//科技break;case 6:baseFragment = new ModeFragment();//时尚break;case 7:baseFragment = new VideoFragment();//视频break;case 8:baseFragment = new  DirectSeedingFragment();//直播break;}mBaseFragments.put(pos, baseFragment);}return baseFragment;}
}

3)定义一个Fragment的父类BaseFragment,我就不解释了看代码。

package com.linwei.lw.tablayoutdemo.ui.fragment;import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;/*** Created by LW on 2017/4/20.*/public abstract class BaseFragment extends Fragment {protected Context mContent;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);mContent = getContext();//上下文。}@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {return initView();//初始化布局。}@Overridepublic void onActivityCreated(Bundle savedInstanceState) {super.onActivityCreated(savedInstanceState);loadData();//初始化数据。}protected abstract void loadData();protected abstract View initView();
}

4)BaseFragment的实现子类TopLineFragment,这里我就只列出一个子类代码,其他子类代码也是一样的。

package com.linwei.lw.tablayoutdemo.ui.fragment;import android.graphics.Color;
import android.view.Gravity;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;/*** Created by LW on 2017/4/21.*/
public class TopLineFragment extends BaseFragment {@Overrideprotected void loadData() {Toast.makeText(mContent,"Fragment头条加载数据",Toast.LENGTH_SHORT).show();}@Overrideprotected View initView() {TextView mView = new TextView(mContent);mView.setText("Fragment头条");mView.setGravity(Gravity.CENTER);mView.setTextSize(18);mView.setTextColor(Color.BLACK);return mView;}
}

5)arrays.xml中第一显示数据。我了方便使用,通过字符串数组定义起来。

<?xml version="1.0" encoding="utf-8"?>
<resources><string-array name="tab_short_Title"><item>头条</item><item>要闻</item><item>娱乐</item><item>体育</item></string-array><string-array name="tab_long_Title"><item>头条</item><item>要闻</item><item>娱乐</item><item>体育</item><item>财经</item><item>科技</item><item>时尚</item><item>视频</item><item>直播</item></string-array>
</resources>

6)ShortTabActivity类,实现TabLayout和ViewPager的业务逻辑。

package com.linwei.lw.tablayoutdemo.ui.activity;import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;import com.linwei.lw.tablayoutdemo.R;
import com.linwei.lw.tablayoutdemo.Utils.CommentUtils;
import com.linwei.lw.tablayoutdemo.ui.fragment.BaseFragment;
import com.linwei.lw.tablayoutdemo.ui.fragment.FragmentFactory;public class ShortTabActivity extends AppCompatActivity {private TabLayout mTab;private ViewPager mViewPager;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_short_tab);initView();initData();}private void initData() {ShortPagerAdapter adapter = new ShortPagerAdapter(getSupportFragmentManager());mViewPager.setAdapter(adapter);mTab.setupWithViewPager(mViewPager);}private void initView() {mTab = (TabLayout) findViewById(R.id.tab);mViewPager = (ViewPager) findViewById(R.id.viewpager);}private class ShortPagerAdapter extends FragmentPagerAdapter {public String[] mTilte;public ShortPagerAdapter(FragmentManager fm) {super(fm);mTilte = getResources().getStringArray(R.array.tab_short_Title);}@Overridepublic CharSequence getPageTitle(int position) {return mTilte[position];}@Overridepublic BaseFragment getItem(int position) {BaseFragment fragment = FragmentFactory.createFragment(position);return fragment;}@Overridepublic int getCount() {return CommentUtils.TAB_SHORT_COUNT;}}
}

3.TabLayout第二种使用–Tab滚动模式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FVb4VM4w-1590030518439)(https://img-blog.csdn.net/20170422164745063?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcGVyc2lzdGVuY2VfbHc=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)]

1)Tab滚动模式和Tab固定模式差不多,只是Apdater中的getCount的个数和app:tabMode发生改变,这里我就不从新写了,把发生改变写出来,如果想看Demo,下面有地址。

1.1)TabMode属性从fill改为scrollable

1.2)适配器中getCount个数。

二、TabLayout高级使用(只列出改变代码内容) 。

4.TabLayout第三种使用–Tab图片显示


1)实现Tab图片显示,只需要改变ImagePagerAdapter适配器中getpageTitle方法,下面是关键代码。

1.1)把图片的id放在数组中,方便对图片使用 。


1.2)getPageTitle()方法,用于Tab显示方式定义,是显示图片关键的代码。


1.3)apader适配器显示个数。


1.4)此时,设置完之后运行,发现Tab上并没有显示图标,而是什么也没有了。这是因为TabLayout的textAllCaps属性默认值是true,会阻止ImageSpan的渲染,我们只需要将其重写为false即可。

1.4.1)对TabLayout抽取出样式,并对样式调用。


1.4.2)对textAllCaps设置和TabLayout样式定义。

5.TabLayout第四种使用–Tab图片和文字显示

1)获取图片和文字资源。

2)对Tab图片和文字设置。

6.TabLayout第五种使用–自定义View


1)对适配器CustomAdapter中getPageTitle返回null


2)在适配器中定义一个方法getTabView(int position),只要对自定义布局调用和数据设置。

3.对TabLayout中获取每个标签,并调用指定getTabView,通过setCustom设置给当前Tab。

三、TabLayout源码分析。

上面我们使用了自定义View作为Tab,但是有个问题上没有处理,就是Tab在选中时候的高亮状态。如果使用文本Tab,我们可以设置Style中的tabSelectedTextColor来实现,那么想一想TabLayout是在什么时机使用这个资源值的?我们是否也可以在此时机改变自定义View的显示来标记选中。

上面我们使用了自定义View作为Tab,但是有个问题上没有处理,就是Tab在选中时候的高亮状态。如果使用文本Tab,我们可以设置Style中的tabSelectedTextColor来实现,那么想一想TabLayout是在什么时机使用这个资源值的?我们是否也可以在此时机改变自定义View的显示来标记选中。

可以看到,给ViewPager添加,注意是添加而不是设置,说明现在ViewPager可以添加任意个页面改变监听器了。与PagerSlidingTabTrip的设置方式相比较,这种方式更好了,看来代码与时俱进还是很重要的,使用TabLayout还是值得的。

好了,放弃题外话,继续关注TabLayoutOnPageChangeListener的实现,关注onPageSelected()方法:

当ViewPager的页面改变时会调用selectTab()方法:

当新的选中Tab与当前不同时,调用了setSelectedTabView()方法:

最后,重新设置了每个TabView的选中状态。也就说,当选中某个Tab时,我们对应的自定义View的setSelected()方法就会调用。所以,当需要根据Tab是否选中更新自定义View的状态时,可以重写setSelected()方法:

好了,分析完毕,原谅我这个标题党,我只想简单分析如何根据Tab是否选中更新自定义View的状态。对于源码感兴趣的,可以自行前往研究…

四、app:tabMode和app: tabGravity比较

Android Material Design 中的TabLayout有两个比较有用的属性 app:tabMode、app:tabGravity。

(1)app:tabMode有两个值:fixed和scrollable。

(2)app:tabGravity有两个值:fill和center。

比较常用的是app:tabMode设置值scrollable,以及app:tabGravity设置值center。
比如,当app:tabMode设置值scrollable表示此TabLayout中当子view超出屏幕边界时候,将提供滑动以便滑出不可见的那些子view。
而app:tabGravity设置值center,在有些情况下,比如TabLayout中子view较少需要居中显示时候的情景。
现在给出一个例子加以说明。
1)tabGravity="fill"和tabMode=“fixed”

2)tabGravity="center"和tabMode=“fixed”

3)tabGravity="fill"和tabMode=“scrollable”

4)tabGravity="cente"和tabMode=“scrollable”

最后,附上源码地址:https://github.com/setasmallgoal/TabLayoutDemo

TabLayout的用法进行总结和归纳相关推荐

  1. try的动词用法_try的用法及短语-try的7种用法-try的短语归纳

    宜城教育资源网www.ychedu.com try的用法及短语-try的7种用法-try的短语归纳 try的用法 1.try可作"审讯""审理"解,指人的罪过与 ...

  2. android design library提供的TabLayout的用法

    在开发中,我们常常需要ViewPager结合Fragment一起使用,如下图: 1 我们可以使用三方开源的PagerSlidingTabStrip去实现,或者viewpagerindicator,我一 ...

  3. 中by的用法_经常混淆的介词at、on、in、by用法细讲,收藏学习

    关注我,每日推送小学到初中各科学习.记忆方法.各科详细资料,帮助孩子轻松拿高分! 今天这篇文章主要讲的是英语中的介词.高老师记得,在初中的学英语的时候,经常容易混淆的就是这些介词(in.on.at), ...

  4. call和calling的用法_Call用法小结

    call既可用作动词,又可用作名词? call用作动词时,既可作及物动词用,也可作不及物动词用?现对其用法作一简单归纳: 一? 用作及物动词时有以下意义: 1. 叫;呼唤;叫来?例如: Call a ...

  5. consider的用法

    consider的用法 consider大致有两种含义.含义不同,用法有别.现归纳如下. 一.consider作"考虑"解,常用于以下句型: 1. Consider+名词/代词/动 ...

  6. 数据之路 Day8 Matplotlib包

    Matplotlib 中文文档 https://www.kesci.com/home/column/5b87a78131902f000f668549?from=zhihu 基本用法¶ 本章知识点归纳如 ...

  7. python绘制曲线y=2x+5_Python数据可视化:Matplotlib绘图详解(二)

    上一章节我们学习了matplotlib的基本用法和坐标轴设置方面的一些内容,这节课,我们要学习在图中添加图例与标注. 基本用法 本章知识点归纳如下: 1.添加图例:plt.legend() 2.画点: ...

  8. C++中四种类型转换运算符的使用方法

    C++的四个类型转换运算符已经有很久了,但一直没有弄清楚它们的用法,今天看到一本书上的解释,才大致地的了解了其具体的用法. 具体归纳如下: reinterpret_cast 该函数将一个类型的指针转换 ...

  9. 【C#】使用COM组件操作Excel

    项目中常常会涉及到对Excel的读写,设置格式的操作,通常的情况下,我会使用开源的第三方组件NPOI,因为它高效轻便.当然,Excel的读写还有其他很多方式,这里不再一一列举. 但遇到一些稍微复杂的情 ...

最新文章

  1. 使用ubuntu(18.04) 作为软路由器连接互联网
  2. LeetCode 25. K 个一组翻转链表
  3. 智能车竞赛技术报告 | 智能车视觉 - 上海工程技术大学 - 萌鸡小队
  4. 「android」查看应用占用cpu和内存消耗情况
  5. 深入探索 Java 热部署--转
  6. 23、Power Query-XML与JSON数据获取
  7. csharp为何不流行_【经营】做餐饮,算好加减法,你不赚谁赚
  8. java8中的lambda用法实例
  9. Blazor 机制初探以及什么是前后端分离,还不赶紧上车?
  10. 如何将word中的对象怎么显示到工具栏_职场必备!Word实用技巧最全总结(五)...
  11. nvme驱动_用户态NVMe运维利器 SPDK NVMe 字符设备
  12. BZOJ 1053: [HAOI2007]反素数ant
  13. 文本生成系列之transformer结构扩展(三)
  14. 转:MSSQL SERVER行转列 列转行
  15. 人工智能进场 AR/VR何去何从?
  16. houdini大神自诉:为什么我要放弃maya I
  17. 2021年中国生育保险参保人数及待遇情况分析:广东省参保人数、享受生育保险待遇人次均居全国首位[图]
  18. [内存泄漏]pppd程序导致的内存泄漏
  19. 展望下未来的计算机400字,展望未来的作文400字
  20. TP-Link家用路由器上网与防蹭网

热门文章

  1. 百度AI---人脸对比(前端拍照上传后端进行对比,后端调用百度接口返回对比信息)
  2. 基于迁移学习的脑肿瘤自动检测研究与系统实现
  3. CoC能够驯服Linus大神么?
  4. 如何判定SAP系统是ECC 还是 S4 HANA
  5. NAL header
  6. PageOffice 对Word文档的一键套红功能
  7. 手机强制移除ppt密码,ppt权限密码多少?
  8. Android:自定义View实现签名带笔锋效果
  9. 室内导航用什么来实现?通过什么可以实现导航功能?
  10. 孩子,我希望你健康成长