在开发中,我们常常会遇到像网易新闻客户端的Tab的开发,如下图:
以往我们在实际开发中可能会使用第三方开源的PagerSlidingTabStrip或者ViewPagerindicator去实现类似的效果。但自从Material Design出世后,Google给我们提供了TabLayout去实现了,这里就是简单学习下TabLayout的使用。
首先,我们得保证更新支持库开发环境支持库至少22以上,如下图:
这里用的开发工具是AS,所以我们要在build.gradle中引用这个design这个库,如下图:
或者自己手动在build.gradle中配置
dependencies {
compile 'com.android.support:design:23.1.1'
}
然后在布局中加入TabLayout就可以了:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.TabLayout
android:id="@+id/tablayout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</android.support.design.widget.TabLayout>
</RelativeLayout>
TabLayout中添加Tab很简单,直接调用addTab()就行:
package com.demo.richard.tablayoutdemo;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.design.widget.TabLayout;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
public class MainActivity extends AppCompatActivity {
private TabLayout mTablayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTablayout = (TabLayout) findViewById(R.id.tablayout);
mTablayout.addTab(mTablayout.newTab().setText("新闻"));
mTablayout.addTab(mTablayout.newTab().setText("娱乐"));
mTablayout.addTab(mTablayout.newTab().setText("财经"));
}
}
效果图:
这里我们是默认的TabLayout的风格,没有进行任何修改样式。其实,TabLayout谷歌自己推出来的东西,它肯定考虑了很多方面的。TabLayout我们可以自行修改选择颜色的字体,底下被选中横线的颜色等等…
- tabIndicatorColor // 下方滚动的下划线颜色
- tabSelectedTextColor // tab被选中后,文字的颜色
- tabTextColor // tab默认的文字颜色
- tabSelectedTextColor // tab被选中的文字颜色
- tabBackground
- tabIndicatorHeight
修改下样式:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:richard="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.TabLayout
android:id="@+id/tablayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
richard:tabIndicatorColor="#FF5544"
richard:tabSelectedTextColor="#FF5544"
richard:tabTextColor="#555555">
</android.support.design.widget.TabLayout>
</RelativeLayout>
效果如下:
那这些Tab页上是否可以加小图片呢?
查看了下TabLayout中有一个setIcon的方法,来看下setIcon()添加的图片会是怎样。
TabLayout.Tab tab1 = mTablayout.newTab();
tab1.setIcon(R.mipmap.ic_launcher);
tab1.setText("最新");
mTablayout.addTab(tab1);
效果图如下:
添加的图标位于文字的上方,那如果我要设置位于图片的左边呢?怎么办?我找了一圈貌似好像没有找到设置图片位置
但是,我们可以发现它有一个setCustomView()方法,这表明,我们可以定制自己想要的布局,所以代如下:
新建一个icon_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="horizontal">
<ImageView
android:id="@+id/img"
android:layout_width="20dp"
android:layout_height="20dp" />
<TextView
android:id="@+id/title_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
MainActivity:
package com.demo.richard.tablayoutdemo;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.design.widget.TabLayout;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ImageView;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private TabLayout mTablayout;
private String[] titleArra = new String[]{"最新", "娱乐", "财经", "体育"};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTablayout = (TabLayout) findViewById(R.id.tablayout);
getTabView();
}
private void getTabView() {
for(String str : titleArra){
View view = LayoutInflater.from(this).inflate(R.layout.icon_layout, null);
TextView tv = (TextView) view.findViewById(R.id.title_tv);
ImageView imageView = (ImageView) view.findViewById(R.id.img);
tv.setText(str);
imageView.setImageResource(R.mipmap.ic_launcher);
mTablayout.addTab(mTablayout.newTab().setCustomView(view));
}
}
}
效果图如下:
那么到这里我们可以知道通过setCustomView()可以去定制我们想要的TabTitle布局。
TabLayout中可以通过setTabMode()去设置Tab显示的模式
TabMode的2种模式
MODE_FIXED:固定选项卡显示所有选项卡的大小,平均分配(默认的模式)。
MODE_SCROLLABLE:可以延伸滚动,包含所有的选项卡,根据选项卡显示的内容来分配显示大小,适用于多选项卡
TabLayout.MODE_SCROLLABLE与TabLayout.MODE_FIXED效果对比如下
从上面的对比中很明显就能看出来,2种模式之间的区别。在这里特别提醒下,setTabGravity()这个方法只有在Mode为MODE_FIED下才有用。
在实际开发中的大部分情况下TabLayout基本上都不会单独去使用,一般我们会配合ViewPager来实现向网易新闻那样的切换效果,下面我们通过一个简单的demo来学习使用它。
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:richard="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.design.widget.TabLayout
android:id="@+id/tablayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
richard:tabIndicatorColor="#FF5544"
richard:tabSelectedTextColor="#FF5544"
richard:tabTextColor="#555555"></android.support.design.widget.TabLayout>
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:background="#44ff55"
android:layout_height="match_parent">
</android.support.v4.view.ViewPager>
</LinearLayout>
TabContentFragment
/**
* Created by Richard on 2016/2/17.
*/
public class TabContentFragment extends Fragment {
private String title;
@Override
public void onAttach(Context context) {
super.onAttach(context);
title = getArguments().getString("title");
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.icon_layout, container, false);
TextView tv = (TextView) view.findViewById(R.id.title_tv);
tv.setText(title);
return view;
}
}
MainActivity
public class MainActivity extends AppCompatActivity {
private TabLayout mTablayout;
private ViewPager mViewPager;
private TabTitlePager mTabTitleAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTablayout = (TabLayout) findViewById(R.id.tablayout);
mTablayout.setTabMode(TabLayout.MODE_FIXED);
mViewPager = (ViewPager) findViewById(R.id.viewpager);
mTabTitleAdapter = new TabTitlePager(getSupportFragmentManager());
mViewPager.setAdapter(mTabTitleAdapter);
mTablayout.setupWithViewPager(mViewPager);
}
public class TabTitlePager extends FragmentPagerAdapter{
private String[] titleArr = new String[]{"全部","体育","娱乐","财经","养生"};
public TabTitlePager(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
TabContentFragment fragment = new TabContentFragment();
Bundle bundle = new Bundle();
bundle.putString("title", titleArr[position]);
fragment.setArguments(bundle);
return fragment;
}
@Override
public int getCount() {
return titleArr.length;
}
@Override
public CharSequence getPageTitle(int position) {
return titleArr[position];
}
}
}
效果图如下
可能到这里细心的朋友可能发现了,没有添加Tab的代码,怎么Title显示在上面呢!其实上面的Demo中,我使用的是ViewPager和TabLayout一站式管理Tab,没有手动添加Tab,所以我们要记得重写adapter中的一个方法getPageTitle(),因为getPageTitle自动帮我们添加Tab的过程进行了封装。
@Override
public CharSequence getPageTitle(int position) {
return titleArr[position];
}
那如果使用demo中的一站式管理,如果我要把Tab布局换成我自己想要定义的布局,怎么办?同理嘛!一个个给它加嘛!
public class MainActivity extends AppCompatActivity {
private String[] titleArr = new String[]{"全部","体育","娱乐","财经","养生"};
private TabLayout mTablayout;
private ViewPager mViewPager;
private TabTitlePager mTabTitleAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTablayout = (TabLayout) findViewById(R.id.tablayout);
mTablayout.setTabMode(TabLayout.MODE_FIXED);
mViewPager = (ViewPager) findViewById(R.id.viewpager);
mTabTitleAdapter = new TabTitlePager(getSupportFragmentManager());
mViewPager.setAdapter(mTabTitleAdapter);
mTablayout.setupWithViewPager(mViewPager);
for(int i = 0; i < titleArr.length; i++){
TabLayout.Tab tab = mTablayout.getTabAt(i);
tab.setCustomView(mTabTitleAdapter.getTabView(i));
}
}
public class TabTitlePager extends FragmentPagerAdapter{
private LayoutInflater mInflater;
public TabTitlePager(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
TabContentFragment fragment = new TabContentFragment();
Bundle bundle = new Bundle();
bundle.putString("title", titleArr[position]);
fragment.setArguments(bundle);
return fragment;
}
@Override
public int getCount() {
return titleArr.length;
}
@Override
public CharSequence getPageTitle(int position) {
return titleArr[position];
}
public View getTabView(int position){
mInflater = LayoutInflater.from(MainActivity.this);
View view = mInflater.inflate(R.layout.icon_layout, null);
TextView textView = (TextView) view.findViewById(R.id.title_tv);
ImageView img = (ImageView) view.findViewById(R.id.img);
img.setImageResource(R.mipmap.ic_launcher);
textView.setText(titleArr[position]);
return view;
}
}
}
效果图
当然咯!如果你仅仅只想添加一个图片在Tab title的左边的话,那么你在getPageTitle()方法里使用SpannableString进行处理也是可以的,实现思路自己想嘛!哈哈…,多用用就知道怎么使用合适了。
在使用TabLayout中我们需要注意一些基本的方法
- getTabAt(int index) 得到选项卡
- getTabCount() 得到选项卡的总个数
- getTabGravity() 得到 tab 的 Gravity
- getTabMode() 得到 tab 的模式
- getTabTextColors() 得到 tab 中文本的颜色
- newTab() 新建个 tab
- removeAllTabs() 移除所有的 tab
- removeTab(TabLayout.Tab tab) 移除指定的 tab
- removeTabAt(int position) 移除指定位置的 tab
- setOnTabSelectedListener(TabLayout.OnTabSelectedListener onTabSelectedListener) 为每个 tab 增加选择监听器
- setScrollPosition(int position, float positionOffset, boolean updateSelectedText) 设置滚动位置
- setTabGravity(int gravity) 设置 Gravity
- setTabMode(int mode) 设置 Mode
- setTabTextColors(ColorStateList textColor) 设置 tab 中文本的颜色
- setTabTextColors(int normalColor, int selectedColor) 设置 tab 中文本的颜色 默认 选中
- setTabsFromPagerAdapter(PagerAdapter adapter) 设置 PagerAdapter
- setupWithViewPager(ViewPager viewPager) 和 ViewPager 联动
嗯嗯,暂时写到这里吧!想要熟悉TabLayout的使用,多敲敲代码就知道了。本文只是一些基本的使用,写得也不是很好。如果想更加熟悉与了解TabLayout,请查看爱哥的博客http://blog.csdn.net/aigestudio/article/details/47155769!过完年要正式开工啦!ps:创业公司太苦逼了,容我哭会去…
Demo下载地址:http://download.csdn.net/detail/richardli1228/9435769