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

Android电商APP:从另一Fragment的Adapter刷新RecyclerView Fragment

解决从Wishlist Adapter刷新Shop Fragment RecyclerView的问题

嘿,这个场景我做电商类App的时候也碰到过,结合你的架构(两个Fragment、索引式心愿单存储),给你梳理几个靠谱的解决方案:

方案1:共享ViewModel(Jetpack推荐规范方案)

这是最贴合Android现代架构的方式,同属一个Activity的Fragment可以共享同一个ViewModel实例,数据和状态传递会非常清晰,还能避免内存泄漏问题。

实现步骤:

  1. 创建共享ViewModel
    里面维护全商品列表、心愿单索引列表,还有用于通知刷新的LiveData(支持单item精准刷新):

    class ShopSharedViewModel : ViewModel() {
        // 全商品列表
        val allProducts = MutableLiveData<List<Product>>()
        // 心愿单索引列表
        val wishlistIndexes = MutableLiveData<MutableList<Int>>()
        // 通知Shop Fragment刷新指定item的信号
        val refreshShopItem = MutableLiveData<Int?>()
    
        // 移除心愿单商品的方法
        fun removeFromWishlist(targetIndex: Int) {
            val currentWishlist = wishlistIndexes.value ?: mutableListOf()
            currentWishlist.remove(targetIndex)
            wishlistIndexes.postValue(currentWishlist)
            // 发送刷新信号
            refreshShopItem.postValue(targetIndex)
        }
    }
    
  2. Shop Fragment中观察ViewModel
    通过activityViewModels()获取共享ViewModel实例,监听刷新信号并更新RecyclerView:

    class ShopFragment : Fragment() {
        private lateinit var viewModel: ShopSharedViewModel
        private lateinit var productAdapter: ProductAdapter
    
        override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
            // 获取共享ViewModel
            viewModel = ViewModelProvider(requireActivity())[ShopSharedViewModel::class.java]
            // 初始化Adapter和RecyclerView...
    
            // 监听刷新信号,精准刷新对应item
            viewModel.refreshShopItem.observe(viewLifecycleOwner) { index ->
                index?.let {
                    productAdapter.notifyItemChanged(it)
                    // 重置信号,避免重复触发
                    viewModel.refreshShopItem.postValue(null)
                }
            }
            return inflater.inflate(R.layout.fragment_shop, container, false)
        }
    }
    
  3. Wishlist Adapter中调用ViewModel方法
    当用户操作心愿单(比如移除商品)时,直接调用ViewModel的方法更新数据并触发刷新:

    class WishlistAdapter(private val viewModel: ShopSharedViewModel, private val wishlistIndexes: List<Int>) : RecyclerView.Adapter<WishlistAdapter.ViewHolder>() {
        // ... 其他Adapter基础代码
    
        inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
            fun bind(productIndex: Int) {
                // 从全商品列表中通过索引获取商品数据
                val targetProduct = viewModel.allProducts.value?.get(productIndex) ?: return
                // 绑定商品名称、图片等数据...
    
                // 移除按钮点击事件
                itemView.btn_remove_from_wishlist.setOnClickListener {
                    viewModel.removeFromWishlist(productIndex)
                }
            }
        }
    }
    

方案2:接口回调(传统但直观的方式)

如果暂时不想引入ViewModel,也可以用接口回调实现跨Fragment的通信,逻辑简单易懂。

实现步骤:

  1. 定义刷新回调接口

    interface OnWishlistChangeListener {
        fun onWishlistItemUpdated(productIndex: Int)
    }
    
  2. Shop Fragment实现接口

    class ShopFragment : Fragment(), OnWishlistChangeListener {
        private lateinit var productAdapter: ProductAdapter
    
        override fun onWishlistItemUpdated(productIndex: Int) {
            // 精准刷新对应商品item
            productAdapter.notifyItemChanged(productIndex)
        }
    
        override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
            super.onViewCreated(view, savedInstanceState)
            // 把当前实例传递给Wishlist Fragment
            val wishlistFragment = parentFragmentManager.findFragmentById(R.id.fragment_wishlist) as? WishlistFragment
            wishlistFragment?.setWishlistChangeListener(this)
        }
    }
    
  3. Wishlist Fragment持有接口实例

    class WishlistFragment : Fragment() {
        private var listener: OnWishlistChangeListener? = null
    
        fun setWishlistChangeListener(listener: OnWishlistChangeListener) {
            this.listener = listener
        }
    
        private fun initAdapter() {
            val adapter = WishlistAdapter(wishlistIndexes) { targetIndex ->
                // 触发回调通知Shop Fragment
                listener?.onWishlistItemUpdated(targetIndex)
                // 同步更新本地心愿单索引列表
                updateWishlistLocalData(targetIndex)
            }
            recyclerView.adapter = adapter
        }
    
        private fun updateWishlistLocalData(removeIndex: Int) {
            // 处理心愿单索引列表的本地更新逻辑...
        }
    }
    
  4. Wishlist Adapter中触发回调

    class WishlistAdapter(
        private val wishlistIndexes: List<Int>,
        private val onItemRemoved: (Int) -> Unit
    ) : RecyclerView.Adapter<WishlistAdapter.ViewHolder>() {
        // ... 其他Adapter代码
    
        inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
            fun bind(productIndex: Int) {
                itemView.btn_remove.setOnClickListener {
                    onItemRemoved(productIndex)
                }
            }
        }
    }
    

方案3:EventBus(简化跨组件通信)

如果你的项目已经在用EventBus,这是个快速实现的方案,通过事件发送来完成刷新通知:

  1. 定义刷新事件类

    data class WishlistRefreshEvent(val productIndex: Int)
    
  2. Shop Fragment注册并接收事件

    class ShopFragment : Fragment() {
        private lateinit var productAdapter: ProductAdapter
    
        override fun onStart() {
            super.onStart()
            EventBus.getDefault().register(this)
        }
    
        override fun onStop() {
            super.onStop()
            EventBus.getDefault().unregister(this)
        }
    
        @Subscribe(threadMode = ThreadMode.MAIN)
        fun handleWishlistRefresh(event: WishlistRefreshEvent) {
            productAdapter.notifyItemChanged(event.productIndex)
        }
    }
    
  3. Wishlist Adapter中发送事件

    itemView.btn_remove.setOnClickListener {
        EventBus.getDefault().post(WishlistRefreshEvent(productIndex))
        // 同步更新心愿单索引列表
    }
    

小提示:

因为你的心愿单存的是全商品的索引,刷新时优先用notifyItemChanged(index)而不是notifyDataSetChanged(),这样能避免RecyclerView全量重绘,提升性能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:06:47