TabLayout 和 ViewPager 组合使用
这篇主要要介绍Tablayout使用,因为在实际开发中TabLayout和ViewPager一起使用,所以下面主要是对这二者的结合使用。
介绍路线
- TabLayout 的两种添加Tab 的方式
- TabLayout 的常用布局设置
- TabLayout 的常用API
- TabLayout 的时间监听
- TabLayout + ViewPager 的两种布局
- TabLayout + ViewPager 实现
TabLayout 的两种添加Tab 的方式
- 通过布局创建
<android.support.design.widget.TabLayout
android:id="@+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.design.widget.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="首页"
/>
<android.support.design.widget.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="分类"
/>
<android.support.design.widget.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="设置"
/>
</android.support.design.widget.TabLayout>
- 通过代码创建
mTabLayout = (TabLayout) findViewById(R.id.tab_layout);
tab1 = mTabLayout.newTab();
tab1.setText("首页");
tab2 = mTabLayout.newTab();
tab2.setText("视频");
tab3 = mTabLayout.newTab();
tab3.setText("我的");
mTabLayout.addTab(tab1);
mTabLayout.addTab(tab2);
mTabLayout.addTab(tab3);
的常用布局设置
-
显示模式
可滑动:
app:tabMode="scrollable"
固定:app:tabMode="fixed"
-
指示器选项
指示器高度 :
app:tabIndicatorHeight="10dp"
指示器颜色 :app:tabIndicatorColor="@color/colorPrimary"
-
文字选项
选择的Tab的文字颜色:
app:tabSelectedTextColor="#ffffff"
未选择的Tab文字颜色:app:tabTextColor="#000000"
文字样式:app:tabTextAppearance="@style/Base.TextAppearance.AppCompat.Large"
-
背景设置(两者没什么区别)
android:background="@color/colorAccent"
app:tabBackground="@color/colorPrimary"
-
标签距离
app:tabPaddingStart="10dp"
app:tabPaddingBottom="10dp"
app:tabPadding="10dp"
app:tabPaddingEnd="10dp"
app:tabPaddingTop="10dp"
-
对齐方式
居中显示:
app:tabGravity="center"
填充:app:tabGravity="fill"
偏移:app:tabContentStart="200dp"
(从左边开始偏移距离, 必须是可滑动的模式 scrollable) -
标签宽度限制
最大宽度:
app:tabMaxWidth="50dp"
最小宽度:app:tabMinWidth="100dp"
TabLayout 的常用API
以下全部是基于TabLayout mTabLayout;
-
创建标签
TabLayout.Tab tab = mTabLayout.newTab();
-
添加标签
mTabLayout.addTab(tab1);
-
删除标签
删除标签
TabLayout.Tab tab = mTabLayout.newTab(); mTabLayout.removeTab(tab);
通过索引删除标签
TabLayout.Tab tab = mTabLayout.newTab(); mTabLayout.removeTab(tab); mTabLayout.removeTabAt(tab.getPosition());
删除所有标签
mTabLayout.removeAllTabs();
-
得到标签
TabLayout.Tab tab = mTabLayout.getTabAt(tabIndex)
-
得到标签总数
int tabCount = mTabLayout.getTabCount();
-
指示器设置
高度
mTabLayout.setSelectedTabIndicatorHeight(20);
颜色
mTabLayout.setSelectedTabIndicatorColor(Color.RED);
-
文本
/**
* 源码结构
* public void setTabTextColors(int normalColor, int selectedColor)
*/
mTabLayout.setTabTextColors(normalColor, // 正常颜色
selectedColor); // 选择状态颜色
void setTabTextColors (ColorStateList textColor) // 状态颜色
-
显示模式
mTabLayout.setTabMode(TabLayout.MODE_FIXED);
固定: TabLayout.MODE_FIXED
滚动:TabLayout.MODE_SCROLLABLE -
对齐方式
获取Tab 对齐方式
int tabGravity = mTabLayout.getTabGravity();
设置对齐方式
mTabLayout.setTabGravity(TabLayout.GRAVITY_CENTER);
居中:TabLayout.GRAVITY_CENTER
填充:TabLayout.GRAVITY_FILL -
直接添加View 为Tab
我们直接看加View 为 Tab 的三个方法:void addView(View child)
child : 要添加的Viewvoid addView (View child,int index)
child : 要添加的View
index : 位置索引void addView (View child,int index,ViewGroup.LayoutParams params)
child : 要添加的View
index : 位置索引
params : 布局参数 -
得到当前选择的位置
mTabLayout.getSelectedTabPosition();
Tab 常用API
以下全部是基于TabLayout mTabLayout;
以下全部基于 TabLayout.Tab mTab = mTabLayout.newTab();
- 判断是否被选择
mTab.isSelected();
- 设置为被选择状态
mTab.select();
- 描述内容(如果你没用设置描述内容, 默认的是标签的标题)
-
设置描述内容
下面介绍两种设置方式直接设置描述内容
mTab.setContentDescription("text content");
通过资源文件设置
mTab.setContentDescription(R.string.app_name);
看一下原码,在源码种可以看到,最终还设通过setContentDescription方法进行设置的。@NonNull public Tab setContentDescription(@StringRes int resId) { if (mParent == null) { throw new IllegalArgumentException("Tab not attached to a TabLayout"); } return setContentDescription(mParent.getResources().getText(resId)); }
-
获取描述内容
CharSequence content = mTab.getContentDescription(); String strContent = content.toString();
- 自定义标签的内容
-
直接设置View方式自定义标签内容
View view = LayoutInflater.from(mContext).inflate(R.layout.view1,null); mTab.setCustomView(view);
-
通过资源文件进行设置
mTab.setCustomView(R.layout.view1);
贴一下源码(不解释):@NonNull public Tab setCustomView(@LayoutRes int resId) { final LayoutInflater inflater = LayoutInflater.from(mView.getContext()); return setCustomView(inflater.inflate(resId, mView, false)); }
- 标签的标签
给Tab设置tag, 然后就可以通过tag得到Tab
-
设置tag (直接看源码)
TabLayout.Tab tab = mTab.setTag("tag");
@NonNull public Tab setTag(@Nullable Object tag) { mTag = tag; return this; }
从上面源码中可以看到,设的tag类型是object ,返回的是Tab 本身。
-
获取tag(直接看源码,不解释)
Object obj = mTab.getTag();
@Nullable public Object getTag() { return mTag; }
-
添加图标
TabLayout.Tab tab = mTab.setIcon(R.mipmap.ic_launcher);
TabLayout.Tab tab = mTab.setIcon(drawable);
7. 标题的文字
TabLayout.Tab tab = mTab.setText(R.string.app_name);
TabLayout.Tab tab = mTab.setText("Tab Name");
8. 当前标签位置
`int position = mTab.getPosition();`
#### TabLayout 的时间监听
给TabLayout 添加监听事件时,要实现 OnTabSelectedListener 接口。多说啰嗦直接上代码:
mTabLayout.addOnTabSelectedListener(listener);
private TabLayout.OnTabSelectedListener listener = new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
//选择的tab
Log.e("TT","onTabSelected:" + tab.getText().toString());
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
//离开的那个tab
Log.e("TT","onTabUnselected" + tab.getText().toString());
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
//再次选择tab
Log.e("TT","onTabReselected" + tab.getText().toString());
}
};
#### TabLayout + ViewPager 的两种布局
1. TabLayout 在ViewPager 布局**内**
<android.support.v4.view.ViewPager
android:id="@+id/vp_viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.TabLayout
android:id="@+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="fixed"
app:tabGravity="fill">
</android.support.design.widget.TabLayout>
</android.support.v4.view.ViewPager>
2. TabLayout 在ViewPager 布局**外**
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.view.ViewPager
android:id="@+id/vp_viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/tab_layout">
</android.support.v4.view.ViewPager>
<android.support.design.widget.TabLayout
android:layout_alignParentBottom="true"
android:id="@+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="fixed"
app:tabGravity="fill">
</android.support.design.widget.TabLayout>
</RelativeLayout>
在上面两种布局中可以看到,在上面我把TabLayout放在了ViewPager外面的底部,如果我们把TabLayout 放到ViewPager外面,我们可以灵活的摆放TabLayout的位置,在实际开发中大多数都是放在上面的,所以如果是在上面,就放在里面还是外面都没有影响。
#### TabLayout + ViewPager 实现
1. TAbLayout 在 ViewPager 布局内。
先上代码,代码很简单,看一下代码,然后在根据代码中注意的地方特殊说明一下。
public class MainActivity extends AppCompatActivity {
private TabLayout mTabLayout;
private ViewPager mViewPager;
private List<View> viewList = new ArrayList<>(3);
private String[] strs = {"首页","视频","我的"};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
View view = null;
view = getLayoutInflater().inflate(R.layout.view1,null);
viewList.add(view);
view = getLayoutInflater().inflate(R.layout.view2,null);
viewList.add(view);
view = getLayoutInflater().inflate(R.layout.view3,null);
viewList.add(view);
initView();
initEvn();
}
private void initEvn() {
mTabLayout.addOnTabSelectedListener(listener);
}
private void initView() {
mTabLayout = (TabLayout) findViewById(R.id.tab_layout);
mViewPager = (ViewPager) findViewById(R.id.vp_viewpager);
mViewPager.setAdapter(new PagerAdapter() {
@Override
public int getCount() {
return viewList.size();
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
View view = viewList.get(position);
container.addView(view);
return view;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
@Override
public CharSequence getPageTitle(int position) {
return strs[position];
}
});
}
private TabLayout.OnTabSelectedListener listener = new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
//选择的tab
Log.e("TT","onTabSelected:" + tab.getText().toString());
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
//离开的那个tab
Log.e("TT","onTabUnselected" + tab.getText().toString());
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
//再次选择tab
Log.e("TT","onTabReselected" + tab.getText().toString());
}
};
}
上面代码中ViewPager的使用不用再说了,要说一下的是TabLayout如果不做其他操作是不需要添加获取的,也就是说不需要findViewById,ViewPager 会自动和TabLayout进行关联。
还需要注意的就是PagerAdapter中的下面这个方法:
private String[] strs = {"首页","视频","我的"};
@Override
public CharSequence getPageTitle(int position) {
return strs[position];
}
getPageTitle 这个方法是设置TabLayout Tab 的文本标题的。
1. TAbLayout 在 ViewPager 布局外。
还是先上代码:
public class MainActivity extends AppCompatActivity {
private TabLayout mTabLayout;
private ViewPager mViewPager;
private List<View> viewList = new ArrayList<>(3);
private String[] strs = {"首页","视频","我的"};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
View view = null;
view = getLayoutInflater().inflate(R.layout.view1,null);
viewList.add(view);
view = getLayoutInflater().inflate(R.layout.view2,null);
viewList.add(view);
view = getLayoutInflater().inflate(R.layout.view3,null);
viewList.add(view);
initView();
initEvn();
}
private void initEvn() {
mTabLayout.addOnTabSelectedListener(listener);
}
private void initView() {
mTabLayout = (TabLayout) findViewById(R.id.tab_layout);
mViewPager = (ViewPager) findViewById(R.id.vp_viewpager);
mTabLayout.setupWithViewPager(mViewPager);
mViewPager.setAdapter(new PagerAdapter() {
@Override
public int getCount() {
return viewList.size();
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
View view = viewList.get(position);
container.addView(view);
return view;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
@Override
public CharSequence getPageTitle(int position) {
return strs[position];
}
});
}
private TabLayout.OnTabSelectedListener listener = new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
//选择的tab
Log.e("TT","onTabSelected:" + tab.getText().toString());
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
//离开的那个tab
Log.e("TT","onTabUnselected" + tab.getText().toString());
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
//再次选择tab
Log.e("TT","onTabReselected" + tab.getText().toString());
}
};
}
看完这段代码,有人会认为这段代码和上面不是差不多嘛,对,我们就要注意一下不同的那一点。
**不同的地方是**,在这里我们要通过 findViewById 获取到TabLayout的setupWithViewPager(mViewPager)方法将ViewPager 对象设置到TabLayout 中和TabLayout进行关联。