概述
TabLayout是一个滑动的标签组件,他是继承自HorizontalScrollView(横向滑动视图),所以它通常适合滑动组件ViewPager配合使用。
会使用ViewPager和RecyclerView的小伙伴直接点击这里快速阅读
效果展示:
一、实现原理
Tablayout的实现其实很简单,只有两个步骤:
①适配ViewPager
②向适配器里添加标签
而标签分类列表的实现实际上就是在此基础上将ViewPager的子布局改为RecyclerView列表展示
二、知识传送门
想了解知识具体详情,点击即刻送达~
- ViewPager的使用(敬请期待……)
- RecyclerView的使用
三、控件解析
如下控件:
<!--
1.tabIndicatorColor
这是TabLayout下面的位置标识横条的颜色
2. tabSelectedTextColor
这是选中状态下字体的颜色
3. tabTextColor
这是未选中状态下字体的颜色
-->
<com.google.android.material.tabs.TabLayout
android:id="@+id/tablayout"
android:layout_width="match_parent"
android:layout_height="50dp"
app:tabIndicatorColor="@color/teal_200"
app:tabSelectedTextColor="@color/teal_200"
app:tabTextColor="@color/black"
tools:ignore="MissingConstraints" />
四、操作步骤
1、实现ViewPager
- 布局
示例代码:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".activity.HomeActivity">
<com.google.android.material.tabs.TabLayout
android:id="@+id/tablayout"
android:layout_width="match_parent"
android:layout_height="50dp"
app:tabIndicatorColor="@color/teal_200"
app:tabSelectedTextColor="@color/teal_200"
app:tabTextColor="@color/black"
tools:ignore="MissingConstraints" />
<androidx.viewpager.widget.ViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
app:layout_constraintTop_toBottomOf="@+id/tablayout"
tools:ignore="MissingConstraints" />
</androidx.constraintlayout.widget.ConstraintLayout>
效果图:
- 添加滑动适配器
public class ViewPagerAdapter extends PagerAdapter {
private List<String> listString;
public ViewPagerAdapter(List<View> listView){
this.listView = listView;
}
@Override
public int getCount() {
return listView.size();
}
@NonNull
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
container.addView(listView.get(position));
return listView.get(position);
}
@Override
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
container.removeView(listView.get(position));
}
@Override
public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
return view == object;
}
@Nullable
@Override
public CharSequence getPageTitle(int position) {
return listString.get(position);
}
}
- 声明
private TabLayout tabLayout;
private ViewPager viewPager;
private LayoutInflater layoutInflater;
private List<View> listView;
private List<String> listString;
private RecyclerView recyclerView01;
private List<News> listNews01;
- 初始化
tabLayout = findViewById(R.id.tablayout);
viewPager = findViewById(R.id.viewPager);
layoutInflater = getLayoutInflater();
View view = layoutInflater.inflate(R.layout.activity_main,null,false);
View view2 = layoutInflater.inflate(R.layout.activity_main,null,false);
View view3 = layoutInflater.inflate(R.layout.activity_main,null,false);
listView = new ArrayList<>();
listString = new ArrayList<>();
- 添加子布局
listView.add(view);
listView.add(view2);
listView.add(view3);
- 添加适配器
//这里的listString是标签,下面会详细介绍
ViewPagerAdapter viewPagerAdapter = new ViewPagerAdapter(listView);
viewPager.setAdapter(viewPagerAdapter);
以上步骤完成了对ViewPager的基本设置,接下来就是TablLayout适配ViewPager
2、适配ViewPager
- 准备标签数据
标签数据实际上就是分类的标题,可以看出就是几个字符串。我们用List来存,这个数据是要传给VIewPager的适配器,然后就会自动适配。
示例代码:
//方便起见我们用循环添加一些基本数据
for (int i = 0; i < 3; i++) {
listString.add("标题"+i);
}
- 给TabLayout适配ViewPager
tabLayout.setupWithViewPager(viewPager);
- 将List数据传给VIewPager的适配器,在此之前我们需要对ViewPager的适配器做一些更改,来适配标签。
- 在适配器里声明List
private List<View> listView;
- 添加构造方法用来接收List并初始化适配器里的List
public ViewPagerAdapter(List<View> listView,List<String> listString){
this.listView = listView;
this.listString = listString;
}
- 添加getTitlePage方法适配
温馨提示:使用快捷键Ctrl+o输入getPageTitle回车直接生成方法
@Nullable
@Override
public CharSequence getPageTitle(int position) {
return listString.get(position);
}
3、添加RecyclerView
列表的添加没什么好说的,按照正常套路添加上去就行,我们上面初始化了三个View,但实际上既是一个套布局克隆出两个,总共三个。这三个布局每个都添加一个RecyclerView就行了。只要写一个适配器就ok。
RecyclerView适配器
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.MyViewHodler> {
private List<News> listNews;
private LayoutInflater layoutInflater;
private Context mcontext;
public RecyclerViewAdapter(List<News> listNews,LayoutInflater layoutInflater,Context context){
this.listNews = listNews;
this.layoutInflater = layoutInflater;
this.mcontext = context;
}
@NonNull
@Override
public MyViewHodler onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = layoutInflater.inflate(R.layout.list,parent,false);
MyViewHodler myViewHodler = new MyViewHodler(view);
return myViewHodler;
}
@Override
public void onBindViewHolder(@NonNull MyViewHodler holder,int position) {
holder.title.setText(listNews.get(position).getTitles());
holder.context.setText(listNews.get(position).getContexts());
int num = holder.getAdapterPosition();
holder.constraintLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(mcontext, "你点击了"+num, Toast.LENGTH_SHORT).show();
}
});
}
@Override
public int getItemCount() {
return listNews.size();
}
class MyViewHodler extends RecyclerView.ViewHolder{
private TextView title,context;
private ConstraintLayout constraintLayout;
public MyViewHodler(@NonNull View itemView) {
super(itemView);
title = itemView.findViewById(R.id.title01);
context = itemView.findViewById(R.id.context01);
constraintLayout = itemView.findViewById(R.id.list_news);
}
}
}
View子布局
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".activity.MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
列表布局
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/list_news"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/title01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
android:textSize="20sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/context01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="3"
android:text="TextView"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/title01" />
</androidx.constraintlayout.widget.ConstraintLayout>
五、总结
总的来说TabLayout和ViewPager的使用就两个步骤调用setupWithViewPager适配ViewPager,在Viewpager的适配器里写一个构造函数来初始化标签,并调用getPageTitle实现。