• RecyclerView入门


    概念

    什么是recyclerView?我们常见的可以滑动的,分块的视图样式就可以认为是recyclerView。

    比如:

    在开发前还需要了解一些概念:

    ViewHolder:可以看到recyclerView是以分块的视图形式组织的。分块无论其形状,里面的内容如何,每一个分快称之为ViewHolder。上图中一个title+subtitle的条形分块就是一个ViewHolder。

    Adapter:可以确认的是,recyclerView一定是有数据填充的,也一定有一个工具性质的东西能够将数据正确地和每一个ViewHolder绑定,进而渲染其内容。实现这个流程的工具就是Adapter。

    知道以上概念之后就可以开发了。

    1.创建recylerView视图与对象

    首先在需要展示的view里创建一个recyclerView:

    1. "1.0" encoding="utf-8"?>
    2. <androidx.constraintlayout.widget.ConstraintLayout
    3. xmlns:android="http://schemas.android.com/apk/res/android"
    4. xmlns:app="http://schemas.android.com/apk/res-auto"
    5. xmlns:tools="http://schemas.android.com/tools"
    6. android:layout_width="match_parent"
    7. android:layout_height="wrap_content"
    8. tools:context=".MainActivity">
    9. <androidx.recyclerview.widget.RecyclerView
    10. android:id="@+id/recycler_view"
    11. android:layout_width="match_parent"
    12. android:layout_height="match_parent"
    13. app:layout_constraintTop_toTopOf="parent"
    14. app:layout_constraintLeft_toLeftOf="parent"
    15. />
    16. androidx.constraintlayout.widget.ConstraintLayout>

    随后在代码中获取其对象: 

            mRecyclerView = this.findViewById(R.id.recycler_view);
    

    此外,viewHolder的视图也需要自定义

    1. "1.0" encoding="utf-8"?>
    2. "http://schemas.android.com/apk/res/android"
    3. android:layout_width="match_parent"
    4. android:layout_height="wrap_content"
    5. xmlns:app="http://schemas.android.com/apk/res-auto"
    6. xmlns:tools="http://schemas.android.com/tools"
    7. android:id="@+id/list_item">
    8. android:id="@+id/main_title"
    9. android:layout_width="wrap_content"
    10. android:layout_height="40dp"
    11. android:textSize="30sp"
    12. app:layout_constraintLeft_toLeftOf="parent"
    13. app:layout_constraintTop_toTopOf="parent"
    14. android:layout_centerVertical="true"
    15. tools:text="你好"/>
    16. android:id="@+id/subtitle"
    17. app:layout_constraintLeft_toLeftOf="@id/main_title"
    18. app:layout_constraintTop_toBottomOf="@id/main_title"
    19. android:layout_marginTop="10dp"
    20. android:textSize="12sp"
    21. android:layout_height="20dp"
    22. android:layout_width="wrap_content"
    23. android:layout_centerVertical="true"
    24. tools:text="是的"/>

     

    2.创建数据类型

    为了方便组织代码,我们通常将每个viewHolder中需要用到的数据抽象成一个data object。

    1. public class ItemDTO {
    2. public String Title;
    3. public String subTitle;
    4. }

    这里为了方便,本地mock出一组给recylerView使用的数据(数组)。

    1. private void mockData() {
    2. itemDTOList = new ArrayList<>();
    3. for (int i = 0; i < 20 ;i++) {
    4. ItemDTO itemDTO = new ItemDTO();
    5. itemDTO.Title = "title" + i;
    6. itemDTO.subTitle = "subtitle" + i;
    7. itemDTOList.add(itemDTO);
    8. }
    9. }

    3.创建adapter和viewHolder

    这是最难的一步,先贴上代码。

    1. package recyclerview;
    2. import android.util.Log;
    3. import android.view.View;
    4. import android.view.ViewGroup;
    5. import android.widget.TextView;
    6. import androidx.recyclerview.widget.RecyclerView;
    7. import com.example.myapplication.R;
    8. import java.util.List;
    9. public class ListViewAdapter extends RecyclerView.Adapter {
    10. private final static String TAG = "ListViewAdapter";
    11. // 绑定在recyclerView的数据集
    12. private final List mItemDTOList;
    13. public ListViewAdapter(List mItemDTOList) {
    14. this.mItemDTOList = mItemDTOList;
    15. }
    16. /**
    17. * 首次创建viewHolder时调用
    18. * @param parent
    19. * @param viewType
    20. * @return
    21. */
    22. @Override
    23. public viewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    24. Log.d(TAG, "onCreateViewHolder");
    25. // 创建viewHolder
    26. View viewHolder = View.inflate(parent.getContext(), R.layout.list_view_item, null);
    27. return new ListViewAdapter.viewHolder(viewHolder);
    28. }
    29. /**
    30. * 上下滑动recyclerView调用
    31. * @param holder
    32. * @param position
    33. */
    34. @Override
    35. public void onBindViewHolder(ListViewAdapter.viewHolder holder, int position) {
    36. // 给对应位置的viewHolder绑定数据
    37. holder.bindData(mItemDTOList.get(position));
    38. }
    39. @Override
    40. public int getItemCount() {
    41. if (mItemDTOList == null || mItemDTOList.isEmpty()) {
    42. return 0;
    43. } else {
    44. return mItemDTOList.size();
    45. }
    46. }
    47. /**
    48. * viewHolder对象
    49. */
    50. public class viewHolder extends RecyclerView.ViewHolder {
    51. private final TextView mMainTitle;
    52. private final TextView mSubtitle;
    53. public viewHolder(View itemView) {
    54. super(itemView);
    55. mMainTitle = itemView.findViewById(R.id.main_title);
    56. mSubtitle = itemView.findViewById(R.id.subtitle);
    57. }
    58. /**
    59. * 将数据映射到每个viewHolder的视图上
    60. * @param itemDTO
    61. */
    62. public void bindData(ItemDTO itemDTO) {
    63. mMainTitle.setText(itemDTO.Title);
    64. mSubtitle.setText(itemDTO.subTitle);
    65. Log.d(TAG, "bindData: title = " + itemDTO.Title + " , subtitle = " + itemDTO.subTitle);
    66. }
    67. }
    68. }

    viewHolder

    自定义的viewHolder集成了安卓原生的viewHolder,并自己实现了一个核心方法。

    viewHolder有两个任务:

    1.初始化viewHolder的视图组件

    2.提供数据绑定的方法,将之前定义的data object里的数据设置到视图中。

    核心方法:bindData,将data object里的数据设置到视图组件中。

    Adapter

    自定义的adapter继承了安卓原生的adapter,并重写两个核心方法。

    adapter有三个任务:

    1.获取到需要绑定到整个recyclerView的数据集。

    2.在创建viewHolder时,创建自定义的viewHolder。

    3.在绑定数据时,将对应的data object传给对应的viewHolder。

    核心方法onCreateViewHolder:

    调用时机:每个viewHolder被创建时(不一定每个都创建)

    recyclerView有复用viewHolder的机制,即同一个类型的viewHolder不会一直重复创建。尤其是整个recylerView只有一种viewHolder时,在第一次填满整个屏幕后通常就不会再创建viewHolder了,而是通过重复绑定数据来刷新视图,给用户一种不断滑动的感觉。

    因此在创建viewHolder时,我们只需要把viewHolder inflate出来,并返回即可。

    核心方法onBindViewHolder:

    调用时机:每个viewHolder被绑定数据时(每个都被绑数据)

    从刚才的描述可以得知,数据绑定这一操作是贯彻在滑动过程中的。该方法调用时会传入当前的viewHolder和当前viewHolder在整个recyclerView的位置。

    因此在绑定数据时,我们只需要执行每个viewHolder的bindData即可。

    4.设置recylerView

    1. private void initData() {
    2. // 填充数据
    3. mockData();
    4. // 创建adapter 必须
    5. ListViewAdapter listViewAdapter = new ListViewAdapter(itemDTOList);
    6. // 设置recyclerView的排列模式 必须
    7. LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
    8. mRecyclerView.setLayoutManager(linearLayoutManager);
    9. // 设置adapter 必须
    10. mRecyclerView.setAdapter(listViewAdapter);
    11. }

    recylerView必须设置的两个元素:排列模式和adapter,否则无法正确运行。

  • 相关阅读:
    Postgres-on conflict do 引起的core宕问题
    解决 VS2022 关于 c++17 报错: C2131 表达式必须含有常量值
    第60节——使用redux-toolkit实战一个商品列表的增删查改
    Grafana+Prometheus 搭建 JuiceFS 可视化监控系统
    C++学习笔记--黑马程序员
    计算机组成学习-数据的表示和运算总结
    ASP.NET Core Web API 接口限流
    5G商企专网,助力打造城市生命线“安徽样板”
    kaggle机器学习baselines
    顺序栈算法库构建
  • 原文地址:https://blog.csdn.net/m0_37872216/article/details/136787656