ListView在android中贡献卓越,但是它并不是完全没有缺点的,如果我们不使用一些技巧来提升它的运行效率,而且他不能实现横向滚动,为此RecyclerView诞生了
1.Recycler View的基本使用
由于RecyclerView属于新增的控件,为了适应所有的android的版本,我们在使用之前要在app/build.gradle文件中导入依赖包
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.recyclerview:recyclerview:1.0.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
implementation 'androidx.recyclerview:recyclerview:1.0.0'
}
implementation 'androidx.recyclerview:recyclerview:1.0.0'
基本使用:
(1)在使用时必须指定一个布局管理器和一个配适器
(2) 自定义的配适器需要继承RecyclerView.Adapter
- 将配适器中定义的ViewHolder类作为泛型
- 自定义配适器中需要根据UI自定义View Holder类(继承RecyclerView.ViewHolder)
- 有参构造用于传入数据
- 重写onCreateViewHolder(),onBindViewHolder(),getItemCount()
具体实现
(1)activity_main.xml中加入控件Recycler View
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
(2)每个子项的布局
在res/layout中新建Layout resource file
recyclerview_item.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/picture"
android:layout_width="20dp"
android:layout_height="20dp"
/>
<TextView
android:id="@+id/textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="20dp"/>
</LinearLayout>
(3)定义实体类myDate
public class myDate{
private String name;
private int id;
public myDate(String name,int id) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
(4)自定义配适器
public class myAdapter extends RecyclerView.Adapter<myAdapter.ViewHolder> {
private List<myDate> list;
//构造函数传入数据
public myAdapter(List<myDate> list) {
this.list = list;
}
//定义ViewHolder类
static public class ViewHolder extends RecyclerView.ViewHolder{
TextView textView;
ImageView imageView;
public ViewHolder(@NonNull View itemView) {
super(itemView);
textView = itemView.findViewById(R.id.textview);
imageView = itemView.findViewById(R.id.picture);
}
}
//重写三种方法
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recyclerview_item,parent,false);
ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
myDate myDate = list.get(position);
holder.imageView.setImageResource(myDate.getId());
holder.textView.setText(myDate.getName());
}
@Override
public int getItemCount() {
return list.size();
}
}
onCreateViewHolder()用于创建View Holder实例,将加载出来的布局传入到构造函数中,返回View Holder实例
onBindViewHolder()是用于对RecycleView子项的数据进行赋值,会在每个子项在屏幕中时执行
getItemCount()用于返回子项的个数
(5)指定布局管理器和配适器
private List<myDate> list = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
RecyclerView recyclerView = findViewById(R.id.recyclerview);
recyclerView.setLayoutManager(layoutManager);
myAdapter myAdapter = new myAdapter(list);
recyclerView.setAdapter(myAdapter);
}
public List<myDate> init() {
for(int i= 0;i < 10;i++) {
myDate myDate = new myDate("樱桃",R.drawable.cherry);
list.add(myDate);
myDate myDate1 = new myDate("樱桃",R.drawable.cherry);
list.add(myDate1);
myDate myDate2 = new myDate("樱桃",R.drawable.cherry);
list.add(myDate2);
myDate myDate3 = new myDate("樱桃",R.drawable.cherry);
list.add(myDate3);
myDate myDate4 = new myDate("樱桃",R.drawable.cherry);
list.add(myDate4);
myDate myDate5 = new myDate("樱桃",R.drawable.cherry);
list.add(myDate5);
myDate myDate6 = new myDate("樱桃",R.drawable.cherry);
list.add(myDate6);
}
return list;
}
2.实现横向滚动和瀑布流布局
实现横向滚动layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
RecyclerView recyclerView = findViewById(R.id.recyclerview);
recyclerView.setLayoutManager(layoutManager);
myAdapter myAdapter = new myAdapter(list);
recyclerView.setAdapter(myAdapter);
除了LinearLayoutManager之外,Recycler View还为我们提供了
- GridLayoutManager 以网格方式展示
- StaggeredGridLayoutManager 以瀑布流方式展示Item
瀑布流
(1)创建StaggeredGridLayoutManager实例,传入两个参数,参数一:指定布局的列数,参数二:指定布局的方向
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
StaggeredGridLayoutManager staggeredGridLayoutManager = new StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL);
RecyclerView recyclerView = findViewById(R.id.recyclerview);
recyclerView.setLayoutManager(staggeredGridLayoutManager);
myAdapter myAdapter = new myAdapter(list);
recyclerView.setAdapter(myAdapter);
}
public List<myDate> init() {
for(int i= 0;i < 10;i++) {
myDate myDate = new myDate("樱桃樱桃樱桃樱桃樱桃樱桃",R.drawable.cherry);
list.add(myDate);
myDate myDate1 = new myDate("樱桃樱桃樱桃",R.drawable.cherry);
list.add(myDate1);
myDate myDate2 = new myDate("樱桃樱桃",R.drawable.cherry);
list.add(myDate2);
myDate myDate3 = new myDate("樱桃",R.drawable.cherry);
list.add(myDate3);
myDate myDate4 = new myDate("樱桃",R.drawable.cherry);
list.add(myDate4);
myDate myDate5 = new myDate("樱桃",R.drawable.cherry);
list.add(myDate5);
myDate myDate6 = new myDate("樱桃",R.drawable.cherry);
list.add(myDate6);
}
return list;
}
网格
GridLayoutManager gridLayoutManager = new GridLayoutManager(MainActivity.this,3);
RecyclerView recyclerView = findViewById(R.id.recyclerview);
recyclerView.setLayoutManager(gridLayoutManager);
两者的区别,借用两张图来表示
- GridLayoutManager 网格
- StaggeredGridLayoutManager 瀑布流
3.添加点击事件
public void onBindViewHolder(@NonNull final ViewHolder holder, int position) {
final myDate myDate = list.get(position);
holder.textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(v.getContext(),"You click" + myDate.getName(),Toast.LENGTH_SHORT ).show();
}
});
holder.imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(v.getContext(),"You click" + myDate.getName(),Toast.LENGTH_SHORT ).show();
}
});
holder.imageView.setImageResource(myDate.getId());
holder.textView.setText(myDate.getName());
}