使用@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
相关产品推荐
相关产品推荐

