ListViewのViewの再利用
まずはListViewのViewが再利用されていることを確認する。
package com.example.listviewglobalvisiblerect
import android.widget.BaseAdapter
import android.content.Context
import android.view.View
import android.view.ViewGroup
import android.app.Activity
import android.graphics.Color
import android.graphics.Rect
import android.util.Log
import android.widget.TextView
data class SampleData(val id: Long, val value: String)
class SampleAdapter: BaseAdapter {
private val context: Context
private val items: List<SampleData>
private val views = ArrayList<View>()
constructor(context: Context, items: List<SampleData>) {
this.context = context
this.items = items
}
override fun getCount(): Int {
return items.size
}
override fun getItem(position: Int): Any {
return items.get(position)
}
override fun getItemId(position: Int): Long {
return items.get(position).id
}
override fun getView(position: Int, convertView: View?, container: ViewGroup?): View {
var view = convertView ?: (this.context as Activity).layoutInflater.inflate(R.layout.sample_list_item, container, false)
if (convertView == null) {
Log.v("SampleAdapter", "view ${position} is created")
view.tag = position
if (position == 0) {
view.setBackgroundColor(Color.LTGRAY)
}
views.add(view)
} else {
Log.v("SampleAdapter", "view ${convertView.tag} is recycled at ${position}")
}
view.findViewById<TextView>(R.id.text_view).setText(items.get(position).value)
return view
}
}
position == 0
のCellだけ生成時に背景色を灰色にしたところ、他のpositionでも再利用された灰色のCellが登場した。
画面に表示される分のViewが生成され、スクロールすると画面外に出たViewが再利用された。
V/SampleAdapter: view 0 is created
V/SampleAdapter: view 1 is created
V/SampleAdapter: view 2 is created
V/SampleAdapter: view 3 is created
V/SampleAdapter: view 4 is created
V/SampleAdapter: view 0 is recycled at 5
V/SampleAdapter: view 1 is recycled at 6
各ViewにgetGlobalVisibleRect()を実行した結果
getGlobalVisibleRect()はViewの可視領域を取得できる関数で、領域がない場合falseを返す。
views.forEach { v ->
var rect = Rect();
if (v.getGlobalVisibleRect(rect)) {
Log.v("SampleAdapter", "view ${v.tag} visible rect: ${rect} has_parent: ${v.parent != null}")
} else {
Log.v("SampleAdapter", v.tag.toString() + " is not visible")
}
}
再利用待ち(parent=false
)の画面内にないView 1はfalseを返すと思っていたが、実際はtrueを返し正しくない値が入ってしまう。
V/SampleAdapter: view 0 visible rect: Rect(0, 1520 - 1080, 2018) has_parent: true
V/SampleAdapter: view 1 visible rect: Rect(0, 0 - 1185, 498) has_parent: false
V/SampleAdapter: view 2 visible rect: Rect(0, 66 - 1080, 515) has_parent: true
V/SampleAdapter: view 3 visible rect: Rect(0, 518 - 1080, 1016) has_parent: true
V/SampleAdapter: view 4 visible rect: Rect(0, 1019 - 1080, 1517) has_parent: true