Android学习|布局列表——RecyclerView
一、前提
RecyclerView效果和 ListView 效果接近,只是RecyclerView更灵活,效果更多。
RecyclerView需要先导入依赖包才能进行使用,类似导入jar 导包:src下面的 bulid.gradle中添加
dependencies { implementation ‘androidx.recyclerview:recyclerview:1.1.0’ }
原项目有导包过程,所以只添加 implementation ‘androidx.recyclerview:recyclerview:1.1.0’ 第一个大象点击下载包
二、实现RecyclerView效果
RecyclerView设置与ListView基本相同,但是在Myadapter和布局管理器方面有些不同。
1、自定义的MyAdapter类
??????????RecyclerView?的自定义Adapter继承 ??RecyclerView.Adapter??<VH extends ViewHolder》
????????? VH 是内部类,继承 ViewHolder,类似ListView里边封装的保存Item里边组件的内部类,并且也避免了像ListView没设置的话,重复的进行findViewById()
package com.example.senconddemo_recyclerview;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
public class MyAdapater extends RecyclerView.Adapter<MyAdapater.MyViewHolder> {
private List<Bean> data;
private Context context;
public MyAdapater(List<Bean> data, Context context) {
this.data = data;
this.context = context;
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = View.inflate(context, R.layout.recyclerview_item, null);
return new MyViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
holder.tv.setText(data.get(position).getName());
}
@Override
public int getItemCount() {
return data==null? 0 :data.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
private TextView tv;
public MyViewHolder(@NonNull View itemView) {
super(itemView);
tv = itemView.findViewById(R.id.textview);
}
}
}
2、主Activity类获取RecyclerView,并进行设置
????????在主Activity类中,获取RecyclerView,然后按理应该类似ListView进行myAdapter的注入,但是,RecyclerView与ListView不同,ListView默认情况下的布局管理器是垂直布局,不用设置。而RecyclerView需要进行设置。
布局管理器LayoutManager
RecyclerView中可以设置的布局管理器LayoutManager是一个抽象类,有3个子类: ????????????LinearLayoutManager: 线性布局管理器 ??????????? GridLayoutManager: 表格布局管理器 ??????????? StaggeredGridLayoutManager: 瀑布流布局管理器
参考 : https://www.jianshu.com/p/501e10bc31f1
package com.example.senconddemo_recyclerview;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.LinearLayout;
import android.widget.ListView;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private List<Bean> data = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
for (int i = 99959; i < 300000; i++) {
Bean bean = new Bean("zjp"+i+ " ");
data.add(bean);
}
RecyclerView recyclerView = findViewById(R.id.rv);
StaggeredGridLayoutManager staggeredGridLayoutManager = new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL);
recyclerView.setLayoutManager(staggeredGridLayoutManager);
MyAdapater myAdapater = new MyAdapater(data,this);
recyclerView.setAdapter(myAdapater);
}
}
上面代码中,构造方法中的3都表示3个数据作为一行(一列)。
在StaggeredGridLayoutManager的构造中,传入的是 StaggeredGridLayoutManager.VERTICAL 其实也可以传入LinearLayout.VERTICAL 或 1,都是等价的
LinearLayout.VERTICAL == StaggeredGridLayoutManager.VERTICAL == 1
3、效果展示:
a、LinearLayoutManager 线性布局
b、GridLayoutManager 表格布局
c、StaggeredGridLayoutManager 瀑布流布局
瀑布流布局,包含如下错乱的情况。99999占一行,10000占2行…并且不像表格布局那种一行的所有内容按照最大的尺寸划分。
三、添加点击事件
???????RecyclerView本身是没有点击事件的,需要我们进行自定义。
???????在MyAdapter类中自定义一个接口RecyclerViewItemOnClickListener,然后定义点击事件的抽象方法onRecyclerViewClick(int postion),为了确保点击事件的对象不重复创建,定义一个引用RecyclerViewItemOnClickListener进行判断,并设置该引用的set()方法。
???????然后,在Adapter类的自定义内部类MyViewHolder的构造中,设置Item组件itemView的点击事件,当点击时,判断前面的recyclerViewItemOnClickListener是否被实例化,未实例化时,进行自定义点击事件的绑定。
部分代码如下:
public class MyViewHolder extends RecyclerView.ViewHolder {
private TextView tv;
public MyViewHolder(@NonNull View itemView) {
super(itemView);
tv = itemView.findViewById(R.id.textview);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (recyclerViewItemOnClickListener!=null){
recyclerViewItemOnClickListener.onRecyclerViewClick(getAdapterPosition());
}
}
});
}
}
private RecyclerViewItemOnClickListener recyclerViewItemOnClickListener;
public void setRecyclerViewItemOnClickListener(RecyclerViewItemOnClickListener listener){
recyclerViewItemOnClickListener = listener;
}
public interface RecyclerViewItemOnClickListener{
void onRecyclerViewClick(int postion);
}
Adapter类的完整代码如下:
package com.example.senconddemo_recyclerview;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
public class MyAdapater extends RecyclerView.Adapter<MyAdapater.MyViewHolder> {
private List<Bean> data;
private Context context;
public MyAdapater(List<Bean> data, Context context) {
this.data = data;
this.context = context;
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = View.inflate(context, R.layout.recyclerview_item, null);
return new MyViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
holder.tv.setText(data.get(position).getName());
}
@Override
public int getItemCount() {
return data==null? 0 :data.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
private TextView tv;
public MyViewHolder(@NonNull View itemView) {
super(itemView);
tv = itemView.findViewById(R.id.textview);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (recyclerViewItemOnClickListener!=null){
recyclerViewItemOnClickListener.onRecyclerViewClick(getAdapterPosition());
}
}
});
}
}
private RecyclerViewItemOnClickListener recyclerViewItemOnClickListener;
public void setRecyclerViewItemOnClickListener(RecyclerViewItemOnClickListener listener){
recyclerViewItemOnClickListener = listener;
}
public interface RecyclerViewItemOnClickListener{
void onRecyclerViewClick(int postion);
}
}
然后,在Avtivity类中设置获取到的Adapter的onclick事件。
package com.example.senconddemo_recyclerview;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.LinearLayout;
import android.widget.ListView;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private List<Bean> data = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
for (int i = 99959; i < 300000; i++) {
Bean bean = new Bean("zjp"+i+ " ");
data.add(bean);
}
RecyclerView recyclerView = findViewById(R.id.rv);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(linearLayoutManager);
MyAdapater myAdapater = new MyAdapater(data,this);
recyclerView.setAdapter(myAdapater);
myAdapater.setRecyclerViewItemOnClickListener(new MyAdapater.RecyclerViewItemOnClickListener() {
@Override
public void onRecyclerViewClick(int postion) {
Log.e("leo","RecyclerView Click");
}
});
}
}
效果如下:
点击后,打印日志
|