You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何创建自适应尺寸的多图片网格?需整合RecyclerView与StaggeredGridLayoutManager

实现自适应图片的瀑布流网格(StaggeredGridLayoutManager + RecyclerView)

嘿,这需求我熟!用StaggeredGridLayoutManager搭配RecyclerView完全能搞定这个自适应尺寸的图片网格,我给你一步步拆解具体实现:

1. 准备布局文件

首先是主布局,只需要一个RecyclerView就行:

<?xml version="1.0" encoding="utf-8"?>
<androidx.recyclerview.widget.RecyclerView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/recyclerView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="8dp"/>

然后是图片Item的布局,用ImageView来承载图片,注意设置scaleType为centerCrop保证图片填充,高度设为wrap_content来实现自适应:

<?xml version="1.0" encoding="utf-8"?>
<ImageView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/imageView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:scaleType="centerCrop"
    android:layout_margin="4dp"/>

2. 实现RecyclerView Adapter

Adapter负责加载图片并自适应调整item高度,这里用Glide来处理图片加载(当然你也可以用其他图片加载库),关键是获取图片的原始宽高,然后根据网格列宽计算出对应的item高度,保证图片比例不变:

class ImageAdapter(private val imageUrls: List<String>) : RecyclerView.Adapter<ImageAdapter.ImageViewHolder>() {

    inner class ImageViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        val imageView: ImageView = itemView.findViewById(R.id.imageView)
    }

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

    override fun onBindViewHolder(holder: ImageViewHolder, position: Int) {
        val imageUrl = imageUrls[position]
        
        // 用Glide加载图片并计算自适应高度
        Glide.with(holder.imageView.context)
            .load(imageUrl)
            .listener(object : RequestListener<Drawable> {
                override fun onLoadFailed(e: GlideException?, model: Any?, target: Target<Drawable>?, isFirstResource: Boolean): Boolean {
                    return false
                }

                override fun onResourceReady(resource: Drawable?, model: Any?, target: Target<Drawable>?, dataSource: DataSource?, isFirstResource: Boolean): Boolean {
                    resource?.let {
                        val originalWidth = it.intrinsicWidth
                        val originalHeight = it.intrinsicHeight
                        // 获取屏幕宽度,计算单列的宽度(减去padding和margin)
                        val screenWidth = holder.imageView.context.resources.displayMetrics.widthPixels
                        val columnWidth = (screenWidth - (8 * 2) - (4 * 2)) / 2
                        // 按比例计算item高度
                        val targetHeight = (columnWidth * originalHeight) / originalWidth
                        // 更新ImageView的布局参数
                        val params = holder.imageView.layoutParams
                        params.height = targetHeight
                        holder.imageView.layoutParams = params
                    }
                    return false
                }
            })
            .into(holder.imageView)
    }

    override fun getItemCount(): Int = imageUrls.size
}

3. 初始化RecyclerView

在Activity或Fragment里,给RecyclerView设置StaggeredGridLayoutManager和Adapter,同时可以添加一些优化设置:

class MainActivity : AppCompatActivity() {
    private lateinit var recyclerView: RecyclerView
    // 替换成你的图片链接列表
    private val imageUrls = listOf(
        "https://example.com/image1.jpg",
        "https://example.com/image2.jpg",
        "https://example.com/image3.jpg",
        "https://example.com/image4.jpg"
    )

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        recyclerView = findViewById(R.id.recyclerView)

        // 初始化StaggeredGridLayoutManager,设置为2列垂直布局
        val layoutManager = StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL)
        // 关闭自动补全间隙,避免滚动时item跳动
        layoutManager.gapStrategy = StaggeredGridLayoutManager.GAP_HANDLING_NONE
        recyclerView.layoutManager = layoutManager

        // 设置Adapter
        recyclerView.adapter = ImageAdapter(imageUrls)
        // 添加自定义间距(可选)
        recyclerView.addItemDecoration(SpacesItemDecoration(4))
    }

    // 自定义间距装饰类
    class SpacesItemDecoration(private val space: Int) : RecyclerView.ItemDecoration() {
        override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
            outRect.left = space
            outRect.right = space
            outRect.top = space
            outRect.bottom = space
        }
    }
}

4. 必要依赖(如果用Glide)

记得在Module级别的build.gradle里添加Glide的依赖:

dependencies {
    implementation 'com.github.bumptech.glide:glide:4.16.0'
    annotationProcessor 'com.github.bumptech.glide:compiler:4.16.0'
}

几个小提示

  • 如果是本地图片资源,获取宽高的逻辑类似,直接用Drawable的intrinsicWidth和intrinsicHeight即可
  • 如果不想用Glide,也可以用Picasso或者系统的BitmapFactory来处理图片加载和尺寸计算
  • 如果需要支持横向瀑布流,把StaggeredGridLayoutManager的方向改成HORIZONTAL就行

内容的提问来源于stack exchange,提问作者Yakov Shaikevich

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:20:49