Quantcast
Channel: CSDN博客移动开发推荐文章
Viewing all articles
Browse latest Browse all 5930

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

$
0
0
标签布局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文件例子:
<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 原文链接
阅读:181 评论:0 查看评论

Viewing all articles
Browse latest Browse all 5930

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>