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

Android低版本下Fragment重新打开后ViewPager2图片不加载如何解决

问题根因分析

这个问题仅出现在Android 6及更低版本,核心是两个兼容问题叠加导致的:

  • 低版本Android对未attach到Window的View的post()任务执行逻辑有差异:Android 7.0+会在下一个渲染帧直接执行未attach View的post任务,而Android 6及更低版本会将任务挂起,直到View正式attach到Window才会执行。你在onBindViewHolder中用thumbnail.post()包裹Glide加载逻辑,Fragment重建时ViewPager2的ItemView还没完成attach,加载任务就被挂起,只有滑动时ItemView重新触发attach,任务才会执行、图片才会加载。
  • ViewPager2默认的离屏加载逻辑在低版本Fragment重建场景下存在兼容缺陷,首次布局不会主动触发所有可见Item的绑定流程,只有滑动触发页面切换才会重新走绑定逻辑。
解决方案
  • 1. 移除onBindViewHolder中多余的post()包裹

onBindViewHolder执行时ItemView已经绑定到RecyclerView父布局,不需要额外用post延迟加载逻辑,这是导致低版本加载卡住的核心诱因。

  • 2. 调整Glide生命周期绑定

将Glide的生命周期和Fragment的viewLifecycleOwner绑定,避免Fragment销毁重建时Glide请求被意外取消、不会自动重启。

  • 3. 显式设置ViewPager2的离屏加载数量

避免默认懒加载逻辑在低版本不触发首次加载,根据你的页面数量设置合理的offscreenPageLimit即可。

  • 4. Fragment销毁时清理ViewPager2的Adapter

避免旧的Adapter实例残留导致重建时加载异常。

修改后的代码示例

Fragment 逻辑调整

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    val media = utilities.getMedia(this)
    val mediaList = media.toMutableList()
    
    // 传入viewLifecycleOwner给Adapter
    val adapter = ViewPagerAdapter(mediaList, viewLifecycleOwner)
    photo_view_pager.adapter = adapter
    // 根据你的图片数量设置离屏加载数,最少设置为1
    photo_view_pager.offscreenPageLimit = minOf(mediaList.size - 1, 2)
    // 低版本兼容:手动触发一次Item刷新
    photo_view_pager.post {
        adapter.notifyItemRangeChanged(0, adapter.itemCount)
    }
}

override fun onDestroyView() {
    // 销毁View时清空Adapter,避免旧实例残留
    photo_view_pager.adapter = null
    super.onDestroyView()
}

ViewPagerAdapter 逻辑调整

class ViewPagerAdapter (
    private val images: List<Media>,
    // 新增LifecycleOwner参数用于Glide生命周期绑定
    private val lifecycleOwner: LifecycleOwner
) : RecyclerView.Adapter<ViewPagerAdapter.ViewPagerViewHolder>() {
    inner class ViewPagerViewHolder(itemView: View): RecyclerView.ViewHolder(itemView)

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

    override fun getItemCount(): Int = images.size

    override fun onBindViewHolder(holder: ViewPagerViewHolder, position: Int) {
        val curImageUri = images[position].uri
        val thumbnail = holder.itemView.image_preview
        // 移除post包裹,直接用lifecycleOwner绑定Glide加载
        Glide.with(lifecycleOwner)
            .load(curImageUri)
            // 可选:设置占位图避免加载过程中空白
            .placeholder(R.drawable.default_placeholder)
            .diskCacheStrategy(DiskCacheStrategy.RESOURCE)
            .into(thumbnail)
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.12 10:45:01