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

如何用ViewModel维护可展开CardView的可见状态(适配配置变更)

让CardView在配置变更时保持展开状态的ViewModel整合方案

你需要将CardView的展开状态交由ViewModel托管,借助LiveData持久化状态,确保配置变更(如横竖屏切换)后UI能自动恢复原有状态。以下是具体整合步骤:

原实现问题分析

当前点击逻辑直接操作View的可见性,状态仅存于内存中,配置变更时View重建会导致状态丢失。你尝试的ViewModel已定义LiveData,但未正确关联UI操作与状态观察逻辑。

原点击逻辑代码

binding.expandMoreButton.setOnClickListener {
    if (binding.collapsableItemSection.visibility == View.VISIBLE) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            TransitionManager.beginDelayedTransition(binding.cardView, AutoTransition())
        }
        binding.collapsableItemSection.visibility = View.GONE
        binding.expandMoreButton.setImageResource(R.drawable.ic_expand_more)
        println(binding.collapsableItemSection.visibility == View.GONE)
    } else {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            TransitionManager.beginDelayedTransition(binding.cardView, AutoTransition())
        }
        binding.collapsableItemSection.visibility = View.VISIBLE
        binding.expandMoreButton.setImageResource(R.drawable.ic_expand_less)
    }
}

原ViewModel尝试代码

private val _isExpanded = MutableLiveData(false)
val isExpanded : LiveData<Boolean>
    get() = _isExpanded

fun toggleCard(value: Boolean) {
    _isExpanded.value = value
    Log.d("HomeFragment", "Is Card Expanded : ${_isExpanded.value}")
}

整合解决方案

1. 优化ViewModel逻辑

修改ViewModel,添加状态切换方法,让ViewModel自行处理状态取反,无需外部传值:

class YourViewModel : ViewModel() {
    private val _isExpanded = MutableLiveData(false)
    val isExpanded: LiveData<Boolean> = _isExpanded

    // 切换展开/收起状态
    fun toggleExpansion() {
        _isExpanded.value = _isExpanded.value?.not() ?: false
        Log.d("HomeFragment", "Is Card Expanded : ${_isExpanded.value}")
    }
}

2. 调整UI层点击逻辑

点击按钮时,不再直接操作View,而是调用ViewModel的状态切换方法:

binding.expandMoreButton.setOnClickListener {
    viewModel.toggleExpansion()
}

3. 观察LiveData,自动同步UI状态

在Fragment的onViewCreated或Activity的onCreate中,观察ViewModel的isExpanded LiveData,根据状态更新UI。这一步是配置变更后恢复状态的核心:

viewModel.isExpanded.observe(viewLifecycleOwner) { isExpanded ->
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        TransitionManager.beginDelayedTransition(binding.cardView, AutoTransition())
    }
    // 根据状态设置View可见性
    binding.collapsableItemSection.visibility = if (isExpanded) View.VISIBLE else View.GONE
    // 根据状态设置按钮图标
    binding.expandMoreButton.setImageResource(
        if (isExpanded) R.drawable.ic_expand_less else R.drawable.ic_expand_more
    )
}

原理说明

  • ViewModel在配置变更时不会被销毁,其持有的LiveData会持续保留状态。
  • 配置变更后,新的View实例会重新观察LiveData,自动触发UI更新,恢复之前的展开/收起状态。

内容的提问来源于stack exchange,提问作者Unish Raj.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 18:23:22