RecyclerView 英 [ri:'saɪklə] 是 Android 开发中的一个重要组件,通常直译为 “recycler 视图” 或循环视图
做一个这样的新闻列表
RecycleView也属于三方工具,老工程可能需要添加依赖
工程比较新,就无需添加依赖了,它已经集成在material中了
我们一般不在RecycleView中添加控件item,而是通过其他方式往里面添加控件,这里介绍适配器方式
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/recycler_view"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
为item新建一个布局,注意Width约束条件设置为0dp
<?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"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/tv_picture"
android:layout_width="100dp"
android:layout_height="70dp"
android:scaleType="centerCrop"
android:src="@drawable/icon_logo"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:ellipsize="end"
android:maxLines="2"
android:text="落魄谷中寒风吹,春秋蝉鸣少年归,荡魂山处石人泪,定仙游走魔向北,逆流河上万仙退,爱情不敌坚持泪,宿命天成命中败,仙尊悔而我不悔"
android:textSize="18sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/tv_picture"
app:layout_constraintTop_toTopOf="@id/tv_picture" />
<TextView
android:id="@+id/tv_author"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:ellipsize="end"
android:maxLines="1"
android:text="作者:大爱仙尊"
android:textSize="16sp"
app:layout_constraintStart_toEndOf="@id/tv_picture"
app:layout_constraintTop_toBottomOf="@+id/tv_title" />
</androidx.constraintlayout.widget.ConstraintLayout>
在复习一下图片的缩放模式,这里是xy按比例缩放匹配宽高,多的裁掉——图片的缩放模式是跟着我们的ImageView来变化的
两个都是xml布局,怎么关联起来???王德发——Adapter,我他喵莱纳
资讯类的适配器,单独创建一个java类
public class ArticleAdapter extends RecyclerView.Adapter {
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
//找item布局,把item转为视图,与LayoutInflater有异曲同工之处
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_article_simple, parent, false);
//创建一个ViewHolder对itemView做管理
MyViewHolder myViewHolder = new MyViewHolder(view);
//ViewHolder和RecycleView做关联
return myViewHolder;
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
}
/**
* @return 告诉RecyclerView显示多少条数据
*/
@Override
public int getItemCount() {
return 20;
}
public class MyViewHolder extends RecyclerView.ViewHolder{
public MyViewHolder(@NonNull View itemView) {
super(itemView);
}
}
}
继承Recycle.Adapter,重写onCreateViewHolder、onBindViewHolder、getItemCount三个方法,下面进行分析
很关键的方法onCreateViewHolder “视图持有者” ,可以理解成一个杯子,而item数据可以理解成咖啡
5:onCreateViewHolder()
的调用时机和次数onCreateViewHolder()
创建对应数量的 ViewHolder(10 个 “杯子”)。6:onCreateViewHolder()
的调用时机和次数滑动过程中:每次有新的列表项进入屏幕(无论是向上滑还是向下滑),都会触发 onBindViewHolder()
,为复用的 ViewHolder 绑定新位置的数据(比如滑出屏幕的 item1 的 ViewHolder,会被重新绑定 item11 的数据)。
我们在RecyclerView.Adapter中获取不到LayoutInflater(布局加载器),但是没有关系;这种可以借鉴这种思想
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
//找item布局,把item转为视图,与LayoutInflater有异曲同工之处
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_article_simple, parent, false);
//创建一个ViewHolder对itemView做管理
MyViewHolder myViewHolder = new MyViewHolder(view);
//ViewHolder和RecycleView做关联
return myViewHolder;
}
parent
是父布局容器(即RecyclerView
本身)用于为加载的布局(这里指R.layout.item_article_simple)提供正确的 布局参数(LayoutParams
)IllegalStateException
。基本就是固定写法了
总结
parent
是 RecyclerView
实例,用于提供布局参数和上下文。attachToRoot = false
避免子项被重复添加。ViewHolder
需要在 onCreateViewHolder
中正确返回。两者做关联还需要一个东西ViewHolder 视图口袋,它会对item的布局做一些管理,item本身会被放到ViewHolder里面;
作用:复用已经滑出屏幕的旧视图,缓存这些视图的引用
他是一个抽象类,不能直接使用,我们自己去创建一个类,然后继承它
//创建一个ViewHolder对itemView做管理
MyViewHolder myViewHolder = new MyViewHolder(view);
return myViewHolder;
public class MyViewHolder extends RecyclerView.ViewHolder{
public MyViewHolder(@NonNull View itemView) {
super(itemView);
}
}
上面的代码仅完成了 适配器(Adapter)与列表项布局(Item)的关联,但 RecyclerView 尚未与适配器绑定。
问题又来了,RecycleView怎么和适配器关联起来?
public class ArticleListActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_article_list);
//找到循环视图
RecyclerView recyclerView = findViewById(R.id.recycler_view);
//将item排列为一维列表,默认是竖向
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
//线性方向改成横向
// layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
//为RecycleView添加布局管理器
recyclerView.setLayoutManager(layoutManager);
//设置适配器
recyclerView.setAdapter(new ArticleAdapter());
}
}
了解即可
为RecycleView添加布局管理器,管理器内部是布局方向,最后为RecycleView设置适配器
左图垂直排列,右图横向排列
总结:item匹配适配器,找到布局转为视图,ViewHolder(需要继承)作为item的管理器;RecycleView匹配Adapter需要设置布局管理器,让item以怎样的形式展现