implementation 'com.android.support:design:26.1.0'
一、 先实现布局文件:
这里解释一下TabLayout 的一些属性:
tabBackground : 标签栏的颜色
tabIndicatorColor : 指示条的颜色
tabIndicatorHeight : 指示条的高度
tabMode : 选项卡的行为模式 两种模式。一种是 scrollable 适用于当标签栏的数量多的时候,标签栏可以滑动,经个人测试,一般是标签栏5个以上适用于这个模式 第二种是 fixed 默认的设置,标签栏是固定的,不能滑动,很多的时候会发生挤压,当标签栏的个数小于等于5个的时候选择这个模式就很不错。
tabSelectedTextColor : tab 被选中的时候的字体颜色
tabTextColor : tab 未被选中的时候的字体的颜色
tabTextAppearance : 设置字体的外观。 比如说设置字体的大小
二、OK,下面开始通过代码实现:
private TabLayout mTabLayout;
private ViewPager mViewPager;
private List titles = new ArrayList();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tablayout);
intData();
initView();
initEvent();
}
private void intData() {
titles.add("电影");
titles.add("电视剧");
titles.add("综艺");
}
private void initView() {
mTabLayout = (TabLayout) findViewById(R.id.tablayout);
mViewPager = (ViewPager) findViewById(R.id.viewpager);
}
private void initEvent() {
for (int i = 0; i < titles.size(); i++) {
mTabLayout.addTab(mTabLayout.newTab().setText(titles.get(i)));
}
List fragments = new ArrayList();
for (int i = 0; i < titles.size(); i++) {
fragments.add(new MyFragment());
}
MyFragmentPager fragmentPager = new MyFragmentPager(getSupportFragmentManager(), fragments, titles);
// 给ViewPager 设置适配器
mViewPager.setAdapter(fragmentPager);
// 将TabLayout 和 ViewPager 关联起来
mTabLayout.setupWithViewPager(mViewPager);
}
因为要使用ViewPager,首先要自定义一个Fragment,我自定义了一个Fragment ,代码如下:
public class MyFragment extends Fragment {
View view;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_tablayout, container, false);
return view;
}
}
其中fragment_tablayout.xml 里面只是有一个TextView。
然后我们在主界面也自定义定义了一个MyFragmentPager,用于配合ViewPager 管理Fragment,代码如下:
public class MyFragmentPager extends FragmentStatePagerAdapter {
List mFragments;
List mTitles;
public MyFragmentPager(FragmentManager fm, List fragments, List titles) {
super(fm);
mFragments = fragments;
mTitles = titles;
}
@Override
public Fragment getItem(int position) {
return mFragments.get(position);
}
@Override
public int getCount() {
return mFragments.size();
}
/**
* 设置标签栏的标题
*
* @param position
* @return
*/
@Override
public CharSequence getPageTitle(int position) {
return mTitles.get(position);
}
}
这个特别要注意一下getPagerTitle 方法,这里返回position 位置的PagerTab 的标题。跑下代码,效果如图:
好了,上面就是tabLayout 配合ViewPager的基本使用了,下面我们扩展下。像网易云音乐的标签栏,并没有使用文字标题,而是使用的图片,那么我们怎样利用tabLayout的时候也使用图片呢? 我上面提到过 getPagerTitle() 方法,这个方法的返回的类型是 CharSequence。我们可以创建一个SpannableString,将图片放置在ImageSpan 中,设置在SpannableString中,我们改下MyFragmentPager 的代码:
public class MyFragmentPager extends FragmentStatePagerAdapter {
List mFragments;
List mTitles;
Context mContext;
int[] mImages;
public MyFragmentPager(Context context, FragmentManager fm, List fragments,
List titles, int[] images) {
super(fm);
mFragments = fragments;
mTitles = titles;
mContext = context;
mImages = images;
}
@Override
public Fragment getItem(int position) {
return mFragments.get(position);
}
@Override
public int getCount() {
return mFragments.size();
}
/**
* 设置标签栏的标题
*
* @param position
* @return
*/
@Override
public CharSequence getPageTitle(int position) {
Drawable image = ContextCompat.getDrawable(mContext, mImages[position]);
image.setBounds(0, 0, image.getIntrinsicWidth(), image.getIntrinsicHeight());
SpannableString sb = new SpannableString(" ");
ImageSpan imageSpan = new ImageSpan(image, ImageSpan.ALIGN_BOTTOM);
sb.setSpan(imageSpan, 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
return sb;
}
}
可以看到我们的这个MyFragmentPager 的构造函数发生了变化,而此时我们也要更改下主界面的传参,代码如下:
private TabLayout mTabLayout;
private ViewPager mViewPager;
private int[] images;
private List titles = new ArrayList();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tablayout);
intData();
initView();
initEvent();
}
private void intData() {
titles.add("电影");
titles.add("电视剧");
titles.add("综艺");
images = new int[]{R.mipmap.teleplay, R.mipmap.movie, R.mipmap.shows};
}
private void initView() {
mTabLayout = (TabLayout) findViewById(R.id.tablayout);
mViewPager = (ViewPager) findViewById(R.id.viewpager);
}
private void initEvent() {
for (int i = 0; i < titles.size(); i++) {
mTabLayout.addTab(mTabLayout.newTab().setText(titles.get(i)));
}
List fragments = new ArrayList();
for (int i = 0; i < titles.size(); i++) {
fragments.add(new MyFragment());
}
MyFragmentPager fragmentPager = new MyFragmentPager(this, getSupportFragmentManager(), fragments, titles, images);
// 给ViewPager 设置适配器
mViewPager.setAdapter(fragmentPager);
// 将TabLayout 和 ViewPager 关联起来
mTabLayout.setupWithViewPager(mViewPager);
}
有时候客户可能并不满足于这样简单的样式,而是想要在TabLayout 的标签上展现各式各样的内容,这时候我们就需要自定义View 来实现了。TabLayout 中有一个方法 setCustomView(),可以通过调用这个方法来加载我们自定义的View,进而实现我们想要的各式各样的标签。OK,我们先自定义一个Tab 的样式,创建一个 item_tab_style.xml 文件,图片在上,文字在下:
然后在代码中将这个布局加载进去,完整的代码如下:
private TabLayout mTabLayout;
private ViewPager mViewPager;
private int[] images;
private List titles = new ArrayList();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tablayout);
intData();
initView();
initEvent();
}
private void intData() {
titles.add("电影");
titles.add("电视剧");
titles.add("综艺");
images = new int[]{R.mipmap.teleplay, R.mipmap.movie, R.mipmap.shows};
}
private void initView() {
mTabLayout = (TabLayout) findViewById(R.id.tablayout);
mViewPager = (ViewPager) findViewById(R.id.viewpager);
}
private void initEvent() {
for (int i = 0; i < titles.size(); i++) {
mTabLayout.addTab(mTabLayout.newTab().setText(titles.get(i)));
}
List fragments = new ArrayList();
for (int i = 0; i < titles.size(); i++) {
fragments.add(new MyFragment());
}
MyFragmentPager fragmentPager = new MyFragmentPager(this, getSupportFragmentManager(), fragments, titles, images);
// 给ViewPager 设置适配器
mViewPager.setAdapter(fragmentPager);
// 将TabLayout 和 ViewPager 关联起来
mTabLayout.setupWithViewPager(mViewPager);
for (int i = 0; i < titles.size(); i++) {
mTabLayout.getTabAt(i).setCustomView(getTabView(i));
}
// 添加TabLayout 的监听
mTabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
changeTabStatus(tab, true);
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
changeTabStatus(tab, false);
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
}
/**
* 获取自定义布局
*
* @param postion
* @return
*/
private View getTabView(final int postion) {
final View view = LayoutInflater.from(this).inflate(R.layout.item_tab_style, null);
ImageView ivTab = (ImageView) view.findViewById(R.id.iv_tab);
TextView tvTab = (TextView) view.findViewById(R.id.tv_tab);
ivTab.setImageDrawable(ContextCompat.getDrawable(this, images[postion]));
tvTab.setText(titles.get(postion));
return view;
}
/**
* 在标签页状态改变的时候更改状态
*
* @param tab
* @param selected
*/
private void changeTabStatus(TabLayout.Tab tab, boolean selected) {
View view = tab.getCustomView();
final ImageView imgTitle = (ImageView) view.findViewById(R.id.iv_tab);
TextView txtTitle = (TextView) view.findViewById(R.id.tv_tab);
imgTitle.setVisibility(View.VISIBLE);
if (selected) {
txtTitle.setTextColor(getResources().getColor(R.color.select_color_000000));
} else {
txtTitle.setTextColor(getResources().getColor(R.color.color_999999));
}
}
这样就实现了标签自定义View,最后看一下我们的实现效果:
好了,上面就是tabLayout 的一些具体的实现。