如何将适配器与刀柄一起注射



我有一个完整的recyclerView示例,现在我想使用hilt将这个示例的ItemListAdapter注入到我的ItemListFragment中。但如果我还想要剑柄的方式,这似乎是做不到的。

class ItemListFragment : Fragment() {
private val viewModel: ItemListViewModel by viewModels()
private var adapter: ItemListAdapter? = null
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val binding = FragmentItemListBinding.inflate(inflater)
binding.lifecycleOwner = this
binding.viewModel = viewModel
adapter =
ItemListAdapter(
ItemListOnClickListener { itemId ->
viewModel.onItemClicked(itemId)
})
binding.itemList.adapter = adapter
return binding.root
}
}
class ItemListAdapter(private val onClickListener: ItemListOnClickListener):
ListAdapter<Item, ItemListAdapter.ViewHolder>(
ItemListDiffCallback()
) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return ViewHolder(
ListItemBinding.inflate(LayoutInflater.from(parent.context))
)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val item = getItem(position)
holder.bind(item)
}
class ViewHolder constructor(private val binding: ListItemBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(item: Item) {
binding.item = item
binding.executePendingBindings()
}
}
}
class ItemListDiffCallback : DiffUtil.ItemCallback<Item>() {
override fun areItemsTheSame(oldItem: Item, newItem: Item): Boolean {
return oldItem == newItem
}
override fun areContentsTheSame(oldItem: Item, newItem: Item): Boolean {
return oldItem.id == newItem.id
}
}
class ItemListOnClickListener(val clickListener: (itemID: String) -> Unit) {
fun onClick(itemID: String) = clickListener(itemID)
}

这就是您想要的吗?你能检查一下这是否有效并满足你的需求吗。

注意:我希望您设置注释很好,所以hilt在您的项目中正确设置并工作(例如:用@AndroidEntryPoint注释ItemListFragment片段等(

我有这样的情况,我认为与其在构造函数中提供回调,不如通过适配器的setter方法提供回调。

对于ItemListAdapter,我们可以制作ItemListOnClickListener类型的属性,并提供setOnClickListenersetter方法。就是这样,现在您可以在ViewHolder中使用onClickListener(现在ItemListAdapter构造函数是无参数构造函数,Hilt可以为您的情况提供绑定(:

@Singleton
class ItemListAdapter @Inject constructor():
ListAdapter<Item, ItemListAdapter.ViewHolder>(ItemListDiffCallback()) {

private var onClickListener: ItemListOnClickListener? = null
...
fun setOnClickListener(onClickListener: ItemListOnClickListener) {
this.onClickListener = onClickListener;
}
inner class ViewHolder constructor(private val binding: ListItemBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(item: Item) {
binding.item = item
binding.executePendingBindings()
// Use `onClickListener` when binding `OnClickListener` callback
binding.view.setOnClickListener(v -> onClickListener?.onClick(...))
}
}
}

对于ItemListFragment,您不需要构造适配器,因为Hilt将能够为您提供一个适配器。您所要做的就是通过这个适配器的setOnClickListener方法提供一个监听器:

@AndroidEntryPoint
class ItemListFragment: Fragment() {
@Inject
var adapter: ItemListAdapter? = null
private val viewModel: ItemListViewModel by viewModels()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val binding = FragmentItemListBinding.inflate(inflater)
...
adapter?.setOnClickListener(
ItemListOnClickListener { 
itemId -> viewModel.onItemClicked(itemId) 
}
)
binding.itemList.adapter = adapter
return binding.root
}
}

回答2021年2月

这是最简单的答案。

模块级

@Module
@InstallIn(SingletonComponent::class)
class AppModule {
@Provides
@Singleton
fun provideAdapter(): MyAdapter = MyAdapter()
}

适配器类

private var onItemClickListener: ((RestaurantX) -> Unit)? = null
fun setOnItemClickListener(listener: (RestaurantX) -> Unit) {
onItemClickListener = listener
}

然后将这条线放入view.setOnClckListener

onItemClickListener?.let {
it(restaurantX)
}

活动中/片段

@Inject
lateinit var myAdapter: MyAdapter

然后在方法内部

myAdapter.setOnItemClickListener {it->
//do whatever you like
}

如果你仍然有困惑这里是完整的源代码

相关内容

最新更新