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

Android Kotlin:从BasketDialogFragment向BasketFragment的RecyclerView添加条目

解决方案:通过共享ViewModel实现跨Fragment购物篮数据同步

1. 创建共享购物篮ViewModel

用ViewModel统一持有购物篮数据,提供添加商品方法和可观察的LiveData,让BasketFragment能实时感知数据变化。

import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel

class BasketViewModel : ViewModel() {
    private val _basketItems = MutableLiveData<MutableList<ProductItem>>(mutableListOf())
    val basketItems: LiveData<MutableList<ProductItem>> = _basketItems

    fun addItemToBasket(item: ProductItem) {
        val currentList = _basketItems.value ?: mutableListOf()
        // 可在此处添加重复商品的数量累加逻辑
        currentList.add(item)
        _basketItems.postValue(currentList)
    }
}

2. 在宿主Activity中初始化ViewModel

因为两个Fragment都依附于GlassContainerActivity,通过Activity的ViewModelProvider获取实例,确保数据全局共享。

class GlassContainerActivity : AppCompatActivity() {
    private lateinit var basketViewModel: BasketViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_glass_container)
        
        basketViewModel = ViewModelProvider(this)[BasketViewModel::class.java]
    }
}

3. 改造BasketDialogFragment实现添加逻辑

在Dialog中获取共享ViewModel,点击按钮时调用添加方法,传入当前展示的商品条目。

class BasketDialogFragment : DialogFragment() {
    private val currentItem: ProductItem by lazy {
        arguments?.getParcelable("PRODUCT_ITEM") ?: ProductItem()
    }
    private lateinit var basketViewModel: BasketViewModel

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        val view = inflater.inflate(R.layout.fragment_basket_dialog, container, false)
        
        basketViewModel = ViewModelProvider(requireActivity())[BasketViewModel::class.java]
        
        view.addToBasket.setOnClickListener {
            basketViewModel.addItemToBasket(currentItem)
            dismiss()
        }
        return view
    }
}

4. 改造BasketFragment监听数据更新

观察ViewModel的LiveData,数据变化时自动刷新RecyclerView。

class BasketFragment : Fragment() {
    private lateinit var basketViewModel: BasketViewModel
    private lateinit var basketAdapter: BasketAdapter

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        val view = inflater.inflate(R.layout.fragment_basket, container, false)
        
        basketAdapter = BasketAdapter(mutableListOf())
        view.recyclerView.apply {
            adapter = basketAdapter
            layoutManager = LinearLayoutManager(context)
        }
        
        basketViewModel = ViewModelProvider(requireActivity())[BasketViewModel::class.java]
        basketViewModel.basketItems.observe(viewLifecycleOwner) { items ->
            basketAdapter.updateData(items)
        }
        return view
    }
}

5. 给BasketAdapter添加数据更新方法

让Adapter能接收新数据源并刷新列表:

class BasketAdapter(private var items: MutableList<ProductItem>) : RecyclerView.Adapter<BasketAdapter.ViewHolder>() {
    // 省略ViewHolder、onCreateViewHolder、onBindViewHolder等基础代码
    
    fun updateData(newItems: MutableList<ProductItem>) {
        items.clear()
        items.addAll(newItems)
        notifyDataSetChanged()
        // 追求性能可替换为DiffUtil实现局部刷新
    }
}

6. 打开Dialog时传递商品数据

在GlassContainerActivity的条目点击事件中,把选中商品通过arguments传入Dialog:

// 条目点击逻辑示例
itemView.setOnClickListener {
    val selectedItem = adapter.currentList[position]
    val dialog = BasketDialogFragment()
    val args = Bundle().apply {
        putParcelable("PRODUCT_ITEM", selectedItem)
    }
    dialog.arguments = args
    dialog.show(supportFragmentManager, "BasketDialog")
}

补充说明

  • 采用ViewModel+LiveData的方案,无需手动管理Fragment间的接口回调,自动适配生命周期,避免内存泄漏。
  • 若需要处理重复商品的数量累加,可在ViewModel的addItemToBasket方法中添加逻辑:遍历现有列表,匹配商品ID后更新数量,再提交数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 20:25:22