代码之家  ›  专栏  ›  技术社区  ›  Ksenia

在ViewHolder中使用自定义视图的奇怪行为

  •  0
  • Ksenia  · 技术社区  · 4 年前

    我有一个关于适配器的回收视图 ChartAdapter ,以及自定义视图( MyChart )在第一个ViewHolder的布局中创建( ProgressViewHolder

    <com.android.MyChart
          android:id="@+id/chart"
          ... /> 
    

    以及此自定义视图的数据( 我的图表 ProgressViewHolder程序 (方法 populateData ):

    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)
                )
        )
    }
    

    这个自定义视图( 我的图表 )它本身看起来是这样的:

    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}")
            }
        }
    }
    

    启动应用程序后,我在Logcat中看到以下日志:

    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
    

    在某个时刻,我 onEndReached ()此自定义视图中的方法( )(通过侦听器),它更新(添加)数据以填充此自定义视图,我调用该方法 chartAdapter?.notifyItemChanged(0) )更新后,我会看到以下日志:

    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
    

    如果我调用这个 方法(通过侦听器更新(添加)数据以填充自定义视图)并调用 图表适配器?。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 (和 init 是需要的 我的图表 ),但在第二次呼叫 通知项已更改 ,将再次使用第一个实例: 我的图表{8e165bf (以及 初始化 方法 不再被称为?

    0 回复  |  直到 4 年前