概要
RecyclerView内にExitTextを配置した際、テキスト入力後スクロールを繰り返すと入力したテキストが保持されない事象が発生。
対策
テキストリストを定義し、その中で保持。EditText
のListener
は複数回定義されないように、onBindViewHolder
内ではなく、ViewHolder
内で定義しておく。
コード
リストアイテム。EditText
を配置。
list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<EditText
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/edit_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
メインレイアウト。RecyclerView
を配置。
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.recyclerview.widget.RecyclerView
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:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:listitem="@layout/list_item"/>
アダプター。
・引数のitemList
はEditText
に表示するテキスト。EditText
の文字が変更されたら、itemList
の変更を行い、文字を保持しておく。
・doOnTextChanged
をViewHolder
クラス内のinit
で定義することで、重複した定義を行わないようにする。
ItemAdapter.kt
class ItemAdapter(var itemList: MutableList<String>) : RecyclerView.Adapter<ItemAdapter.ViewHolder>() {
class ViewHolder(val binding: ListItemBinding) : RecyclerView.ViewHolder(binding.root) {
var onTextChanged: ((String) -> Unit) = {}
init {
binding.editText.doOnTextChanged { text, _, _, _ ->
onTextChanged(text.toString())
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ViewHolder(ListItemBinding.inflate(LayoutInflater.from(parent.context), parent, false))
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.onTextChanged = {}
holder.binding.editText.setText(itemList[position])
holder.onTextChanged = {
itemList[position] = it
}
}
override fun getItemCount() = itemList.size
}
最後にメインレイアウトの処理。
MainActivity.kt
binding.list.adapter = ItemAdapter((0..50).map { it.toString() }.toMutableList())
参考サイト