使用 Entrypoints Dagger hilt 检测活动中的适配器 onclick 侦听器方法

Posted

技术标签:

【中文标题】使用 Entrypoints Dagger hilt 检测活动中的适配器 onclick 侦听器方法【英文标题】:Detect Adapter onclick Listener method in activity using Entrypoints Dagger hilt 【发布时间】:2022-01-13 01:56:10 【问题描述】:

我需要借助匕首来检测活动类中的适配器 onclick 事件。

Step1 :我创建了一个名为 ItemClickListener 的接口类,并使用 Dagger hilt 使用 EntryPoint。

 @InstallIn(SingletonComponent::class)
 @EntryPoint
 interface ItemClickListener 
     fun onItemClick(bundle: Bundle?)
 

Step2:然后我创建了名为CountryNewAdapter的适配器类。我还在其中注入了我的应用程序上下文。

    @Singleton
   class CountryNewsAdapter @Inject constructor(
       @ApplicationContext var context: Context
    ) :
    RecyclerView.Adapter<CountryNewsAdapter.OnCountryNewsViewHolder>(), OnItemUpdateListener 

    private val TAG: String = javaClass.simpleName
    private var hasWritePermission = false
    private var itemList: List<CountryNews> = ArrayList()

    var itemClickEntryPoint = EntryPoints.get(context, ItemClickListener::class.java)
  


    private var diffCallback = object : DiffUtil.ItemCallback<CountryNews>() 
        override fun areItemsTheSame(oldItem: CountryNews, newItem: CountryNews): Boolean 
            return oldItem.title == newItem.title
        

        override fun areContentsTheSame(oldItem: CountryNews, newItem: CountryNews): Boolean 
            return oldItem.hashCode() == newItem.hashCode()
        

    

    private val differ = AsyncListDiffer(this, diffCallback)

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): OnCountryNewsViewHolder 
        val binding =
            CountryNewsRowItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
        return OnCountryNewsViewHolder(binding)
    

    override fun onBindViewHolder(holder: OnCountryNewsViewHolder, position: Int) 

        bindView(holder, position)
    

    private fun bindView(holder: OnCountryNewsViewHolder, position: Int) 
        with(holder) 
            with(differ.currentList[position]) 
                if (imageHref == null || localImageHref.isNullOrEmpty())
                    binding.ivFeature.visibility = View.GONE
                else 
                    val urlToLoad = if (hasWritePermission) if (localImageHref.isNullOrEmpty())
                        imageHref else localImageHref else ""

                    Glide.with(context)
                        .load(urlToLoad)
                        .placeholder(R.drawable.ic_loader)
                        .error(R.drawable.ic_loader)
                        .into(binding.ivFeature)
                    binding.ivFeature.visibility = View.VISIBLE
                

                binding.tvTitle.text = title
                binding.tvDesc.text = description
                binding.ivFeature.setOnClickListener 
                    Log.e(TAG, "bindView: " )
                    itemClickEntryPoint.onItemClick(null)
                
            
        
    

    override fun getItemCount(): Int 
        return differ.currentList.size
    

    fun setItemData(itemList: List<CountryNews>?) 
        if (itemList != null) 
            differ.submitList(itemList)
        
    

    fun hasPermission(status: Boolean) 
        this.hasWritePermission = status
        notifyDataSetChanged()
    

    inner class OnCountryNewsViewHolder(val binding: CountryNewsRowItemBinding) :
        RecyclerView.ViewHolder(binding.root)

    override fun onItemUpdate(bundle: Bundle?) 
        Handler(Looper.getMainLooper()).post 
            notifyDataSetChanged()
        
    
 

Step3:现在在 MainActivity 上,我已经注入了我的适配器类并将这个适配器类设置到我的活动中。结果我在屏幕上得到项目列表,但是当我点击它时。它不会检测到点击事件。我想用入口点检测。我已经尝试在 MainActivity 中实现我的界面,但两者都不适合我。

@androidEntryPoint
class MainActivity : AppCompatActivity(), ItemClickListener 
    private val TAG: String = javaClass.simpleName
    private lateinit var binding: ActivityMainBinding
    private val mainViewModel: MainViewModel by viewModels()

    @Inject
    lateinit var countryNewsAdapter: CountryNewsAdapter


    override fun onCreate(savedInstanceState: Bundle?) 
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        initViewModel()
        initAdapter()
        requestPermissions()
    

    private fun initViewModel() 

        lifecycleScope.launch 
            mainViewModel.newsList.collect 
                when (it.status) 
                    Status.LOADING -> 
                        binding.progressBar.isVisible = true
                        binding.rvCountryNews.isVisible = false
                        binding.tvNoDataFound.isVisible = false
                    
                    Status.SUCCESS -> 
                        binding.progressBar.isVisible = false
                        if (!it.data.isNullOrEmpty()) 
                            countryNewsAdapter.setItemData(it.data)
                            binding.rvCountryNews.isVisible = true
                            binding.tvNoDataFound.isVisible = false
                         else 
                            binding.rvCountryNews.isVisible = false
                            binding.tvNoDataFound.isVisible = true
                        
                    
                    Status.ERROR -> 
                        binding.progressBar.isVisible = false
                        binding.rvCountryNews.isVisible = false
                        binding.tvNoDataFound.isVisible = true
                        Toast.makeText(
                            this@MainActivity,
                            it.message,
                            Toast.LENGTH_SHORT
                        ).show()
                    
                
            
        
    

    private fun initAdapter() 

        /* Bind Json String with Kotlin class.
           * Intialize Adapter and attached with recyclerView.*/
        binding.rvCountryNews.layoutManager = LinearLayoutManager(this)
        countryNewsAdapter.itemClickEntryPoint.apply 
            Log.e(TAG, "initAdapter: " )
        
        binding.rvCountryNews.adapter = countryNewsAdapter
    

    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<String>,
        grantResults: IntArray,
    ) 
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        when (requestCode) 
            MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE -> 
                // If request is cancelled, the result arrays are empty.
                if ((grantResults.isNotEmpty() && grantResults[0] != PackageManager.PERMISSION_GRANTED)) 
                    Toast.makeText(
                        this,
                        getString(R.string.str_please_allow_storage_permission),
                        Toast.LENGTH_SHORT
                    ).show()
                 else 
                    // permission denied, boo! Disable the
                    // functionality that depends on this permission.
                    mainViewModel.getNewsList()
                    countryNewsAdapter.hasPermission(true)
                
                return
            
            // Add other 'when' lines to check for other
            // permissions this app might request.
            else -> 
                // Ignore all other requests.
            
        
    

    @TargetApi(Build.VERSION_CODES.M)
    fun requestPermissions() 
        if (ContextCompat.checkSelfPermission(
                this,
                Manifest.permission.WRITE_EXTERNAL_STORAGE
            ) != PackageManager.PERMISSION_GRANTED
        ) 
            ActivityCompat.requestPermissions(
                this,
                arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE),
                MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE
            )
         else 
            mainViewModel.getNewsList()
            countryNewsAdapter.hasPermission(true)
        
    

    override fun onItemClick(bundle: Bundle?) 
        Log.e(TAG, "onItemClick: " )
        requestPermissions()
    

【问题讨论】:

【参考方案1】:

我想你要求在 onclickListners 中使用 hilt,但我不知道为什么,Kotlin 提供了多个函数来存档它。


in your Adapter


     var itemClickListener: ((position: Int, name: String) -> Unit)? = null
//bindviewholder
     itemClickListner.invoke(1,"anyvalue")

活动中

   adapter.itemClickListener =  
            position, name ->
        Toast.makeText(requireContext(),"position is $position name is $name ",Toast.LENGTH_SHORT).show()
    
 

在这个方法中你只注入适配器。

【讨论】:

以上是关于使用 Entrypoints Dagger hilt 检测活动中的适配器 onclick 侦听器方法的主要内容,如果未能解决你的问题,请参考以下文章

错误:Chunk.entrypoints:使用 Chunks.groupsIterable 并按 instanceof Entrypoint 过滤

[webpack] Error: Chunk.entrypoints: Use Chunks.groupsIterable and filter by instanceof Entrypoint in

基于Excel的HIL自动化测试工具VIAutoHIL

Error: Chunk.entrypoints: Use Chunks.groupsIterable and filter by instanceof Entrypoint instead(示例代码

Chunk.entrypoints: Use Chunks.groupsIterable and filter by instanceof Entrypoint instead

nodeJS - 切换使用淘宝镜像临时切换 长期切换