我目前正在与Kotlin一起开发一个Wordle克隆。到目前为止,我已经完成了用RecyclerView构建键盘,但是onClick事件侦听器存在一些问题,它的响应能力不强。我必须多次单击键才能使其工作,有时它根本不响应单击。我想知道我在这里做错了什么。
这是我的MainActivity代码
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的代码
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)
}
}
}
此外,我还附加了密钥列表的布局文件和主布局的代码。
// 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>
以下是主活动的布局
<?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>
发布于 2022-08-01 19:50:06
您还没有发布问题中其他两行的单击侦听器代码,因此我们不知道那里发生了什么,是否有问题--但是您发布的解决方案是将每个单击侦听器值视为来自第1行。
// 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需要处理我们传入的函数:
// 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
)并计算按下哪个键。只是个主意!你已经在这里完成了这项工作,所以不需要重新发明它
https://stackoverflow.com/questions/73196827
复制相似问题