編集可能なTextViewがListViewの中にある場合が今回の問題です。
class GroupListAdapter(context: Context, var groups: MutableList<MemoGroup>) :
ArrayAdapter<MemoGroup> (context, 0, groups) {
data class ViewHolder(val textView: TextView)
private val layoutInflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
var view = convertView
var holder: ViewHolder
if (view == null) {
view = layoutInflater.inflate(R.layout.view_group_setting, null)
holder = ViewHolder(
view.findViewById(R.id.textView)
)
view.tag = holder
holder.textView.addTextChangedListener(object: TextWatcher {
override fun afterTextChanged(p0: Editable?) {
if(p0 != null) {
groups[position].title = p0.toString()
}
}
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
})
} else {
holder = view.tag as ViewHolder
}
holder.textView.text = groups[position].title
return view!!
}
}
本当はもうちょっとごちゃごちゃしているのですが、多少見やすいように修正しました。
さて、これだと何度もafterTextChangedが呼ばれて、しかもpositionもp0.toString()も思った値が取れない。
ここを参考にして解決しました。
class GroupListAdapter(context: Context, var groups: MutableList<MemoGroup>) :
ArrayAdapter<MemoGroup> (context, 0, groups) {
inner class MutableWatcher : TextWatcher {
var position: Int = 0
var active: Boolean = false
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {}
override fun afterTextChanged(s: Editable) {
if (active) {
groups[position].title = s.toString()
}
}
}
data class ViewHolder(val textView: TextView, val watcher:MutableWatcher)
private val layoutInflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
var view = convertView
var holder: ViewHolder
if (view == null) {
view = layoutInflater.inflate(R.layout.view_group_setting, null)
holder = ViewHolder(
view.findViewById(R.id.textView),
MutableWatcher()
)
view.tag = holder
holder.textView.addTextChangedListener(holder.watcher)
} else {
holder = view.tag as ViewHolder
}
holder.watcher.active = false
holder.textView.text = groups[position].title
holder.watcher.position = position
holder.watcher.active = true
return view!!
}
}
textView.textに代入してもafterTextChangedが呼ばれるので、その時は無視するようにして、TextWatcher をそれぞれに持たせる感じなのか?まだ勉強が足りません。