RecyclerView 适配器 onItemClick 事件未触发

朴灿佑

我是一名 Java Android 开发人员,正在尝试重新学习 Kotlin 中的 RecyclerView 适配器。

我有一个包含 RecyclerView 的 Fragment。我在 Fragment 类中初始化了适配器和 OnItemClickListener。但是我的 onItemClick() 从未被触发。Log.d 从不显示。

突发新闻片段.kt

class BreakingNewsFragment : Fragment(R.layout.fragment_breaking_news) {

lateinit var viewModel: NewsViewModel
lateinit var newsAdapter: NewsAdapter

val TAG = "BreakingNewsFragment"

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    viewModel = (activity as NewsActivity).viewModel
    setupRecyclerView()
    Log.d(TAG, "onitemclick") // this shows!

    newsAdapter.setOnItemClickListener {
        Log.d(TAG, "onitemclick") // this won't show
        val bundle = Bundle().apply {
            putSerializable("article", it)
        }
        findNavController().navigate(
            R.id.action_breakingNewsFragment_to_articleFragment,
            bundle
        )
    }

    viewModel.breakingNews.observe(viewLifecycleOwner, Observer { response ->
        when(response) {
            is Resource.Success -> {
                hideProgressBar()
                response.data?.let { newsResponse ->
                    newsAdapter.differ.submitList(newsResponse.articles)
                }
            }
            is Resource.Error -> {
                hideProgressBar()
                response.message?.let {message ->
                    Log.e(TAG, "An error occurred: $message")
                }
            }
            is Resource.Loading -> {
                showProgressBar()
            }
        }
    })
}

private fun hideProgressBar() {
    paginationProgressBar.visibility = View.INVISIBLE
}

private fun showProgressBar() {
    paginationProgressBar.visibility = View.VISIBLE
}

private fun setupRecyclerView() {
    newsAdapter = NewsAdapter()
    rvBreakingNews.apply {
        adapter = newsAdapter
        layoutManager = LinearLayoutManager(activity)
    }
}
}

新闻适配器.kt

class NewsAdapter : RecyclerView.Adapter<NewsAdapter.ArticleViewHolder>() {

inner class ArticleViewHolder(itemView: View): RecyclerView.ViewHolder(itemView)

private val differCallback = object : DiffUtil.ItemCallback<Article>() {
    override fun areItemsTheSame(oldItem: Article, newItem: Article): Boolean {
        // can't compare article IDs; articles from API do not have IDs. but URLs are unique for each article so we can compare those
        return oldItem.url == newItem.url
    }

    override fun areContentsTheSame(oldItem: Article, newItem: Article): Boolean {
        return oldItem == newItem
    }
}

// instead of using a standard list to store objects, use this ListDiffer to calculate differences between lists
val differ = AsyncListDiffer(this, differCallback)

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ArticleViewHolder {
    return ArticleViewHolder(
        LayoutInflater.from(parent.context).inflate(R.layout.item_article_preview, parent,false)
    )
}

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

override fun onBindViewHolder(holder: ArticleViewHolder, position: Int) {
    val article = differ.currentList[position]
    holder.itemView.apply { // apply: reference views directly
        Glide.with(this).load(article.urlToImage).into(ivArticleImage)
        tvSource.text = article.source.name
        tvTitle.text = article.title
        tvDescription.text = article.description
        tvPublishedAt.text = article.publishedAt
        setOnItemClickListener { onItemClickListener?.let( { it(article) }) }
    }
}

private var onItemClickListener: ((Article) -> Unit)? = null // pass current article to function, open webview page from there

fun setOnItemClickListener(listener: (Article) -> Unit) {
    onItemClickListener = listener
}
}
比利

在您的 中holder.itemView.apply {,您没有将回调分配给您的 holder.itemView; 您正在调用setOnItemClickListener它所做的只是更改您的onItemClickListener,它实际上是一个局部变量,而不是视图中的回调函数。

你想要做的是:


holder.itemView.apply { // apply: reference views directly
        ..
        setOnClickListener { onItemClickListener?.let( { it(article) }) }
    }

(注意,这是setOnClickListener,不是setOn*Item*ClickListener

我建议你var onItemClickListener不要私有,直接从适配器外部使用它,然后删除fun setOnItemClickListener()......在 Kotlin 世界中,var像这样的public被编译为拥有它们的 setter,所以你不再真的需要 Java 风格的 setter。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

使用RecyclerView适配器-错误E / RecyclerView:未连接适配器;跳过布局

Android适配器onItemClick在RecyclerView上会影响多个View项

未连接适配器;跳过布局:RecyclerView和适配器

RecyclerView适配器连接错误:未连接适配器

RecyclerView() 适配器

RecyclerView:未连接适配器;跳过片段中的布局

“ E / RecyclerView:未连接适配器;正在跳过布局”

recyclerview未连接适配器;跳过布局

Recycleview RecyclerView:未连接适配器;跳过布局

RecyclerView没有显示项目。适配器未调用

如何修复RecyclerView:未连接适配器;跳过布局?

E / RecyclerView:未连接适配器;跳过布局

RecyclerView 错误:未连接适配器;跳过布局

从适配器更新recyclerview

RecyclerView Android错误:E / RecyclerView:未连接适配器;跳过布局

到recyclerview的Firebase数据显示错误-RecyclerView:android中未连接适配器

E / RecyclerView:未连接适配器;跳过布局而不在recyclerview中显示数据

RecyclerView 未填充,可能是一个愚蠢的适配器问题

Android Studio从Fiewbase检索数据并获得错误E / RecyclerView:未连接适配器;跳过布局

RecyclerView:未连接适配器-为什么我不断收到此错误?

E / RecyclerView:未连接适配器;跳过Android,kotlin中的布局

无法解决E / RecyclerView:未连接适配器;跳过布局

在RecyclerView适配器类中询问权限-未调用onRequestPermissionsResult

修改错误的请求和RecyclerView:未连接适配器;跳过布局

RecyclerView:未连接适配器;跳过布局和java.lang.NullPointerException

E / RecyclerView:未连接适配器;在获取Json Array时跳过布局

我不知道为什么我的适配器未更新我的recyclerview

错误ANDROID STUDIO E / RecyclerView:未连接适配器;跳过布局

RecyclerView在更新适配器数据后未显示任何内容