目录
一、添加依赖库
在项目build.gradle导入RecyclerView、CardView、SwipeRefreshLayout的依赖库:
implementation 'androidx.recyclerview:recyclerview:1.2.1'
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
添加完之后记得点击Sync Now进行同步
CardView 的介绍:CardView - 简书 (jianshu.com)
SwipeRefreshLayouter介绍:
(1条消息) SwipeRefreshLayout的基本使用_fjnu_se的博客-CSDN博客_swiperefreshlayout
二、布局
(1)、activity_main的布局如下:
<?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="match_parent"
android:orientation="vertical"
>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/refresh"
>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</LinearLayout>
(2)、RecyclerView的子布局如下:
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
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"
android:layout_margin="5dp"
app:cardCornerRadius="4dp">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/goods_image"
android:layout_width="match_parent"
android:layout_height="100dp"
android:scaleType="centerCrop" />
<TextView
android:id="@+id/goods_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_margin="5dp"
android:textSize="16sp" />
</LinearLayout>
</androidx.cardview.widget.CardView>
三、准备数据
(1)、定义一个Goods类,属性有商品名称goodsName,商品图片goodsPic,还有构造方法和两个getxxx方法,就这么简单。
package com.example.recyclerviewtest;
public class Goods {
private String name;
private int picId;
public Goods(String name,int id){
this.picId = id;
this.name = name;
}
public String getName() {
return name;
}
public int getPicId() {
return picId;
}
}
(2)准备图片(我在网上找了20找那个图片放到了drawable)
定义一个picture类,里面定义一个数组Pics装图片
public class Picture {
public static final int[] Pics = {
R.drawable.img1,R.drawable.img2, R.drawable.img3,R.drawable.img4,
R.drawable.img5,R.drawable.img6,R.drawable.img7,R.drawable.img8,
R.drawable.img9,R.drawable.img10,R.drawable.img11,R.drawable.img13,
R.drawable.img12,R.drawable.img14,R.drawable.img15,R.drawable.img16,
R.drawable.img17,R.drawable.img18,R.drawable.img19,R.drawable.img20,
R.drawable.img15,R.drawable.img10,R.drawable.img14,R.drawable.img12,
};
}
四、RecyclerView的适配器
为RecyclerView准备一个适配器,这个适配器要继承自RecyclerView,并实现相应的方法。CommodityApater.ViewHolder,其中ViewHoler是我们自己定义的一个内部类。
在适配器中的方法的用法如下:
(1)内部类
在内部类的方法里找到item中的控件。
// 这就是内部类viewHolder
public class ViewHolder extends RecyclerView.ViewHolder {
private final ImageView mGoodsPic;
private final TextView mGoodsName;
private final View mGoodsView;
// 在构造方法找控件
public ViewHolder(@NonNull View itemView) {
super(itemView);
mGoodsView = itemView;
mGoodsPic = itemView.findViewById(R.id.goods_image);
mGoodsName = itemView.findViewById(R.id.goods_name);
}
}
(2)定义一个构造方法GoodsAdapter和全局变量集合goodsList
目的:是用来接收MainActivity传进来的数据
private final List<Goods> mGoodsList;
public GoodsAdapter(List<Goods> goodsList){
mGoodsList = goodsList;
}
(3)、在onCreateViewHolder()用于创建一个ViewHolder实例,并把加载出来的布局传入到构造函数中,最后将ViewHolder的实例返回。
// 这里是加载布局
public GoodsAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
// 获取view对象
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item,
parent, false);
// 创建ViewHolder对象
ViewHolder holder = new ViewHolder(view);
// 添加点击添加点击事件
// 这个是添加的是图片的点击事件
holder.mGoodsPic.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int position = holder.getAdapterPosition();
Goods goods = mGoodsList.get(position);
Toast.makeText(v.getContext(),"点击了"+goods.getName(),Toast.LENGTH_LONG).show();
}
});
// 添加的是添加的是点击文本框事件
holder.mGoodsName.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int position = holder.getAdapterPosition();
Goods goods = mGoodsList.get(position);
Toast.makeText(v.getContext(),"点击了"+goods.getName(),Toast.LENGTH_LONG).show();
}
});
return holder;
}
(4)onBindViewHolder()对子项的数据进行赋值和添加点击事件
@Override
public void onBindViewHolder(@NonNull GoodsAdapter.ViewHolder holder, int position) {
// 获取货物对象
Goods goods = mGoodsList.get(position);
// 在TextView mGoodsName给货物设置名称
holder.mGoodsName.setText(goods.getName());
// 在ImageView mGoodsPic设置货物的图片
holder.mGoodsPic.setImageResource(goods.getPicId());
}
(5)getItemCount()返回数据源的长度,即告诉RecyclerView一共有多少子项
@Override
public int getItemCount() {
// 如果集合不为空,就说明数据的大小不为0
if(mGoodsList!= null){
// 集合的大小就是数据的大小,所以返回集合的大小
return mGoodsList.size();
}
return 0;
}
适配器完整的代码如下:
package com.example.recyclerviewtest;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
public class GoodsAdapter extends RecyclerView.Adapter<GoodsAdapter.ViewHolder> {
private final List<Goods> mGoodsList;
public GoodsAdapter(List<Goods> goodsList){
mGoodsList = goodsList;
}
@NonNull
@Override
// 这里是加载布局
public GoodsAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
// 获取view对象
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item,
parent, false);
// 创建ViewHolder对象
ViewHolder holder = new ViewHolder(view);
// 添加点击添加点击事件
// 这个是添加的是图片的点击事件
holder.mGoodsPic.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int position = holder.getAdapterPosition();
Goods goods = mGoodsList.get(position);
Toast.makeText(v.getContext(),"点击了"+goods.getName(),Toast.LENGTH_LONG).show();
}
});
// 添加的是添加的是点击文本框事件
holder.mGoodsName.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int position = holder.getAdapterPosition();
Goods goods = mGoodsList.get(position);
Toast.makeText(v.getContext(),"点击了"+goods.getName(),Toast.LENGTH_LONG).show();
}
});
return holder;
}
@Override
public void onBindViewHolder(@NonNull GoodsAdapter.ViewHolder holder, int position) {
// 获取货物对象
Goods goods = mGoodsList.get(position);
// 在TextView mGoodsName给货物设置名称
holder.mGoodsName.setText(goods.getName());
// 在ImageView mGoodsPic设置货物的图片
holder.mGoodsPic.setImageResource(goods.getPicId());
}
@Override
public int getItemCount() {
if(mGoodsList!= null){
return mGoodsList.size();
}
return 0;
}
// 这就是内部类viewHolder
public class ViewHolder extends RecyclerView.ViewHolder {
private final ImageView mGoodsPic;
private final TextView mGoodsName;
private final View mGoodsView;
// 在构造方法找控件
public ViewHolder(@NonNull View itemView) {
super(itemView);
mGoodsView = itemView;
mGoodsPic = itemView.findViewById(R.id.goods_image);
mGoodsName = itemView.findViewById(R.id.goods_name);
}
}
}
五、在MainActivity中(详细内容看注释)
(1)、initData()方法是用来给集合添加数据,然后通过创建的适配器时,将集合数据传进适配器。
private void initData() {
for (int i = 0; i < Picture.Pics.length; i++) {
Goods goods = new Goods("商品"+i,Picture.Pics[i]);
mGoodsList.add(goods);
}
}
(2)、setAdapterWithLayout()是设置recyclerView的适配器和布局
private void setAdapterWithLayout() {
// 找到recyclerView控件
mRecyclerView = findViewById(R.id.recyclerView);
// 创建适配器
GoodsAdapter adapter = new GoodsAdapter(mGoodsList);
// 设置适配器
mRecyclerView.setAdapter(adapter);
// 获取瀑布流布局对象
GridLayoutManager manager = new GridLayoutManager(this,2);
// 设置布局
mRecyclerView.setLayoutManager(manager);
}
(3)、refresh()这个方法是用来刷新数据的。
private void refresh() {
SwipeRefreshLayout swipeRefresh= this.findViewById(R.id.refresh);
// 设置刷新条的颜色
swipeRefresh.setColorSchemeResources(R.color.teal_200);
// 设置监听刷新动作
swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
try {
// 进度条转2秒钟
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 在主线程中更新数据
runOnUiThread(new Runnable() {
@Override
public void run() {
// 更新数据
updateData();
// 这个是用来通知适配器数据更新了
mAdapter.notifyDataSetChanged();
// 更新完成之后,隐藏刷新的进度条
swipeRefresh.setRefreshing(false);
}
});
}
});
}
// 每次刷新更新10条数据
private void updateData() {
// 创建随机数对象
Random random = new Random();
for (int i = 1; i <= 10; i++) {
// 获取照片数组的索引
int index = random.nextInt(20);
// 创建更新的货物对象
Goods goods = new Goods("新数据"+i,Picture.Pics[index]);
// 添加到集合
mGoodsList.add(0,goods);
}
}
完整的MainActivity代码:
package com.example.recyclerviewtest;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import android.os.Bundle;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class MainActivity extends AppCompatActivity {
private List<Goods> mGoodsList = new ArrayList<>();
private RecyclerView mRecyclerView;
private GoodsAdapter mAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 准备数据
initData();
// 给recyclerView 设置适配器和设置布局
setAdapterWithLayout();
// 刷新
refresh();
}
private void refresh() {
SwipeRefreshLayout swipeRefresh= this.findViewById(R.id.refresh);
// 设置刷新条的颜色
swipeRefresh.setColorSchemeResources(R.color.teal_200);
// 设置监听刷新动作
swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
try {
// 进度条转2秒钟
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 在主线程中更新数据
runOnUiThread(new Runnable() {
@Override
public void run() {
// 更新数据
updateData();
// 这个是用来通知适配器数据更新了
mAdapter.notifyDataSetChanged();
// 更新完成之后,隐藏刷新的进度条
swipeRefresh.setRefreshing(false);
}
});
}
});
}
// 每次刷新更新10条数据
private void updateData() {
// 创建随机数对象
Random random = new Random();
for (int i = 1; i <= 10; i++) {
// 获取照片数组的索引
int index = random.nextInt(24);
// 创建更新的货物对象
Goods goods = new Goods("新数据"+i,Picture.Pics[index]);
// 添加到集合
mGoodsList.add(0,goods);
}
}
private void setAdapterWithLayout() {
// 找到recyclerView控件
mRecyclerView = findViewById(R.id.recyclerView);
// 创建适配器
mAdapter = new GoodsAdapter(mGoodsList);
// 设置适配器
mRecyclerView.setAdapter(mAdapter);
// 获取瀑布流布局对象
GridLayoutManager manager = new GridLayoutManager(this,2);
// 设置布局
mRecyclerView.setLayoutManager(manager);
}
// 设置数据
private void initData() {
for (int i = 0; i < Picture.Pics.length; i++) {
Goods goods = new Goods("商品"+i,Picture.Pics[i]);
mGoodsList.add(goods);
}
}
// 当我们退出APP时,释放资源
@Override
protected void onDestroy() {
super.onDestroy();
if (mGoodsList != null) {
// 清空集合
mGoodsList.clear();
}
}
}
六、运行效果
今天的总结就到这里了,谢谢大家观看。最后,希望大家可以给我点点赞支持一下!