立即触发 addTextChangedListener
addTextChangedListener is triggered immediately
我对 addTextChangedListener 有疑问。
当我启动应用程序时(触摸屏幕后)立即触发 addTextChangedListener。
addTextChangedListener 在带有自定义适配器的回收视图中的 ViewHolder Class 中。
我尝试将 setOnClickListener1() 和 setOnClickListener2() 从 onBindViewHolder 移动到 onCreateViewHolder 但最糟糕的是(启动应用程序后立即触发)。
这是我的适配器代码
import android.text.Editable
import android.text.TextWatcher
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.EditText
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
open class CustomAdapter(private val data: DataClass, private val activity: MainActivity) :
RecyclerView.Adapter<CustomAdapter.ViewHolder>() {
init {
setHasStableIds(true)
}
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): ViewHolder {
val rowItem: View =
LayoutInflater.from(parent.context).inflate(com.example.essai2.R.layout.list_item_view, parent, false)
var myview= ViewHolder(rowItem)
//myview.setOnClickListener1()
//myview.setOnClickListener2()
return myview
}
override fun onBindViewHolder(
holder: ViewHolder,
position: Int
) {
holder.editText.setText(data.list1[position])
holder.editText2.setText(data.list2[position])
holder.textview.setText(data.list3[position])
holder.setOnClickListener1()
holder.setOnClickListener2()
}
override fun getItemId(position: Int): Long {
return position.toLong()
}
override fun getItemCount(): Int {
return data.list1.size
}
inner class ViewHolder(rowItem: View) : RecyclerView.ViewHolder(rowItem) {
val textview : TextView = rowItem.findViewById(com.example.essai2.R.id.textview)
val editText : EditText= rowItem.findViewById(com.example.essai2.R.id.editText)
val editText2 : EditText= rowItem.findViewById(com.example.essai2.R.id.editText2)
fun fonction3(position: Int)
{
if (position >=1 && position <=98) {
data.list3[position] = (0.5 * (data.list2[position - 1].toDouble() + data.list2[position + 1].toDouble())).toString()
//activity.Update()
}
}
fun setOnClickListener1() {
editText.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(p0: Editable?) {
data.list1[getAdapterPosition()]= editText.text.toString()
// activity.fonction()
}
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
}
})
}
fun setOnClickListener2() {
editText2.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(p0: Editable?) {
data.list2[getAdapterPosition()] = editText2.text.toString()
activity.fonction2()
fonction3(getAdapterPosition())
}
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
}
})
}
}
}
这是我的 activity 代码
import android.os.Bundle
import android.widget.EditText
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val recyclerView = findViewById<RecyclerView>(R.id.recycler_view)
recyclerView.layoutManager = LinearLayoutManager(this)
recyclerView.adapter = CustomAdapter(DataClass(),this)
recyclerView.addItemDecoration(DividerItemDecoration(this, DividerItemDecoration.VERTICAL))
var textView2: TextView
textView2 = findViewById(R.id.textView)
var editText : EditText
}
fun Update()
{
// findViewById<RecyclerView>(R.id.recycler_view).getAdapter()?.notifyDataSetChanged()
val recyclerView = findViewById<RecyclerView>(R.id.recycler_view)
recyclerView.adapter=CustomAdapter(DataClass(),this)
(recyclerView.adapter as CustomAdapter).notifyDataSetChanged()
}
fun fonction ()
{
var textView2: TextView
textView2 = findViewById(R.id.textView)
textView2.text="!!!!!!"
}
fun fonction2 ()
{
var textView2: TextView
textView2 = findViewById(R.id.textView)
textView2.text="?????"
}
private fun generateData(): List<String> {
val data: MutableList<String> = ArrayList()
for (i in 0..99) {
data.add(i.toString() + "th Element")
}
return data
}
}
class DataClass(){
var list1: MutableList<String> = generateData2() as MutableList<String>
var list2: MutableList<String> = generateData3() as MutableList<String>
var list3: MutableList<String> = generateData4() as MutableList<String>
private fun generateData2(): List<String> {
val data: MutableList<String> = mutableListOf()
for (i in 0..99) {
data.add(i.toString())
}
return data
}
private fun generateData3(): List<String> {
val data: MutableList<String> =mutableListOf()
for (i in 0..99) {
data.add((10*i).toString())
}
return data
}
private fun generateData4(): List<String> {
val data: MutableList<String> = mutableListOf()
for (i in 0..99) {
data.add("none")
}
return data
}
}
在此先感谢您的帮助
编辑:这里是 list_item_view.xml
<?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="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
app:layout_constraintBottom_toBottomOf="parent"
tools:ignore="MissingConstraints">
<TextView
android:id="@+id/textview2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="TextView"
android:textSize="16dp" />
<TextView
android:id="@+id/textview"
android:layout_width="wrap_content"
android:layout_height="35dp"
android:text="TextView"
android:textSize="16dp" />
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/editText2"
android:layout_width="196dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:focusableInTouchMode="true"
android:focusedByDefault="false"
android:hint="hint" />
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/editText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:focusedByDefault="false"
android:hint="hint" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
您不应该在 onBindViewHolder 中添加 TextWatcher,因为每次 onBindViewHolder
调用时您都会向小部件添加多个侦听器。
在 onCreateViewHolder
中设置您的监听器以仅添加一个监听器,然后当您希望将 setText 设置为 EditText 时,您可以通过 setTag 来查看
editText.setTag("system input");
然后在侦听器中检查视图的标签以确定它是用户输入还是系统输入
如果 tag=="system input"
完成你的工作并最终删除标签
view.setTag(null)
我刚刚根据下面的对话更改了我的答案。
首先,这是您的 XML 文件(我只是更改了视图的 ID,没有其他任何内容):
<?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="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
app:layout_constraintBottom_toBottomOf="parent"
tools:ignore="MissingConstraints">
<TextView
android:id="@+id/tv2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="TextView2"
android:textSize="16dp" />
<TextView
android:id="@+id/tv1"
android:layout_width="wrap_content"
android:layout_height="35dp"
android:text="TextView1"
android:textSize="16dp" />
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/et2"
android:layout_width="196dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:focusableInTouchMode="true"
android:focusedByDefault="false"
android:hint="hint" />
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/et1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:focusedByDefault="false"
android:hint="hint" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
这是你的适配器(我检查了一切,没有错误):
import android.content.Context
import android.text.Editable
import android.text.TextWatcher
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.list_item_view.view.*
class CustomAdapter(private val data : DataClass, private val context : Context) :
RecyclerView.Adapter<CustomAdapter.ViewHolder>() {
init {
setHasStableIds(true)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val rowItem: View = LayoutInflater.from(context).inflate(R.layout.list_item_view, parent, false)
return ViewHolder(rowItem)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.itemView.tv1.setText(data.list3[position])
holder.itemView.et1.setText(data.list1[position])
holder.itemView.et2.setText(data.list2[position])
holder.itemView.et1.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(p0: Editable?) {
data.list1[position]= holder.itemView.et1.text.toString()
// activity.fonction()
}
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
}
})
holder.itemView.et2.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(p0: Editable?) {
data.list2[position] = holder.itemView.et2.text.toString()
//this is instead of `fonction2()`
holder.itemView.tv2.text = "?????"
//fonction2()
fonction3(position)
}
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
}
})
}
override fun getItemId(position: Int): Long {
return position.toLong()
}
override fun getItemCount(): Int {
return data.list1.size
}
inner class ViewHolder(rowItem: View) : RecyclerView.ViewHolder(rowItem) {
}
fun fonction3(position: Int) {
if (position in 1..98) {
data.list3[position] = (0.5 * (data.list2[position - 1].toDouble() + data.list2[position + 1].toDouble())).toString()
//activity.Update()
}
}
}
我对 addTextChangedListener 有疑问。 当我启动应用程序时(触摸屏幕后)立即触发 addTextChangedListener。
addTextChangedListener 在带有自定义适配器的回收视图中的 ViewHolder Class 中。
我尝试将 setOnClickListener1() 和 setOnClickListener2() 从 onBindViewHolder 移动到 onCreateViewHolder 但最糟糕的是(启动应用程序后立即触发)。
这是我的适配器代码
import android.text.Editable
import android.text.TextWatcher
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.EditText
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
open class CustomAdapter(private val data: DataClass, private val activity: MainActivity) :
RecyclerView.Adapter<CustomAdapter.ViewHolder>() {
init {
setHasStableIds(true)
}
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): ViewHolder {
val rowItem: View =
LayoutInflater.from(parent.context).inflate(com.example.essai2.R.layout.list_item_view, parent, false)
var myview= ViewHolder(rowItem)
//myview.setOnClickListener1()
//myview.setOnClickListener2()
return myview
}
override fun onBindViewHolder(
holder: ViewHolder,
position: Int
) {
holder.editText.setText(data.list1[position])
holder.editText2.setText(data.list2[position])
holder.textview.setText(data.list3[position])
holder.setOnClickListener1()
holder.setOnClickListener2()
}
override fun getItemId(position: Int): Long {
return position.toLong()
}
override fun getItemCount(): Int {
return data.list1.size
}
inner class ViewHolder(rowItem: View) : RecyclerView.ViewHolder(rowItem) {
val textview : TextView = rowItem.findViewById(com.example.essai2.R.id.textview)
val editText : EditText= rowItem.findViewById(com.example.essai2.R.id.editText)
val editText2 : EditText= rowItem.findViewById(com.example.essai2.R.id.editText2)
fun fonction3(position: Int)
{
if (position >=1 && position <=98) {
data.list3[position] = (0.5 * (data.list2[position - 1].toDouble() + data.list2[position + 1].toDouble())).toString()
//activity.Update()
}
}
fun setOnClickListener1() {
editText.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(p0: Editable?) {
data.list1[getAdapterPosition()]= editText.text.toString()
// activity.fonction()
}
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
}
})
}
fun setOnClickListener2() {
editText2.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(p0: Editable?) {
data.list2[getAdapterPosition()] = editText2.text.toString()
activity.fonction2()
fonction3(getAdapterPosition())
}
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
}
})
}
}
}
这是我的 activity 代码
import android.os.Bundle
import android.widget.EditText
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val recyclerView = findViewById<RecyclerView>(R.id.recycler_view)
recyclerView.layoutManager = LinearLayoutManager(this)
recyclerView.adapter = CustomAdapter(DataClass(),this)
recyclerView.addItemDecoration(DividerItemDecoration(this, DividerItemDecoration.VERTICAL))
var textView2: TextView
textView2 = findViewById(R.id.textView)
var editText : EditText
}
fun Update()
{
// findViewById<RecyclerView>(R.id.recycler_view).getAdapter()?.notifyDataSetChanged()
val recyclerView = findViewById<RecyclerView>(R.id.recycler_view)
recyclerView.adapter=CustomAdapter(DataClass(),this)
(recyclerView.adapter as CustomAdapter).notifyDataSetChanged()
}
fun fonction ()
{
var textView2: TextView
textView2 = findViewById(R.id.textView)
textView2.text="!!!!!!"
}
fun fonction2 ()
{
var textView2: TextView
textView2 = findViewById(R.id.textView)
textView2.text="?????"
}
private fun generateData(): List<String> {
val data: MutableList<String> = ArrayList()
for (i in 0..99) {
data.add(i.toString() + "th Element")
}
return data
}
}
class DataClass(){
var list1: MutableList<String> = generateData2() as MutableList<String>
var list2: MutableList<String> = generateData3() as MutableList<String>
var list3: MutableList<String> = generateData4() as MutableList<String>
private fun generateData2(): List<String> {
val data: MutableList<String> = mutableListOf()
for (i in 0..99) {
data.add(i.toString())
}
return data
}
private fun generateData3(): List<String> {
val data: MutableList<String> =mutableListOf()
for (i in 0..99) {
data.add((10*i).toString())
}
return data
}
private fun generateData4(): List<String> {
val data: MutableList<String> = mutableListOf()
for (i in 0..99) {
data.add("none")
}
return data
}
}
在此先感谢您的帮助
编辑:这里是 list_item_view.xml
<?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="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
app:layout_constraintBottom_toBottomOf="parent"
tools:ignore="MissingConstraints">
<TextView
android:id="@+id/textview2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="TextView"
android:textSize="16dp" />
<TextView
android:id="@+id/textview"
android:layout_width="wrap_content"
android:layout_height="35dp"
android:text="TextView"
android:textSize="16dp" />
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/editText2"
android:layout_width="196dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:focusableInTouchMode="true"
android:focusedByDefault="false"
android:hint="hint" />
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/editText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:focusedByDefault="false"
android:hint="hint" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
您不应该在 onBindViewHolder 中添加 TextWatcher,因为每次 onBindViewHolder
调用时您都会向小部件添加多个侦听器。
在 onCreateViewHolder
中设置您的监听器以仅添加一个监听器,然后当您希望将 setText 设置为 EditText 时,您可以通过 setTag 来查看
editText.setTag("system input");
然后在侦听器中检查视图的标签以确定它是用户输入还是系统输入
如果 tag=="system input"
完成你的工作并最终删除标签
view.setTag(null)
我刚刚根据下面的对话更改了我的答案。
首先,这是您的 XML 文件(我只是更改了视图的 ID,没有其他任何内容):
<?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="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
app:layout_constraintBottom_toBottomOf="parent"
tools:ignore="MissingConstraints">
<TextView
android:id="@+id/tv2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="TextView2"
android:textSize="16dp" />
<TextView
android:id="@+id/tv1"
android:layout_width="wrap_content"
android:layout_height="35dp"
android:text="TextView1"
android:textSize="16dp" />
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/et2"
android:layout_width="196dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:focusableInTouchMode="true"
android:focusedByDefault="false"
android:hint="hint" />
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/et1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:focusedByDefault="false"
android:hint="hint" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
这是你的适配器(我检查了一切,没有错误):
import android.content.Context
import android.text.Editable
import android.text.TextWatcher
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.list_item_view.view.*
class CustomAdapter(private val data : DataClass, private val context : Context) :
RecyclerView.Adapter<CustomAdapter.ViewHolder>() {
init {
setHasStableIds(true)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val rowItem: View = LayoutInflater.from(context).inflate(R.layout.list_item_view, parent, false)
return ViewHolder(rowItem)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.itemView.tv1.setText(data.list3[position])
holder.itemView.et1.setText(data.list1[position])
holder.itemView.et2.setText(data.list2[position])
holder.itemView.et1.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(p0: Editable?) {
data.list1[position]= holder.itemView.et1.text.toString()
// activity.fonction()
}
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
}
})
holder.itemView.et2.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(p0: Editable?) {
data.list2[position] = holder.itemView.et2.text.toString()
//this is instead of `fonction2()`
holder.itemView.tv2.text = "?????"
//fonction2()
fonction3(position)
}
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
}
})
}
override fun getItemId(position: Int): Long {
return position.toLong()
}
override fun getItemCount(): Int {
return data.list1.size
}
inner class ViewHolder(rowItem: View) : RecyclerView.ViewHolder(rowItem) {
}
fun fonction3(position: Int) {
if (position in 1..98) {
data.list3[position] = (0.5 * (data.list2[position - 1].toDouble() + data.list2[position + 1].toDouble())).toString()
//activity.Update()
}
}
}