Java 如何检测用户';在RecyclerView中输入EditText的值完成了吗?

Java 如何检测用户';在RecyclerView中输入EditText的值完成了吗?,java,android,kotlin,android-recyclerview,Java,Android,Kotlin,Android Recyclerview,我有一个包含编辑文本的recyclerview。只有在用户在任何编辑文本中输入金额后,我才能获得每个编辑文本的值,这样我才能更新总金额 我试图实现的是添加EditText的值并将其发送到活动。在活动中,我有“继续”按钮(我将在其中对总量执行一些验证)和总量文本视图(使用侦听器从recyclerview适配器检索) 我尝试使用setOnEditorActionListener,但如果用户单击“上一步”按钮而不是按enter键,这将不会有帮助 此外,我尝试使用焦点更改侦听器,但问题是即使在页面外部单

我有一个包含编辑文本的recyclerview。只有在用户在任何编辑文本中输入金额后,我才能获得每个编辑文本的值,这样我才能更新总金额

我试图实现的是添加EditText的值并将其发送到活动。在活动中,我有“继续”按钮(我将在其中对总量执行一些验证)和总量文本视图(使用侦听器从recyclerview适配器检索)

我尝试使用
setOnEditorActionListener
,但如果用户单击“上一步”按钮而不是按enter键,这将不会有帮助

此外,我尝试使用焦点更改侦听器,但问题是即使在页面外部单击,EditText也不会失去焦点

当然,TextWatcher不是一个理想的解决方案,因为它在OnBindViewHolder中可能非常昂贵

我需要确保每当用户单击“继续”按钮时,总金额都会在之前更新。

Idea 最好的方法是添加两个通信(通过接口):

  • 活动
    适配器

  • 适配器
    和单个
    视窗夹之间的第二个

在添加此类通信后,您可以计算“实时”总数

解决方案 步骤#1 创建第一个
接口
,例如:

interface AdapterContentChanged {
    fun valuesChanged()
}
private val ownAdapter = OwnAdapter(
    items,    // elements inside list
    this      // interface implementation
)
interface OwnViewHolderTextChanged {
    fun onTextChanged(position: Int, newValue: Int)
}
override fun onBindViewHolder(holder: OwnViewHolder, position: Int) {
    val number = list[position]
    holder.bind(number, position, this)
}
fun bind(
    // TODO - add here more information which you need,
    position: Int,
    listener: OwnViewHolderTextChanged
) {
    itemView.edit_text.addTextChangedListener(object : TextWatcher {
        override fun afterTextChanged(s: Editable?) {
            // Get EditText content
            val newValue = getNumber()

            // Call method from interface
            listener.onTextChanged(position = position, newValue = newValue)
        }

        override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
            // Not used
        }

        override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
            // Not used
        }

    })
}
override fun onTextChanged(position: Int, newValue: Int) {
    list[position] = newValue
    listener.valuesChanged()
}
并在活动中实现它或创建新变量(作为匿名类)

第2步 在创建适配器时传递您的活动(或上述接口的实例),例如:

interface AdapterContentChanged {
    fun valuesChanged()
}
private val ownAdapter = OwnAdapter(
    items,    // elements inside list
    this      // interface implementation
)
interface OwnViewHolderTextChanged {
    fun onTextChanged(position: Int, newValue: Int)
}
override fun onBindViewHolder(holder: OwnViewHolder, position: Int) {
    val number = list[position]
    holder.bind(number, position, this)
}
fun bind(
    // TODO - add here more information which you need,
    position: Int,
    listener: OwnViewHolderTextChanged
) {
    itemView.edit_text.addTextChangedListener(object : TextWatcher {
        override fun afterTextChanged(s: Editable?) {
            // Get EditText content
            val newValue = getNumber()

            // Call method from interface
            listener.onTextChanged(position = position, newValue = newValue)
        }

        override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
            // Not used
        }

        override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
            // Not used
        }

    })
}
override fun onTextChanged(position: Int, newValue: Int) {
    list[position] = newValue
    listener.valuesChanged()
}
步骤3 创建第二个
接口
,例如:

interface AdapterContentChanged {
    fun valuesChanged()
}
private val ownAdapter = OwnAdapter(
    items,    // elements inside list
    this      // interface implementation
)
interface OwnViewHolderTextChanged {
    fun onTextChanged(position: Int, newValue: Int)
}
override fun onBindViewHolder(holder: OwnViewHolder, position: Int) {
    val number = list[position]
    holder.bind(number, position, this)
}
fun bind(
    // TODO - add here more information which you need,
    position: Int,
    listener: OwnViewHolderTextChanged
) {
    itemView.edit_text.addTextChangedListener(object : TextWatcher {
        override fun afterTextChanged(s: Editable?) {
            // Get EditText content
            val newValue = getNumber()

            // Call method from interface
            listener.onTextChanged(position = position, newValue = newValue)
        }

        override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
            // Not used
        }

        override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
            // Not used
        }

    })
}
override fun onTextChanged(position: Int, newValue: Int) {
    list[position] = newValue
    listener.valuesChanged()
}
并在适配器中实现它或创建新变量(匿名类)-与步骤1中的相同

步骤4 绑定viewHolder时,传递适配器(或变量)和
位置(项目的),例如:

interface AdapterContentChanged {
    fun valuesChanged()
}
private val ownAdapter = OwnAdapter(
    items,    // elements inside list
    this      // interface implementation
)
interface OwnViewHolderTextChanged {
    fun onTextChanged(position: Int, newValue: Int)
}
override fun onBindViewHolder(holder: OwnViewHolder, position: Int) {
    val number = list[position]
    holder.bind(number, position, this)
}
fun bind(
    // TODO - add here more information which you need,
    position: Int,
    listener: OwnViewHolderTextChanged
) {
    itemView.edit_text.addTextChangedListener(object : TextWatcher {
        override fun afterTextChanged(s: Editable?) {
            // Get EditText content
            val newValue = getNumber()

            // Call method from interface
            listener.onTextChanged(position = position, newValue = newValue)
        }

        override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
            // Not used
        }

        override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
            // Not used
        }

    })
}
override fun onTextChanged(position: Int, newValue: Int) {
    list[position] = newValue
    listener.valuesChanged()
}
步骤5 在
bind()

PostTextChanged()
方法(来自
TextWatcher
)中,从接口调用方法并传递新值。例如:

interface AdapterContentChanged {
    fun valuesChanged()
}
private val ownAdapter = OwnAdapter(
    items,    // elements inside list
    this      // interface implementation
)
interface OwnViewHolderTextChanged {
    fun onTextChanged(position: Int, newValue: Int)
}
override fun onBindViewHolder(holder: OwnViewHolder, position: Int) {
    val number = list[position]
    holder.bind(number, position, this)
}
fun bind(
    // TODO - add here more information which you need,
    position: Int,
    listener: OwnViewHolderTextChanged
) {
    itemView.edit_text.addTextChangedListener(object : TextWatcher {
        override fun afterTextChanged(s: Editable?) {
            // Get EditText content
            val newValue = getNumber()

            // Call method from interface
            listener.onTextChanged(position = position, newValue = newValue)
        }

        override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
            // Not used
        }

        override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
            // Not used
        }

    })
}
override fun onTextChanged(position: Int, newValue: Int) {
    list[position] = newValue
    listener.valuesChanged()
}
要从
EditText
计算值,可以使用以下方法:

private fun getNumber(): Int =
    try {
        itemView.edit_text.text.toString().toInt()
    } catch (e: Exception) {
        0
    }
步骤6 在方法内更改文本时,您必须:

  • 更新列表的内容

  • 通知适配器“某些内容已更改”

例如:

interface AdapterContentChanged {
    fun valuesChanged()
}
private val ownAdapter = OwnAdapter(
    items,    // elements inside list
    this      // interface implementation
)
interface OwnViewHolderTextChanged {
    fun onTextChanged(position: Int, newValue: Int)
}
override fun onBindViewHolder(holder: OwnViewHolder, position: Int) {
    val number = list[position]
    holder.bind(number, position, this)
}
fun bind(
    // TODO - add here more information which you need,
    position: Int,
    listener: OwnViewHolderTextChanged
) {
    itemView.edit_text.addTextChangedListener(object : TextWatcher {
        override fun afterTextChanged(s: Editable?) {
            // Get EditText content
            val newValue = getNumber()

            // Call method from interface
            listener.onTextChanged(position = position, newValue = newValue)
        }

        override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
            // Not used
        }

        override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
            // Not used
        }

    })
}
override fun onTextChanged(position: Int, newValue: Int) {
    list[position] = newValue
    listener.valuesChanged()
}
步骤7 当某些内容发生变化时(Activty会知道这一点),您可以计算新的总和:

override fun valuesChanged() {
    val sum: Int = ownAdapter.getCurrentSum()
    text_view.text = "Sum:  $sum"
}
演示

Apt!很详细。我的解决方案有效吗?:)是的,博肯,你的解决方案正在发挥作用。谢谢