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

切换Fragment或返回应用后GradientDrawable背景异常缩放问题求助

切换Fragment或返回应用后GradientDrawable背景异常缩放问题求助

我看你遇到了个挺闹心的UI问题——切换Fragment或者把应用切后台再回来时,RecyclerView条目里的GradientDrawable背景就乱掉了对吧?先帮你梳理下可能的原因,再给你几个具体的排查和解决方向:

首先,你的Adapter里有个明显的性能+状态隐患

看你在onBindViewHolder里每次绑定条目时,都给子RecyclerView(timetableList)重新创建LayoutManager、ItemAnimator甚至全新的TimetableAdapter:

binding.timetableList.layoutManager = LinearLayoutManager(context)
binding.timetableList.itemAnimator = DefaultItemAnimator()
binding.timetableList.adapter = TimetableAdapter(context).apply { showTimetableList(value) }

这种写法会导致RecyclerView的子View被频繁销毁重建,不仅性能拉胯,还会触发Drawable的重复测量与状态重置——这大概率是你背景异常的核心诱因之一。

优化方案:把这些初始化操作移到ViewHolder创建时只做一次,绑定的时候只更新数据:

  1. 给StationViewHolder加个初始化块,提前配置好子RecyclerView:
inner class StationViewHolder(val binding: ElementTimetableBinding) : RecyclerView.ViewHolder(binding.root) {
    private val timetableAdapter = TimetableAdapter(context)

    init {
        // 只初始化一次,复用整个生命周期
        binding.timetableList.layoutManager = LinearLayoutManager(context)
        binding.timetableList.itemAnimator = DefaultItemAnimator()
        binding.timetableList.adapter = timetableAdapter
    }

    // 暴露更新数据的方法
    fun updateTimetable(data: List<TubeTime>) {
        timetableAdapter.showTimetableList(data)
    }
}
  1. 然后在onBindViewHolder里只调用更新方法:
is Status.Normal -> {
    with(holder) {
        val entry = timetable[position]
        binding.directionText.text = if (entry.key.id.length == 1) "Platform ${entry.key.id}" else entry.key.id
        // 只更新数据,不重建Adapter
        updateTimetable(entry.value)
    }
}

其次,GradientDrawable的状态共享问题

你的背景用的是@drawable/transport_card(GradientDrawable),默认情况下,所有引用这个资源的View会共享同一个Drawable实例的状态。当View被Recycler回收复用、或者Fragment重建时,Drawable的边界/缩放状态可能被错误复用,导致显示异常。

解决办法:给每个View的Drawable设置独立状态,在ViewHolder初始化时手动创建Drawable并调用mutate():

inner class StationViewHolder(val binding: ElementTimetableBinding) : RecyclerView.ViewHolder(binding.root) {
    private val timetableAdapter = TimetableAdapter(context)

    init {
        // 给根布局设置独立的背景Drawable
        val background = ContextCompat.getDrawable(itemView.context, R.drawable.transport_card)?.mutate()
        itemView.background = background
        // 同时给子RecyclerView也设置独立的Drawable
        val listBackground = ContextCompat.getDrawable(itemView.context, R.drawable.transport_card)?.mutate()
        binding.timetableList.background = listBackground

        // 其他RecyclerView初始化代码...
    }
    // ...
}

mutate()方法会让Drawable脱离资源池的共享状态,每个View都拥有自己的Drawable实例,不会互相干扰。

最后,额外排查点

  1. 检查TimetableAdapter里有没有修改背景Drawable的代码,如果有,确保每次更新数据时都正确重置了Drawable的边界;
  2. 确认你的Fragment在切换/后台返回时,有没有触发不必要的重建,避免RecyclerView被频繁销毁重建;
  3. 可以尝试在StationAdapter的showTimetable方法里,先清空旧的timetable列表再添加新数据,确保数据更新的原子性。

先试试上面的前两个优化,应该能解决大部分问题~

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.08 08:08:02