标签布局TabLayout是MaterialDesign库中的一个新控件,常与工具栏Toolbar搭配使用。大家平时常用的App就有不少采用了TabLayout,比如京东App的商品页,从左到右依次是“商品”、“详情”、“评价”,具体界面如下图所示:
京东的这个页面便是典型的Toolbar+TabLayout效果,实现的话不外乎Toolbar内部嵌套TabLayout,然后TabLayout再通过ViewPager集成多个Fragment页。如此说来其实也不复杂,那还是先看看模拟京东的页面效果图。下面是模拟页面之一的“商品”页:
下面是模拟页面之一的“详情”页:
接下来看看这两个页面互相切换的动图,切换操作可以通过点击顶部的标签文字实现(TabLayout切换页面),也可以通过在下方左右滑动页面实现(ViewPager切换页面)。如下所示:
看完了效果图,再来分析分析具体的实现过程。TabLayout的展现形式类似PagerTabStrip,一样是文字标签带下划线,不同的是,TabLayout允许定制更丰富的样式,它新增的样式属性主要有:
tabBackground : 指定标签的背景。
tabIndicatorColor : 指定下划线的颜色。
tabIndicatorHeight : 指定下划线的高度。
tabTextColor : 指定标签文字的颜色。
tabTextAppearance : 指定标签文字的风格。
tabSelectedTextColor : 指定选中文字的颜色。
而在代码中,TabLayout通过如下方法操作标签:
newTab : 创建新标签。
addTab : 添加一个标签。
getTabAt : 获取指定位置的标签。
setOnTabSelectedListener : 设置标签的选中监听器。该监听器需实现OnTabSelectedListener接口的三个方法,具体说明如下:
onTabSelected: 在标签选中时触发;
onTabUnselected: 在标签取消选中时触发;
onTabReselected: 在标签已选中状态再次选中时触发;
上面的属性和方法说明略显单调,那还是给个具体的代码例子,看看这些属性和方法该如何搭配使用。下面是界面布局的xml文件例子:
下面是操纵TabLayout和ViewPager的代码片段:
以上的xml文件与代码配合,已经能够实现文章开头的商品页切换效果了。不过这里尚存在两点待改进的地方,首先我们看到,商品页和详情页之间的切换,既能通过点击TabLayout实现,也能通过滑动ViewPager实现;也就是说,TabLayout和ViewPager要完成的页面切换其实是同一个行为,可是代码中给TabLayout注册了一个选择监听器,得重写三个方法;同样的,ViewPager也注册了一个滑动监听器,又得重写三个方法;如此一来,一共要重写六个方法,使得代码的冗余程度增加了。
当然Android在设计之初也考虑到了这个冗余的情况,所以这个页面切换其实有捷径可以走。比如对于ViewPager的页面切换,多数情况只需重写onPageSelected一个方法,所以系统已经自带了简单的滑动监听器SimpleOnPageChangeListener,使用该监听器即可大大简化代码,简化后的页面切换代码如下所示:
tab_title.setOnTabSelectedListener(new ViewPagerOnTabSelectedListener(vp_content));
TabLayout第二个有待改进的地方,是它的标签文字风格。前面说到,TabLayout的几个属性可以调整标签文字的颜色、样式等等,可是这仅限于修改文本,无法在标签中定制图片,因此若要给标签加个角标什么的,就必须进行自定义了。虽然TabLayout默认采用文本标签,但它也支持自定义标签,而且自定义标签的过程也很简单,只要定义标签项的布局文件,然后调用Tab页的setCustomView方法即可设置自定义布局。
比如下面是一个标签项的自定义布局文件,其中指定了一个标签文本,加上一个圆点角标,并通过状态图形区分标签的选中与非选中两种状态:
接着打开活动页面代码,只消把initTabLayout函数改成下面这样,寥寥几行就实现了自定义的标签栏:
自定义标签栏的最终页面切换效果如下面的动图所示:
点此查看Android开发笔记的完整目录
__________________________________________________________________________
本文现已同步发布到微信公众号“老欧说安卓”,打开微信扫一扫下面的二维码,或者直接搜索公众号“老欧说安卓”添加关注,更快更方便地阅读技术干货。
京东的这个页面便是典型的Toolbar+TabLayout效果,实现的话不外乎Toolbar内部嵌套TabLayout,然后TabLayout再通过ViewPager集成多个Fragment页。如此说来其实也不复杂,那还是先看看模拟京东的页面效果图。下面是模拟页面之一的“商品”页:
下面是模拟页面之一的“详情”页:
接下来看看这两个页面互相切换的动图,切换操作可以通过点击顶部的标签文字实现(TabLayout切换页面),也可以通过在下方左右滑动页面实现(ViewPager切换页面)。如下所示:
看完了效果图,再来分析分析具体的实现过程。TabLayout的展现形式类似PagerTabStrip,一样是文字标签带下划线,不同的是,TabLayout允许定制更丰富的样式,它新增的样式属性主要有:
tabBackground : 指定标签的背景。
tabIndicatorColor : 指定下划线的颜色。
tabIndicatorHeight : 指定下划线的高度。
tabTextColor : 指定标签文字的颜色。
tabTextAppearance : 指定标签文字的风格。
tabSelectedTextColor : 指定选中文字的颜色。
而在代码中,TabLayout通过如下方法操作标签:
newTab : 创建新标签。
addTab : 添加一个标签。
getTabAt : 获取指定位置的标签。
setOnTabSelectedListener : 设置标签的选中监听器。该监听器需实现OnTabSelectedListener接口的三个方法,具体说明如下:
onTabSelected: 在标签选中时触发;
onTabUnselected: 在标签取消选中时触发;
onTabReselected: 在标签已选中状态再次选中时触发;
上面的属性和方法说明略显单调,那还是给个具体的代码例子,看看这些属性和方法该如何搭配使用。下面是界面布局的xml文件例子:
<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.v7.widget.Toolbar android:id="@+id/tl_head" android:layout_width="match_parent" android:layout_height="50dp" app:navigationIcon="@drawable/ic_back" > <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <android.support.design.widget.TabLayout android:id="@+id/tab_title" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_centerInParent="true" app:tabIndicatorColor="@color/red" app:tabIndicatorHeight="2dp" app:tabSelectedTextColor="@color/red" app:tabTextColor="@color/grey" app:tabTextAppearance="@style/TabText" /> </RelativeLayout> </android.support.v7.widget.Toolbar> <View android:layout_width="match_parent" android:layout_height="1dp" android:background="@color/grey" /> <android.support.v4.view.ViewPager android:id="@+id/vp_content" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout>
下面是操纵TabLayout和ViewPager的代码片段:
public class TabLayoutActivity extends AppCompatActivity implements OnTabSelectedListener, OnPageChangeListener { private Toolbar tl_head; private ViewPager vp_content; private TabLayout tab_title; private ArrayList<String> mTitleArray = new ArrayList<String>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_tab_layout); tl_head = (Toolbar) findViewById(R.id.tl_head); tab_title = (TabLayout) findViewById(R.id.tab_title); vp_content = (ViewPager) findViewById(R.id.vp_content); setSupportActionBar(tl_head); tl_head.setNavigationOnClickListener(new OnClickListener() { @Override public void onClick(View view) { finish(); } }); mTitleArray.add("商品"); mTitleArray.add("详情"); initTabLayout(); initTabViewPager(); } private void initTabLayout() { tab_title.addTab(tab_title.newTab().setText(mTitleArray.get(0))); tab_title.addTab(tab_title.newTab().setText(mTitleArray.get(1))); tab_title.setOnTabSelectedListener(this); } private void initTabViewPager() { GoodsPagerAdapter adapter = new GoodsPagerAdapter( getSupportFragmentManager(), mTitleArray); vp_content.setAdapter(adapter); vp_content.addOnPageChangeListener(this); } @Override public void onTabReselected(Tab tab) { } @Override public void onTabSelected(Tab tab) { vp_content.setCurrentItem(tab.getPosition()); } @Override public void onTabUnselected(Tab tab) { } @Override public void onPageScrollStateChanged(int position) { } @Override public void onPageScrolled(int position, float arg1, int arg2) { } @Override public void onPageSelected(int position) { tab_title.getTabAt(position).select(); } }
以上的xml文件与代码配合,已经能够实现文章开头的商品页切换效果了。不过这里尚存在两点待改进的地方,首先我们看到,商品页和详情页之间的切换,既能通过点击TabLayout实现,也能通过滑动ViewPager实现;也就是说,TabLayout和ViewPager要完成的页面切换其实是同一个行为,可是代码中给TabLayout注册了一个选择监听器,得重写三个方法;同样的,ViewPager也注册了一个滑动监听器,又得重写三个方法;如此一来,一共要重写六个方法,使得代码的冗余程度增加了。
当然Android在设计之初也考虑到了这个冗余的情况,所以这个页面切换其实有捷径可以走。比如对于ViewPager的页面切换,多数情况只需重写onPageSelected一个方法,所以系统已经自带了简单的滑动监听器SimpleOnPageChangeListener,使用该监听器即可大大简化代码,简化后的页面切换代码如下所示:
vp_content.addOnPageChangeListener(new SimpleOnPageChangeListener() { @Override public void onPageSelected(int position) { tab_title.getTabAt(position).select(); } });对于TabLayout的页面切换,它的简化方案更简洁,只需下面一行代码,即可完成TabLayout与ViewPager的页面选择关联,具体代码如下所示:
tab_title.setOnTabSelectedListener(new ViewPagerOnTabSelectedListener(vp_content));
TabLayout第二个有待改进的地方,是它的标签文字风格。前面说到,TabLayout的几个属性可以调整标签文字的颜色、样式等等,可是这仅限于修改文本,无法在标签中定制图片,因此若要给标签加个角标什么的,就必须进行自定义了。虽然TabLayout默认采用文本标签,但它也支持自定义标签,而且自定义标签的过程也很简单,只要定义标签项的布局文件,然后调用Tab页的setCustomView方法即可设置自定义布局。
比如下面是一个标签项的自定义布局文件,其中指定了一个标签文本,加上一个圆点角标,并通过状态图形区分标签的选中与非选中两种状态:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <TextView android:id="@+id/tv_toolbar1" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_centerInParent="true" android:gravity="center" android:textColor="@drawable/toolbar_text_selector" android:textSize="17sp" /> <ImageView android:id="@+id/iv_point1" android:layout_width="25dp" android:layout_height="25dp" android:layout_toRightOf="@+id/tv_toolbar1" android:paddingTop="10dp" android:paddingLeft="3dp" android:scaleType="fitCenter" android:src="@drawable/toolbar_image_selector" /> </RelativeLayout>
接着打开活动页面代码,只消把initTabLayout函数改成下面这样,寥寥几行就实现了自定义的标签栏:
private void initTabLayout() { tab_title.addTab(tab_title.newTab().setCustomView(R.layout.item_toolbar1)); tv_toolbar1 = (TextView) findViewById(R.id.tv_toolbar1); tv_toolbar1.setText(mTitleArray.get(0)); tab_title.addTab(tab_title.newTab().setCustomView(R.layout.item_toolbar2)); tv_toolbar2 = (TextView) findViewById(R.id.tv_toolbar2); tv_toolbar2.setText(mTitleArray.get(1)); tab_title.setOnTabSelectedListener(new ViewPagerOnTabSelectedListener(vp_content)); }
自定义标签栏的最终页面切换效果如下面的动图所示:
点此查看Android开发笔记的完整目录
__________________________________________________________________________
本文现已同步发布到微信公众号“老欧说安卓”,打开微信扫一扫下面的二维码,或者直接搜索公众号“老欧说安卓”添加关注,更快更方便地阅读技术干货。
作者:aqi00 发表于2017/6/8 9:15:40 原文链接
阅读:239 评论:0 查看评论