0

私はrecyclerViewを持っています。プルして更新すると、新しいデータが 1 つのリスト アイテムにすぎない場合、リサイクラー ビューはそのアイテムを完全に読み込みます。しかし、更新されたデータに 2 つ以上が含まれている場合、ビューは適切に再利用されていないと思います。actionContainer では、更新されたリスト アイテムごとに 1 つのアイテムのみを追加する必要があります。ただし、更新するプル中に、更新するリスト項目が 2 つ以上ある場合にのみ、actionContainer は 1 つだけであるべき場所に 2 つのデータを表示します。誰かがこれを修正するのを手伝ってくれますか?

override fun onBindViewHolder(holder: HistoryListAdapter.ViewHolder?, position: Int) {
            info("onBindViewHolder =>"+listAssets.size)
            info("onBindViewHolder itemCount =>"+itemCount)
            info("onBindViewHolder position =>"+position)
        val notesButton = holder?.notesButton
        val notesView = holder?.notesTextView

        val dateTime = listAssets[position].date
        val location = listAssets[position].location

        val sessionId = listAssets[position].id
        holder?.sessionID = sessionId
        holder?.portraitImageView?.setImageDrawable(listAssets[position].image)
        holder?.titleTextView?.text = DateTimeFormatter.getFormattedDate(context, dateTime)

        val timeString = DateTimeFormatter.getFormattedTime(context, dateTime)

        if (location.length != 0) {
            holder?.subtitleTextView?.text = "$timeString @ $location"
        } else {
            holder?.subtitleTextView?.text = "$timeString"
        }

        val data = listAssets[position].data

        for (actionData in data) {
            val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
            val parent = inflater.inflate(R.layout.history_card_action, null)

            val icon = parent?.findViewById(R.id.historyActionIcon) as ImageView
            val title = parent?.findViewById(R.id.historyActionTitle) as TextView
            val subtitle = parent?.findViewById(R.id.historyActionSubtitle) as TextView

            var iconDrawable: Drawable? = null

            when(actionData.type) {

                ActionType.HEART -> {
                    iconDrawable = ContextCompat.getDrawable(context, R.drawable.heart)
                }
                ActionType.LUNGS -> {
                    iconDrawable = ContextCompat.getDrawable(context, R.drawable.lungs)
                }
                ActionType.TEMPERATURE -> {
                    iconDrawable = ContextCompat.getDrawable(context, R.drawable.temperature)
                }
            }

            icon.setImageDrawable(iconDrawable)

            val titleString = actionData.title

            titleString?.let {
                title.text = titleString
            }

            val subtitleString = actionData.subtitle

            subtitleString?.let {
                subtitle.text = subtitleString
            }

            holder?.actionContainer?.addView(parent)
        }


        val notes = listAssets[position].notes
        notesView?.text = notes

        if (notes.length == 0) {
            notesButton?.layoutParams?.width = 0
        } else {
            notesButton?.layoutParams?.width = toggleButtonWidth
        }

        if (expandedNotes.contains(sessionId)) {
            notesView?.expandWithoutAnimation()
        } else {
            notesView?.collapseWithoutAnimation()
        }

        notesButton?.onClick {
            notesView?.toggleExpansion()
        }
    }


        data class ListAssets(val id: String,
                                  val date: Date,
                                  val location: String,
                                  val notes: String,
                                  val image: Drawable,
                                  val data: ArrayList<ListData>)

            data class ListData(val type: ActionType,
                                val title: String?,
                                val subtitle: String?)

    override fun onViewRecycled(holder: HistoryListAdapter.ViewHolder?) {
            super.onViewRecycled(holder)

            if (holder != null) {
    holder.actionContainer.removeAllViewsInLayout()
                holder.actionContainer.removeAllViews()

                val notesTextView = holder.notesTextView

                if (notesTextView != null) {
                    if (notesTextView.expandedState) {
                        val sessionID = holder.sessionID

                        sessionID?.let {
                            val sessionSearch = expandedNotes.firstOrNull {
                                it.contentEquals(sessionID)
                            }

                            if (sessionSearch == null) {
                                expandedNotes.add(sessionID)
                            }
                        }

                    } else {
                        val sessionID = holder.sessionID

                        sessionID?.let {
                            val sessionSearch = expandedNotes.firstOrNull {
                                it.contentEquals(sessionID)
                            }

                            if (sessionSearch != null) {
                                expandedNotes.remove(sessionSearch)
                            }
                        }
                    }
                }
            }

        }
4

3 に答える 3

0

onViewRecycled()まず、非常に特定のリソースのクリーンアップを実行する必要がない限り、おそらくオーバーライドしないでください。表示前にビューをセットアップする場所は ですonBindViewHolder()

VISIBLE次に、 RecyclerView アイテムでビューを動的に追加または削除する必要はありません。ビューの可視性を と の間で切り替えるだけの方が簡単で効率的GONEです。ビューがあまりにも異なっているためにこれでは不十分な場合は、異なるビュー タイプを宣言する必要があります。これにより、ビュー タイプViewHolderごとに個別の が作成されます。

于 2016-01-23T11:22:39.770 に答える
0

RecyclerView Adapter の onBindViewHoder() メソッドをオーバーライドしている間は、ビューを削除または追加しないでください。再利用されたレイアウトが次に使用されるときに、削除されたビューが見つからないためです。これの代わりに、ビューで表示/非表示を使用できます。

レイアウトにビューを動的に追加すると、後でこのレイアウトがリサイクルされるときに、以前に追加した余分なビューも含まれます。

同様に、レイアウトからビューを動的に削除した場合、後でこのレイアウトが再利用されるときに、以前に削除したビューは含まれません。

于 2016-09-08T05:33:52.083 に答える