【Android】RecyclerView实现新闻列表布局(1)适配器使用相关问题


三三要成为安卓糕手

一:RecycleView

RecyclerView 英 [ri:'saɪklə] 是 Android 开发中的一个重要组件,通常直译为 "recycler 视图"循环视图

1:目标需求

做一个这样的新闻列表

(1)源码

二:用RecyclerView完成一个列表式布局

1:依赖添加

RecycleView也属于三方工具,老工程可能需要添加依赖

工程比较新,就无需添加依赖了,它已经集成在material中了

2:xml代码

我们一般不在RecycleView中添加控件item,而是通过其他方式往里面添加控件,这里介绍适配器方式

xml 复制代码
    <androidx.recyclerview.widget.RecyclerView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/recycler_view"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

为item新建一个布局,注意Width约束条件设置为0dp

xml 复制代码
<?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="match_parent"
    android:layout_height="wrap_content">

    <ImageView
        android:id="@+id/tv_picture"
        android:layout_width="100dp"
        android:layout_height="70dp"
        android:scaleType="centerCrop"
        android:src="@drawable/icon_logo"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/tv_title"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginLeft="8dp"
        android:ellipsize="end"
        android:maxLines="2"
        android:text="落魄谷中寒风吹,春秋蝉鸣少年归,荡魂山处石人泪,定仙游走魔向北,逆流河上万仙退,爱情不敌坚持泪,宿命天成命中败,仙尊悔而我不悔"
        android:textSize="18sp"
        android:textStyle="bold"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@id/tv_picture"
        app:layout_constraintTop_toTopOf="@id/tv_picture" />

    <TextView
        android:id="@+id/tv_author"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginLeft="8dp"
        android:ellipsize="end"
        android:maxLines="1"
        android:text="作者:大爱仙尊"
        android:textSize="16sp"
        app:layout_constraintStart_toEndOf="@id/tv_picture"
        app:layout_constraintTop_toBottomOf="@+id/tv_title" />


</androidx.constraintlayout.widget.ConstraintLayout>

在复习一下图片的缩放模式,这里是xy按比例缩放匹配宽高,多的裁掉------图片的缩放模式是跟着我们的ImageView来变化的

三:Item与Adapter做关联

两个都是xml布局,怎么关联起来???王德发------Adapter,我他喵莱纳

1:Adapter

资讯类的适配器,单独创建一个java类

java 复制代码
public class ArticleAdapter extends RecyclerView.Adapter {

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        //找item布局,把item转为视图,与LayoutInflater有异曲同工之处
        View view = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.item_article_simple, parent, false);

        //创建一个ViewHolder对itemView做管理
        MyViewHolder myViewHolder = new MyViewHolder(view);
        //ViewHolder和RecycleView做关联
        return myViewHolder;
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {

    }


    /**
     * @return  告诉RecyclerView显示多少条数据
     */
    @Override
    public int getItemCount() {
        return 20;
    }

    public class MyViewHolder extends RecyclerView.ViewHolder{

        public MyViewHolder(@NonNull View itemView) {
            super(itemView);
        }
    }


}

继承Recycle.Adapter,重写onCreateViewHolder、onBindViewHolder、getItemCount三个方法,下面进行分析

2:创建Holder

很关键的方法onCreateViewHolder "视图持有者" ,可以理解成一个杯子,而item数据可以理解成咖啡

  • 作用:创建新的 ViewHolder 对象

  • 参数:

    • parent:RecyclerView 本身
    • viewType:用于区分不同类型的 item(多布局时使用)
  • 返回值:ViewHolder 对象,通常包含一个 itemView

  • 触发时机:当 RecyclerView 需要创建新的 ViewHolder 时调用

3:绑定Holder

  • 作用:将数据绑定到 ViewHolder 上

  • 参数:

    • holder:需要绑定数据的 ViewHolder
    • position:当前 item 的位置
  • 返回值:无

  • 触发时机:当 ViewHolder 需要展示数据时调用

4:getItemCount

  • 作用:返回 RecyclerView 中的 item 总数
  • 参数:无
  • 返回值:int 类型的 item 数量
  • 触发时机:RecyclerView 需要知道数据量时调用

5:onCreateViewHolder() 的调用时机和次数

  • 初始加载时 :当 RecyclerView 显示,会根据屏幕能容纳的item数量(假设 10 条),调用 onCreateViewHolder() 创建对应数量的 ViewHolder(10 个 "杯子")。
  • 滑动过程中 :如果后续滑动时,新的列表项进入屏幕,而之前回收的 ViewHolder 不足以复用(比如快速滑动导致临时需求增加),可能会额外多创建几个 ViewHolder作为 "缓冲"(比如 12 个),但不会超过可见数量太多。

6:onCreateViewHolder() 的调用时机和次数

滑动过程中 :每次有新的列表项进入屏幕(无论是向上滑还是向下滑),都会触发 onBindViewHolder(),为复用的 ViewHolder 绑定新位置的数据(比如滑出屏幕的 item1 的 ViewHolder,会被重新绑定 item11 的数据)。

7:在Adapter中怎么找到布局

我们在RecyclerView.Adapter中获取不到LayoutInflater(布局加载器),但是没有关系;这种可以借鉴这种思想

java 复制代码
@NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        //找item布局,把item转为视图,与LayoutInflater有异曲同工之处
        View view = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.item_article_simple, parent, false);

        //创建一个ViewHolder对itemView做管理
        MyViewHolder myViewHolder = new MyViewHolder(view);
        //ViewHolder和RecycleView做关联
        return myViewHolder;
    }

(1)LayoutInflater.from(parent.getContext()).inflate

  • parent.getContext获取RecycleView的上下文

  • from方法用于获取LayoutInflater实例对象

  • 在调用充气方法哈哈转化为view视图妙啊妙啊

  • 参数之前用过前两个,这里三个,解释parent和false:

    • parent:parent 是父布局容器(即RecyclerView本身)用于为加载的布局(这里指R.layout.item_article_simple)提供正确的 布局参数LayoutParams
    • false:仅加载布局,不添加到 parent,返回加载的布局视图。若为true,会导致布局被立即添加到 RecyclerView 中,而 RecyclerView 自身也会尝试添加该视图,最终抛出 IllegalStateException

基本就是固定写法了

总结

  • parentRecyclerView 实例,用于提供布局参数和上下文。
  • attachToRoot = false 避免子项被重复添加。
  • ViewHolder 需要在 onCreateViewHolder 中正确返回。

(2)ViewHolder

两者做关联还需要一个东西ViewHolder 视图口袋,它会对item的布局做一些管理,item本身会被放到ViewHolder里面;

作用:复用已经滑出屏幕的旧视图,缓存这些视图的引用

他是一个抽象类,不能直接使用,我们自己去创建一个类,然后继承它

java 复制代码
		//创建一个ViewHolder对itemView做管理
        MyViewHolder myViewHolder = new MyViewHolder(view);
		return myViewHolder;


	public class MyViewHolder extends RecyclerView.ViewHolder{

        public MyViewHolder(@NonNull View itemView) {
            super(itemView);
        }
    }

上面的代码仅完成了 适配器(Adapter)与列表项布局(Item)的关联 ,但 RecyclerView 尚未与适配器绑定

问题又来了,RecycleView怎么和适配器关联起来?

四:RecycleView和Adapter关联

1:代码

java 复制代码
public class ArticleListActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_article_list);

        //找到循环视图
        RecyclerView recyclerView = findViewById(R.id.recycler_view);

        //将item排列为一维列表,默认是竖向
        LinearLayoutManager layoutManager = new LinearLayoutManager(this);

        //线性方向改成横向
//        layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);

        //为RecycleView添加布局管理器
        recyclerView.setLayoutManager(layoutManager);


        //设置适配器
        recyclerView.setAdapter(new ArticleAdapter());

    }
}

2:排列方向

了解即可

  • LinearLayoutManager:将item排列在一维列表
  • GridLayoutManager:将item排列在二维网络
  • StaggeredGridLayoutManager:瀑布流排列

3:总结

为RecycleView添加布局管理器,管理器内部是布局方向,最后为RecycleView设置适配器

五:效果

左图垂直排列,右图横向排列


总结:item匹配适配器,找到布局转为视图,ViewHolder(需要继承)作为item的管理器;RecycleView匹配Adapter需要设置布局管理器,让item以怎样的形式展现

相关推荐
侠客行03171 天前
Mybatis连接池实现及池化模式
java·mybatis·源码阅读
蛇皮划水怪1 天前
深入浅出LangChain4J
java·langchain·llm
子兮曰1 天前
OpenClaw入门:从零开始搭建你的私有化AI助手
前端·架构·github
Victor3561 天前
https://editor.csdn.net/md/?articleId=139321571&spm=1011.2415.3001.9698
后端
吴仰晖1 天前
使用github copliot chat的源码学习之Chromium Compositor
前端
1024小神1 天前
github发布pages的几种状态记录
前端
Victor3561 天前
Hibernate(89)如何在压力测试中使用Hibernate?
后端
灰子学技术1 天前
go response.Body.close()导致连接异常处理
开发语言·后端·golang
老毛肚1 天前
MyBatis体系结构与工作原理 上篇
java·mybatis
风流倜傥唐伯虎1 天前
Spring Boot Jar包生产级启停脚本
java·运维·spring boot