RecycerView、CardView、SwipeRefreshLayouter的使用

发布于:2023-01-08 ⋅ 阅读:(291) ⋅ 点赞:(0)

目录

一、添加依赖库

二、布局

三、准备数据

四、RecyclerView的适配器

五、在MainActivity中(详细内容看注释)

六、运行效果

一、添加依赖库

在项目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();
        }
    }
}

六、运行效果

             今天的总结就到这里了,谢谢大家观看。最后,希望大家可以给我点点赞支持一下!

本文含有隐藏内容,请 开通VIP 后查看