【问题标题】:Detect Adapter onclick Listener method in activity using Entrypoints Dagger hilt使用 Entrypoints Dagger hilt 检测活动中的适配器 onclick 侦听器方法
【发布时间】: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()
    }
}

【问题讨论】:

    标签: android kotlin mvvm android-jetpack dagger-hilt


    【解决方案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()
        }
     
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-20
      • 2020-06-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-18
      相关资源
      最近更新 更多