前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android开发笔记(一百四十七)标签布局TabLayout

Android开发笔记(一百四十七)标签布局TabLayout

作者头像
aqi00
发布2019-01-18 15:11:43
1.1K0
发布2019-01-18 15:11:43
举报
文章被收录于专栏:老欧说安卓老欧说安卓

标签布局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文件例子:

代码语言:javascript
复制
<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的代码片段:

代码语言:javascript
复制
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,使用该监听器即可大大简化代码,简化后的页面切换代码如下所示:

代码语言:javascript
复制
	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方法即可设置自定义布局。 比如下面是一个标签项的自定义布局文件,其中指定了一个标签文本,加上一个圆点角标,并通过状态图形区分标签的选中与非选中两种状态:

代码语言:javascript
复制
<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函数改成下面这样,寥寥几行就实现了自定义的标签栏:

代码语言:javascript
复制
	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开发笔记的完整目录

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017年06月08日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档