Странности с созданием и использованием custom view во ViewHolder
У меня есть recyclerview c адаптером ChartAdapter, и в layout-e первого ViewHolder-а (ProgressViewHolder) создаётся custom view (MyChart):
<com.android.MyChart
android:id="@+id/chart"
... />
данные которого наполняются через метод этого ViewHolder-а:
class ProgressViewHolder(
val binding: ItemProgressBinding
) : BaseAdapter.BaseViewHolder<BaseEntry>(binding) {
override fun bind(item: BaseJourneyEntry, handler: Any?) {
Log.d(TAG, "ProgressViewHolder, bind, $this")
super.bind(item, handler)
populateDataAfterLayoutReady(progressModel = item as ChartEntry)
}
private fun populateDataAfterLayoutReady(
progressModel: chartEntry
) {
binding.root.doOnLayout { populateData(progressModel) }
}
private fun populateData(сhartEntry: ChartEntry) {
binding.chart.populateData(
ChartData(
values = getChartValues(сhartEntry)
)
)
}
A само это custom view (MyChart) выглядит следующим образом:
class MyChart @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr) {
private val adapterItems = mutableListOf<ChartColumnData>()
init {
Log.d(TAG, "init, adapterItems.count = ${adapterItems.size}, $this")
...
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
Log.d(TAG, "onAttachedToWindow, adapterItems.count = ${adapterItems.size}, $this")
}
fun populateData(data: ChartData) {
Log.d(TAG, "populateData, adapterItems.count = ${adapterItems.size}")
Log.d(TAG, "populateData, data.values.size = ${data.values.size}")
if (adapterItems.isEmpty()) {
val items = data.values
adapterItems.addAll(items)
Log.d(TAG, "populateData 2, adapterItems.count = ${adapterItems.size}")
}
}
}
После запуска приложения я вижу в логах следующее:
init, adapterItems.count = 0, com.android.MyChart{8e165bf V.E...... ......I. 0,0-0,0 #7f0b00f3 app:id/chart}
rogressViewHolder, bind, ProgressViewHolder{7a05e16 position=0 id=-1, oldPos=-1, pLpos:-1 no parent}
onAttachedToWindow, adapterItems.count = 0, com.android.MyChart{8e165bf V.E...... ......I. 0,0-0,0 #7f0b00f3 app:id/chart}
populateData, adapterItems.count = 0
populateData, data.values.size = 15
populateData 2, adapterItems.count = 15
И в какой-то момент я из этого custom view (MyChart) (через listener) вызываю метод (onEndReached), который обновляет (добавляет) данные для наполнения этого custom view, и вызываю метод chartAdapter?.notifyItemChanged(0). Данные в этом custom view (MyChart) обновляются и я при этом вижу в логах следующее:
onEndReached, adapterItems.count = 15
init, adapterItems.count = 0, com.android.MyChart{c0f2b1c V.E...... ......I. 0,0-0,0 #7f0b00f3 app:id/chart}
ProgressViewHolder, bind, ProgressViewHolder{581934c position=0 id=-1, oldPos=-1, pLpos:-1 no parent}
onAttachedToWindow, adapterItems.count = 0, com.android.MyChart{c0f2b1c V.E...... ......I. 0,0-0,0 #7f0b00f3 app:id/chart}
populateData, adapterItems.count = 0
populateData, data.values.size = 28
populateData 2, adapterItems.count = 28
и если я снова вызываю этот метод onEndReached (который через listener обновляет (добавляет) данные для наполнения custom view) и вызываю метод chartAdapter?.notifyItemChanged(0), в логах видно следующее:
onEndReached, adapterItems.count = 28
ProgressViewHolder, bind, ProgressViewHolder{7a05e16 position=0 id=-1, oldPos=-1, pLpos:-1 no parent}
onAttachedToWindow, adapterItems.count = 15, com.android.MyChart{8e165bf V.E...... .......D 0,194-936,717 #7f0b00f3 app:id/chart}
populateData, adapterItems.count = 15
populateData, data.values.size = 41
То, что я вижу в логах, вызывает у меня вопрос:
каким образом получается так, что сначала создаются и используются экземпляры ProgressViewHolder{7a05e16 и MyChart{8e165bf, а после первого вызова notifyItemChanged создаются другие экземпляры этих классов - ProgressViewHolder{581934c и MyChart{c0f2b1c (и у MyChart вызывается init), а после второго вызова notifyItemChanged - снова используется первые экземпляры: ProgressViewHolder{7a05e16 и MyChart{8e165bf (и метод init у MyChart уже не вызывается)?