Android 列表或网格形式展示大量数据:RecyclerView

目录

  1. RecyclerView是什么
  2. 如何使用
  3. RecyclerView 涉及到的类
  4. LayoutManager
  5. 为Item设置不同的布局样式
  6. 制作拖动的RecyclerView

一、RecyclerView是什么

RecyclerView是Android支持库中的一个控件,用于在列表或网格形式展示大量数据。它是ListView的升级版,提供了更灵活、可定制化的方式来展示和管理数据。

二、如何使用

RecyclerView的使用步骤:

  1. 创建RecyclerView控件对象
  2. 设置适配器 : 一般是使用自定义的适配器 , 设置给 RecyclerView 对象 ;
  3. 创建适配器的布局文件
  4. 创建并设置布局管理器 : 可以使用预置的布局管理器 , 也可以自定义布局管理器 ;

(1)创建控件


    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/home_rv_product"
        android:layout_width="1500dp"
        android:layout_height="800dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

(2)创建适配器

class HomeProductAdapter(var productList:ArrayList<HomeProductBean>): RecyclerView.Adapter<HomeProductAdapter.MyViewHolder>() {

    inner class MyViewHolder(view: View): RecyclerView.ViewHolder(view){
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
       val view = LayoutInflater.from(parent.context).inflate(R.layout.home_item_home_product,parent,false)
        return MyViewHolder(view)
    }

    override fun getItemCount(): Int {
        return productList.size
    }

    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
    }
}
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="200dp"
    android:layout_height="270dp"
    android:layout_marginRight="20dp"
    android:layout_marginBottom="20dp"
    android:background="@drawable/dingdian_imge_price_bg">


    <ImageView
        android:id="@+id/iv_sugar"
        android:layout_width="150dp"
        android:layout_height="150dp"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="28dp"
        android:src="@drawable/icon_coin"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />


    <TextView
        android:id="@+id/tv_name1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:text="蓝色棉花"
        android:textColor="#fa7698"
        android:textSize="22sp"
        android:textStyle="bold"
        android:layout_marginTop="10dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/iv_sugar" />

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        android:gravity="center"
        android:layout_marginTop="10dp"
        app:layout_constraintTop_toBottomOf="@+id/tv_name1">

        <ImageView
            android:id="@+id/home_imageview"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginRight="5dp"
            android:src="@drawable/icon_coin" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:text="0.0"
            android:textColor="#fa7698"
            android:textSize="30sp"
            android:textStyle="bold"/>

    </LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

(3)进行使用

class HomeFragment : BaseFragment<HomeFragmentHomeBinding, HomeFragmentVM>() {

    private val productList  = ArrayList<HomeProductBean>()
    private var homeProductAdapter:HomeProductAdapter? = null


    override fun HomeFragmentHomeBinding.initView() {

        //设置布局排列方式,默认垂直排列
        val gridLayoutManager: GridLayoutManager =
            GridLayoutManager(this@HomeFragment.context, 6, GridLayoutManager.VERTICAL, false)
        homeRvProduct.layoutManager = gridLayoutManager

        //设置adapter
        productList.add(HomeProductBean(1,"asdf"))
        productList.add(HomeProductBean(1,"asdf"))
        productList.add(HomeProductBean(1,"asdf"))
        productList.add(HomeProductBean(1,"asdf"))
        productList.add(HomeProductBean(1,"asdf"))
        productList.add(HomeProductBean(1,"asdf"))
        productList.add(HomeProductBean(1,"asdf"))
        ....
        homeProductAdapter = HomeProductAdapter(productList)
        homeRvProduct.adapter = homeProductAdapter

        tvTime.setOnLongClickListener {
            val findNavController = findNavController()
            findNavController.navigate(R.id.home_action_home_homefragment_to_home_userloginfragment)
            return@setOnLongClickListener true
        }
    }


}

运行结果:
在这里插入图片描述

三、RecyclerView 涉及到的类

  1. RecyclerView:是RecyclerView控件的核心类,用于展示和管理数据。它负责协调LayoutManager、Adapter和ItemAnimator之间的交互,并处理用户交互事件。

  2. RecyclerView.Adapter:是RecyclerView的适配器类,负责将数据绑定到RecyclerView上。开发者需要继承该类并实现必要的方法,如创建ViewHolder、绑定数据等。

  3. RecyclerView.ViewHolder:是RecyclerView中每个列表项或网格项的持有者类。它包含了对应项的视图以及与之相关的操作。通过重写Adapter的 onCreateViewHolder() 方法来创建ViewHolder。RecyclerView.Adapter 适配器 的 onBindViewHolder 方法中为其关联数据 ;

  4. RecyclerView.LayoutManager:是RecyclerView的布局管理器类,负责决定子项的排列方式。Android提了一些默认的LayoutManager,如LinearLayoutManager(线性布局)、GridLayoutManager(网格布局)和StaggeredGridLayoutManager(瀑布流布局),也可以自定义LayoutManager。

  5. RecyclerView.ItemDecoration:是RecyclerView的装饰器类,用于为列表项添加分割线或其他样式。开发者可以继承该类并实现相应的方法,然后通过RecyclerView的addItemDecoration方法添加装饰器。
    【binding.rvX.addItemDecoration(new CustomDecoration(mContext, LinearLayoutManager.VERTICAL, 2));】这句代码的作用是在RecyclerView中添加一个自定义的装饰器,用于给列表项之间添加分割线,并指定分割线的宽度和方向。

  6. RecyclerView.ItemAnimator:是RecyclerView的动画类,用于在插入、删除和移动列表项时添加过渡动画效果。Android提供了一些默认的ItemAnimator,如DefaultItemAnimator和SimpleItemAnimator,也可以自定义ItemAnimator。

四、LayoutManager

4.1 线性布局 LinearLayoutManager

使用代码创建 线性布局管理器 LinearLayoutManager

LinearLayoutManager(Context context, @RecyclerView.Orientation int orientation, boolean reverseLayout)

context:表示上下文对象,通常是Activity或Fragment的引用。
orientation:表示布局的方向,可以是RecyclerView.HORIZONTAL(水平方向)或RecyclerView.VERTICAL(垂直方向)。
reverseLayout:表示是否将布局进行反转。如果设置为true,则列表项会从尾部开始排列;如果设置为false,则列表项会从头部开始排列。

reverseLayout这个参数在某些情况下很有用,比如当需要实现类似聊天界面的消息列表时,可以将reverseLayout设置为true,使得新的消息始终显示在列表的底部。


 LinearLayoutManager layoutManagerFirst = new LinearLayoutManager(mContext,RecyclerView.HORIZONTAL,true);
 
 advancedNewBinding.rvAdvancedFirst.setLayoutManager(layoutManagerFirst);

4.2 GridLayoutManager

使用代码创建 线性布局管理器 GridLayoutManager

GridLayoutManager (Context context, int spanCount, @RecyclerView.Orientation int orientation, boolean reverseLayout)

参数同LinearLayoutManager一样。

int spanCount : 网格布局行或列的个数.

 GridLayoutManager layoutManager = new GridLayoutManager(mContext, 8, GridLayoutManager.HORIZONTAL, false);
        
 advancedBinding.rvPara.setLayoutManager(layoutManager);

五、为Item设置不同的布局样式

比如,有的item需要的是:
布局一:文本+输入框+按钮
布局二:按钮
在这里插入图片描述

 @Override
    public int getItemViewType(int position) {
    		//这里为不同位置的组件设置不同的布局类型 ;
        if (position > 27) return TYPE_OTHER;
        return TYPE_NORMAL;
    }
 @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
        View inflate;
        //根据布局类型加载不同的布局文件
        if (viewType == TYPE_NORMAL) {
            inflate = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_parameter_new, viewGroup, false);
            return new ViewHolder(inflate);
        } else {
            inflate = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_manual_advanced, viewGroup, false);
            return new ViewHolderOther(inflate);
        }


    }

六、制作拖动的RecyclerView

比如我们想通过拖动item来调整位置,应该如何操作呢?
ItemTouchHelper 可以为 RecyclerView 添加拖动效果 ;

ItemTouchHelper 需要与 RecyclerView 和 ItemTouchHelper.Callback 结合起来使用 ;

 ItemTouchHelper helper = new ItemTouchHelper(new ItemTouchHelper.Callback() {
        //线性布局和网格布局都可以使用
        @Override
        public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
            int dragFrlg = 0;
            if (recyclerView.getLayoutManager() instanceof GridLayoutManager) {
                dragFrlg = ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
            } else if (recyclerView.getLayoutManager() instanceof LinearLayoutManager) {
                dragFrlg = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
            }
            return makeMovementFlags(dragFrlg, 0);
        }

        @Override
        public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
            //滑动事件  下面注释的代码,滑动后数据和条目错乱,被舍弃
//            Collections.swap(datas,viewHolder.getAdapterPosition(),target.getAdapterPosition());
//            ap.notifyItemMoved(viewHolder.getAdapterPosition(),target.getAdapterPosition());

            //得到当拖拽的viewHolder的Position
            int fromPosition = viewHolder.getAdapterPosition();
            //拿到当前拖拽到的item的viewHolder
            int toPosition = target.getAdapterPosition();
            if (fromPosition < toPosition) {
                for (int i = fromPosition; i < toPosition; i++) {
                    Collections.swap(showAdapter.getGoodsBeans(), i, i + 1);
                }
            } else {
                for (int i = fromPosition; i > toPosition; i--) {
                    Collections.swap(showAdapter.getGoodsBeans(), i, i - 1);
                }
            }
            showAdapter.notifyItemMoved(fromPosition, toPosition);
            return true;
        }

        @Override
        public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
            //侧滑删除可以使用;
        }

        @Override
        public boolean isLongPressDragEnabled() {
        //启用长按拖动功能
            return true;
        }

        /**
         * 长按选中Item的时候开始调用
         * 长按高亮
         *
         * @param viewHolder
         * @param actionState
         */
        @SuppressLint("MissingPermission")
        @Override
        public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
            super.onSelectedChanged(viewHolder, actionState);
            if (actionState == ItemTouchHelper.ACTION_STATE_DRAG) {
                viewHolder.itemView.setScaleX(1.1f);
                viewHolder.itemView.setScaleY(1.1f);
            }
        }

        /**
         * 手指松开的时候还原高亮
         *
         * @param recyclerView
         * @param viewHolder
         */
        @Override
        public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
            super.clearView(recyclerView, viewHolder);
            viewHolder.itemView.setBackgroundColor(0);
            showAdapter.notifyDataSetChanged();  //完成拖动后刷新适配器,这样拖动后删除就不会错乱
        }
    });

		//为rv设置helper
        helper.attachToRecyclerView(binding.rvShow);

  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值