RecyclerViewActivity:
public class RecyclerViewActivity extends AppCompatActivity {
private List<Fruit> fruitList = new ArrayList<>();
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recyclerview);
initFruits();//初始化水果数据
RecyclerView recyclerView = findViewById(R.id.recyclerView);
//创建一个LinearLayoutManager对象,LinearLayoutManager是用于指定RecyclerView的布局方式,
//这里使用的LinearLayoutManager是线性布局的,可以实现类似ListVIew类似的效果。
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(linearLayoutManager);
// recyclerView.setLayoutManager(new GridLayoutManager(this,3));//使recyclerView呈九宫格显示
//创建FruitAdapter实例,并将水果数据传入FruitAdapter的构造函数中
FruitAdapter adapter = new FruitAdapter(fruitList);
//调用setAdapter()方法将构建好的适配器对象传递进去,使ListView和数据之间的关联建立完成
recyclerView.setAdapter(adapter);
}
private void initFruits() {
for (int i = 0;i<2;i++){
Fruit apple = new Fruit("apple",R.mipmap.ic_launcher);
fruitList.add(apple);
Fruit banana = new Fruit("banana",R.mipmap.ic_launcher);
fruitList.add(banana);
Fruit orange = new Fruit("orange",R.mipmap.ic_launcher);
fruitList.add(orange);
}
}
}
FruitAdapter
public class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder> {
private List<Fruit> mFruitList;
static class ViewHolder extends RecyclerView.ViewHolder{
ImageView imageView;
TextView textView;
public ViewHolder(@NonNull View itemView) {
super(itemView);
imageView = itemView.findViewById(R.id.iv);
textView = itemView.findViewById(R.id.tv);
}
}
public FruitAdapter(List<Fruit> fruitList){
this.mFruitList = fruitList;
}
//onCreateViewHolder方法用于创建ViewHolder实例和将在布局的
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.listview_item,parent,false);
ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
//onBindViewHolder用于对RecyclerView子项的数据进行赋值,会在每个被滚动到屏幕内的时候执行,
// 这里我们通过position参数得到当前项的Fruit实例,在将数据设置到ViewHolder的ImageView和TextView中
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
Fruit fruit = mFruitList.get(position);
holder.imageView.setImageResource(fruit.getImageId());
holder.textView.setText(fruit.getName());
}
//getItemCount用于告诉RecyclerView一共与偶多少子项,直接返回数据源的长度就行
@Override
public int getItemCount() {
return mFruitList.size();
}
}
Fruit
public class Fruit {
private String name;
private int imageId;
public Fruit(String name, int imageId) {
this.name = name;
this.imageId = imageId;
}
public String getName() {
return name;
}
public int getImageId() {
return imageId;
}
}
listview_item
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:id="@+id/iv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/tv"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
注意item处的android:layout_height="wrap_content"的wrap_content,如果是match_parent一个item就会填满屏幕,其他的item要翻下一页才能显示出来
RecyclerView实现横向滚动、瀑布流和网格布局
横向布局
仅仅只需在Activity中加入一段话即可
layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
瀑布流布局
将LinearLayoutManager layoutManager = new LinearLayoutManager(this);
修改为StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL);
其中第一个参数用于指定布局的列数,第而个参数用与指定布局的排列方式
网格布局
修改与瀑布流布局相似
GridLayoutManager gridLayoutManager = new GridLayoutManager(this,3);//使recyclerView呈九宫格显示
RecyclerView的点击事件
修改FruitAdapter处代码
public class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder> {
private List<Fruit> mFruitList;
static class ViewHolder extends RecyclerView.ViewHolder{
View fruitView;
ImageView imageView;
TextView textView;
public ViewHolder(@NonNull View itemView) {
super(itemView);
fruitView = itemView;
imageView = itemView.findViewById(R.id.iv);
textView = itemView.findViewById(R.id.tv);
}
}
public FruitAdapter(List<Fruit> mFruitList) {
this.mFruitList = mFruitList;
}
//onCreateViewHolder方法用于创建ViewHolder实例和将在布局的
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.listview_item,parent,false);
final ViewHolder viewHolder = new ViewHolder(view);
viewHolder.fruitView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int position = viewHolder.getAbsoluteAdapterPosition();
//此处本来用getAdapterPosition(),现改用getAbsoluteAdapterPosition()和getBindingAdapterPosition()搭配使用
Fruit fruit = mFruitList.get(position);
Toast.makeText(v.getContext(),"you click view"+fruit.getName(),Toast.LENGTH_SHORT).show();
}
});
viewHolder.imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int position = viewHolder.getBindingAdapterPosition();
Fruit fruit = mFruitList.get(position);
Toast.makeText(v.getContext(),"you click image"+fruit.getName(),Toast.LENGTH_SHORT).show();
}
});
viewHolder.textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int position = viewHolder.getBindingAdapterPosition();
Fruit fruit = mFruitList.get(position);
Toast.makeText(v.getContext(),"you click name"+fruit.getName(),Toast.LENGTH_SHORT).show();
}
});
return viewHolder;
}
//onBindViewHolder用于对RecyclerView子项的数据进行赋值,会在每个被滚动到屏幕内的时候执行,
// 这里我们通过position参数得到当前项的Fruit实例,在将数据设置到ViewHolder的ImageView和TextView中
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
Fruit fruit = mFruitList.get(position);
holder.imageView.setImageResource(fruit.getImageId());
holder.textView.setText(fruit.getName());
}
//getItemCount用于告诉RecyclerView一共与偶多少子项,直接返回数据源的长度就行
@Override
public int getItemCount() {
return mFruitList.size();
}
}
我们先是修改了ViewHolder处代码,在ViewHolder 中添加fruitView变量来保存子项最外面的布局的实例(即若点击的不是item内的控件而是控件之外的地方),然后在onCreateViewHolder方法中为最外层布局和item内控件注册点击事件。
viewHolder.getAbsoluteAdapterPosition();
//此处本来用getAdapterPosition(),现改用getAbsoluteAdapterPosition()和getBindingAdapterPosition()搭配使用
上面代码的getAdapterPosition()由于点击指定的不明确而被弃用,使用getAbsoluteAdapterPosition()和getBindingAdapterPosition()替代,
getAbsoluteAdapterPosition()方法表示子项最外卖呢的布局,
getBindingAdapterPosition()方法表示item内控件的单独位置。