首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >RecyclerView onclick侦听器没有响应

RecyclerView onclick侦听器没有响应
EN

Stack Overflow用户
提问于 2022-08-01 16:28:08
回答 3查看 85关注 0票数 0

我目前正在与Kotlin一起开发一个Wordle克隆。到目前为止,我已经完成了用RecyclerView构建键盘,但是onClick事件侦听器存在一些问题,它的响应能力不强。我必须多次单击键才能使其工作,有时它根本不响应单击。我想知道我在这里做错了什么。

这是我的MainActivity代码

代码语言:javascript
运行
复制
class MainActivity : AppCompatActivity() {
    private var layoutManager: RecyclerView.LayoutManager? = null;
    private var adapter: RecyclerView.Adapter<RecyclerAdapter.ViewHolder>? = null;
    private var row1KeyList = listOf<String>("Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P");
    private var row2KeyList = listOf<String>("A", "S", "D", "F", "G", "H", "J", "K", "L");
    private var row3KeyList = listOf<String>("Z", "X", "C", "V", "B", "N", "M");

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val recyclerView = findViewById<RecyclerView>(R.id.recyclerView)
        val recyclerView2 = findViewById<RecyclerView>(R.id.recyclerView2)
        val recyclerView3 = findViewById<RecyclerView>(R.id.recyclerView3)

        recyclerView.layoutManager = LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false)
        recyclerView2.layoutManager = LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false)
        recyclerView3.layoutManager = LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false)

        var rowAdapter1 = RecyclerAdapter(row1KeyList)
        recyclerView.adapter = rowAdapter1
        rowAdapter1.setOnItemClickListener(object : RecyclerAdapter.onItemClickListener{
            override fun onItemClick(position: Int){
//                Toast.makeText(this@MainActivity, row1KeyList[position], Toast.LENGTH_SHORT).show()
                Log.d("letter: ", row1KeyList[position])
                Log.d("position", position.toString())
                val tile = findViewById<TextView>(R.id.tile1)
                tile.text = row1KeyList[position]
            }
        })
        recyclerView2.adapter= RecyclerAdapter(row2KeyList)
        recyclerView3.adapter= RecyclerAdapter(row3KeyList)
    }


}

这是RecyclerAdapter的代码

代码语言:javascript
运行
复制
class RecyclerAdapter(val keyList: List<String>): RecyclerView.Adapter <RecyclerAdapter.ViewHolder>() {
//        private var keyList = listOf<String>("Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P");
        private var mListener: onItemClickListener? = null

        interface onItemClickListener{
            fun onItemClick(position: Int)
        }

        fun setOnItemClickListener(listener: onItemClickListener){
            mListener = listener
        }

        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
            val v = LayoutInflater.from(parent.context).inflate(R.layout.key_list, parent, false)
            return ViewHolder(v, mListener)
        }

        override fun onBindViewHolder(holder: ViewHolder, position: Int) {
            holder.itemKey.text = keyList[position]
        }

        override fun getItemCount(): Int {
            return keyList.size;
        }

        inner class ViewHolder(itemView: View, listener: onItemClickListener?): RecyclerView.ViewHolder(itemView) {
            var itemKey: AppCompatButton

            init{
                itemView.setOnClickListener {
                    listener?.onItemClick(position)
                }
               itemKey = itemView.findViewById(R.id.letterKey)

            }
        }
}

此外,我还附加了密钥列表的布局文件和主布局的代码。

代码语言:javascript
运行
复制
// key_list.xml defined how each key looks like
<?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        >
        <androidx.appcompat.widget.AppCompatButton
            android:id="@+id/letterKey"
            android:layout_width="24dp"
            android:layout_height="36dp"
            android:background="#D3D6DA"
            android:layout_marginRight="6dp"
            android:textColor="@android:color/black"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    </androidx.constraintlayout.widget.ConstraintLayout>

以下是主活动的布局

代码语言:javascript
运行
复制
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.5"
        />
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.6"
        />
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.7"
        />

    <TextView
        android:id="@+id/tile1"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:layout_marginTop="16dp"
        android:layout_marginEnd="16dp"
        android:textSize="10pt"
        android:gravity="center"
        android:background="@drawable/tile_border"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintVertical_bias="0.1"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toTopOf="parent" />


</androidx.constraintlayout.widget.ConstraintLayout>

EN

Stack Overflow用户

发布于 2022-08-01 19:50:06

您还没有发布问题中其他两行的单击侦听器代码,因此我们不知道那里发生了什么,是否有问题--但是您发布的解决方案是将每个单击侦听器值视为来自第1行。

代码语言:javascript
运行
复制
// Making it a list of lists instead of separate variables will make lookups easier!
// You could keep them as variables, but then you'll have to translate row numbers
// to the correct variable
val rows = listOf(
    listOf("Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P"),
    listOf("A", "S", "D", "F", "G", "H", "J", "K", "L"),
    listOf("Z", "X", "C", "V", "B", "N", "M")
)

// we'll look this up once in onCreate and store it here
lateinit var tile: TextView

// this is the function your click listeners will call
fun handleKeyClick(row: Int, position: Int) {
    // look up the key, nice and easy when it's nested lists!
    tile.text = rows[row][position]
}


override fun onCreate(savedInstanceState: Bundle?) {
    ...
    // it's better to find this once and keep a reference to it!
    tile = findViewById<TextView>(R.id.tile1)
    ...
    // pass each RecyclerView the appropriate row of keys, and also a function
    // that takes a position Int. We're using that to call our handler function,
    // and also passing the appropriate row number - it's different in each function
    // for each RecyclerView!
    recyclerView.adapter = RecyclerAdapter(rows[0]) { position -> 
        handleKeyClick(row = 0, position)
    }
    recyclerView.adapter = RecyclerAdapter(rows[1]) { position ->
        handleKeyClick(row = 1, position)
    }
    recyclerView.adapter = RecyclerAdapter(rows[2]) { position ->
        handleKeyClick(row = 2, position)
    }
    ...
}

然后,Adapter需要处理我们传入的函数:

代码语言:javascript
运行
复制
// the second parameter is different - it's a type that represents a function with
// one Int parameter (the position) and it returns nothing. That's what we're
// passing in when we're creating the adapters in onCreate up there
class RecyclerAdapter(
    val keyList: List<String>,
    val positionClickListener : (Int) -> Unit
) : RecyclerView.Adapter <RecyclerAdapter.ViewHolder>() {

    ...

    // no need to pass a listener in, it's an -inner- class so it can see
    // positionClickListener in the parent class
    inner class ViewHolder(itemView: View): RecyclerView.ViewHolder(itemView) {
        
        init {
            itemView.setOnClickListener {
                // call the listener with the current position this is displaying
                positionClickListener(bindingAdapterPosition)
            }
        }
}

您可以在onBindViewHolder中设置一个单击侦听器,但是在每个ViewHolder中设置它一次会更有效,因此您不会经常创建侦听器对象(通常,在这里您的固定布局并不重要!)

这将使您所做的工作--您的另一个选择是传递键字符本身,即将侦听器函数设置为(String) -> Unit (您应该真正使用Char),然后侦听器就可以使用该字符而不必按位置查找它。

我要说的另一件事是,这并不是真正应该使用RecyclerView的东西--它是用来滚动项目列表的,它重用ViewHolder来提高效率,而不是为每个项目创建一个。你在屏幕上同时显示了所有的东西,你并没有从它所涉及的额外工作中得到任何好处!

有很多方法可以完成您正在做的事情--最简单的方法就是一个ConstraintLayout,其中包含所有的关键TextView(它们应该是Button的,特别是出于可访问性的原因),用packed链将它们挤在中间。它们都可以使用相同的OnClickListener,它传递作为参数单击的View,因此您可以获取文本内容(或tag)并计算按下哪个键。只是个主意!你已经在这里完成了这项工作,所以不需要重新发明它

票数 0
EN
查看全部 3 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73196827

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档