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

设备旋转后RecyclerView内容消失问题求助

问题分析与解决

问题根源

竖屏正常、旋转后卡片消失的核心原因是:在SportAdapter的onCreateViewHolder方法中,通过parent.measuredWidth / 3设置卡片宽度时,设备旋转后RecyclerView的父容器尚未完成测量流程,此时parent.measuredWidth的值为0,导致卡片宽度被设为0,因此虽然视图已创建,但无法显示。

解决方案

以下提供三种可靠的解决方式,按推荐优先级排序:

方案1:使用GridLayoutManager替代手动设置宽度

直接利用GridLayoutManager的横向布局+3列配置,自动分配每个卡片的宽度,无需手动计算,旋转后会自动适配新的屏幕宽度。

修改Activity中初始化LayoutManager的代码:

// 替换原LinearLayoutManager为GridLayoutManager
val gridLayoutManager = GridLayoutManager(this, 3, LinearLayoutManager.HORIZONTAL, false)
sportRV.layoutManager = gridLayoutManager

同时删除SportAdapter中onCreateViewHolder里设置宽度的代码:

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
    val view = LayoutInflater.from(parent.context).inflate(R.layout.card_view, parent, false)
    // 删除原设置lp.width的代码
    return ViewHolder(view)
}

方案2:在Activity中计算宽度并传递给Adapter

在Activity中获取屏幕的有效宽度,将计算好的单张卡片宽度传递给Adapter,避免在Adapter中依赖未完成测量的父容器。

修改Activity代码:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_show_profile)
    sportRV = findViewById(R.id.idRVSport)

    // ...其他代码...

    val sportModelArrayList: ArrayList<SportModel> = ArrayList()
    sports.map { sportModelArrayList.add(SportModel(it)) }
    
    // 计算单张卡片的宽度:屏幕宽度的1/3
    val screenWidth = resources.displayMetrics.widthPixels
    val itemWidth = screenWidth / 3
    
    val linearLayoutManager = LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false)
    sportRV.layoutManager = linearLayoutManager
    // 将itemWidth传入Adapter
    val sportAdapter = SportAdapter(this, sportModelArrayList, itemWidth)
    sportRV.adapter = sportAdapter
}

修改SportAdapter的构造方法和onCreateViewHolder:

class SportAdapter(
    private val context: Context, 
    sportModelArrayList: ArrayList<SportModel>,
    private val itemWidth: Int // 添加itemWidth参数
) : RecyclerView.Adapter<SportAdapter.ViewHolder>() {
    private var sportModelArrayList: ArrayList<SportModel>

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.card_view, parent, false)
        val lp = view.layoutParams
        lp.width = itemWidth
        view.layoutParams = lp // 确保参数生效
        return ViewHolder(view)
    }

    // ...其他方法不变...
}

方案3:监听视图布局完成事件再设置宽度

在Adapter中通过ViewTreeObserver监听视图的布局完成事件,确保父容器测量完成后再设置卡片宽度。

修改SportAdapter的onCreateViewHolder:

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
    val view = LayoutInflater.from(parent.context).inflate(R.layout.card_view, parent, false)
    view.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
        override fun onGlobalLayout() {
            // 移除监听,避免重复触发
            view.viewTreeObserver.removeOnGlobalLayoutListener(this)
            val lp = view.layoutParams
            lp.width = parent.measuredWidth / 3
            view.layoutParams = lp
        }
    })
    return ViewHolder(view)
}

额外布局优化建议

检查RecyclerView的布局参数,将layout_height从match_parent改为wrap_content,避免父容器(LinearLayout为wrap_content)出现高度计算异常:

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/idRVSport"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</LinearLayout>

内容的提问来源于stack exchange,提问作者Juan José Jaramillo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 13:35:20