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

使用@AssistedInjection为RecyclerViewAdapter传参报错问题

Dagger Assisted Injection 参数匹配错误解决及MVVM下RecyclerView点击解耦实现

错误原因

你遇到的错误是因为适配器构造器中@Assisted标注了自定义名称,但辅助工厂里的@Assisted没有对应匹配这些名称。虽然错误信息里显示的Actual和Expected参数列表看起来完全一致,但Dagger对带命名的@Assisted参数会严格匹配名称,不匹配就会触发这个看似矛盾的错误。

解决方案

有两种方式可以修复这个问题:

方式一:移除适配器@Assisted的自定义名称

修改ChampionshipAdapter的构造器,去掉@Assisted的命名参数,让参数仅通过类型匹配:

open class ChampionshipAdapter
        @AssistedInject constructor(@Assisted championshipData: OrderedRealmCollection<Championship>,
                                    @Assisted donwloadDataClickListener: View.OnClickListener,
                            ):
                                    RealmRecyclerViewAdapter<Championship, ChampionshipViewHolder>
                                                                    (championshipData, true) {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ChampionshipViewHolder {
        val binding = RowItemChampionshipBinding.inflate(LayoutInflater.from(parent.context), parent, false)
        return ChampionshipViewHolder(binding)
    }

    override fun onBindViewHolder(holder: ChampionshipViewHolder, position: Int) {
        holder.bind(championshipData[position])
    }
}

方式二:给辅助工厂的@Assisted添加对应命名

修改ChampionshipAdapterAssistedFactory,让每个@Assisted参数的名称和适配器构造器里的完全一致:

@AssistedFactory
interface ChampionshipAdapterAssistedFactory {

    fun start(@Assisted("championshipData") championshipData: OrderedRealmCollection<Championship>,
               @Assisted("donwloadDataClickListener") donwloadDataClickListener: View.OnClickListener) : ChampionshipAdapter
}

MVVM模式下点击事件解耦优化

你原本的需求是让RecyclerView项点击触发ViewModel里的Realm持久化逻辑,建议用Lambda回调替代View.OnClickListener,更贴合Kotlin风格,同时彻底和ViewHolder解耦:

1. 修改适配器和ViewHolder

open class ChampionshipAdapter
        @AssistedInject constructor(@Assisted championshipData: OrderedRealmCollection<Championship>,
                                    @Assisted private val onItemClick: (Championship) -> Unit,
                            ):
                                    RealmRecyclerViewAdapter<Championship, ChampionshipViewHolder>
                                                                    (championshipData, true) {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ChampionshipViewHolder {
        val binding = RowItemChampionshipBinding.inflate(LayoutInflater.from(parent.context), parent, false)
        return ChampionshipViewHolder(binding, onItemClick)
    }

    override fun onBindViewHolder(holder: ChampionshipViewHolder, position: Int) {
        championshipData[position]?.let { holder.bind(it) }
    }
}

// ViewHolder类
class ChampionshipViewHolder(
    private val binding: RowItemChampionshipBinding,
    private val onItemClick: (Championship) -> Unit
) : RecyclerView.ViewHolder(binding.root) {
    fun bind(championship: Championship) {
        // 绑定数据到UI组件,示例:
        binding.tvChampionshipName.text = championship.name
        
        // 设置项点击事件,直接触发回调
        binding.root.setOnClickListener { onItemClick(championship) }
    }
}

2. 更新辅助工厂

@AssistedFactory
interface ChampionshipAdapterAssistedFactory {
    fun start(
        @Assisted championshipData: OrderedRealmCollection<Championship>,
        @Assisted onItemClick: (Championship) -> Unit
    ): ChampionshipAdapter
}

3. 在Activity中传入ViewModel逻辑

// 在MainActivity的onCreate里
val onItemClick = { championship: Championship ->
    // 调用ViewModel中的持久化方法,将逻辑完全放在ViewModel中
    championshipViewModel.saveNewChampionshipRecord(championship)
}

championshipAdapter = championshipAdapterAssistedFactory.start(championshipData, onItemClick)

4. ViewModel中实现Realm持久化逻辑

class ChampionshipViewModel @Inject constructor(
    private val realm: Realm
) : ViewModel() {

    fun saveNewChampionshipRecord(championship: Championship) {
        viewModelScope.launch {
            realm.executeTransactionAsync { realm ->
                // 这里实现你的持久化逻辑,示例:
                val newRecord = Championship().apply {
                    name = "${championship.name}_副本"
                    // 其他字段赋值
                }
                realm.insert(newRecord)
            }
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 21:50:38