RecyclerПросмотр неправильного изменения изображения onNotifyItemChanged - PullRequest
0 голосов
/ 25 июня 2018

У меня есть эта проблема, с recyclerView. Можете ли вы проверить два снимка экрана ниже:

enter image description here

enter image description here

Так что это моя проблема, когда onNotifyItemChange запускается, другая информация изменяется, неверно. Теперь вот мой адаптер:

class TimelineAdapter(var timeline: TimelineDTO,
                      var toggleLikeClicked: OnRowClick,
                      var onCommentClicked: OnRowClick,
                      var onMediaClick: OnRowClick,
                      val onUserClicked: OnRowClick,

                      val reportPost: OnRowClick,
                      val editPost  : OnRowClick,
                      val deletePost: OnRowClick,

                      val contract: TimelineViewContract) : BaseAdapter<RecyclerView.ViewHolder>() {


    init {
        setHasStableIds(true)
    }

    private var currentItem: Int = 0

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        when (PostType.fromInt(viewType)) {
            PostType.BASIC -> {
                return PostViewHolder(parent.inflate(R.layout.row_post_default_item),
                                                    toggleLikeClicked, onCommentClicked, onMediaClick,
                                                    onUserClicked, reportPost,
                                                    editPost,
                                                    deletePost,
                                                    FirebaseAnalytics.getInstance(contract.returnContext()))
            }
            PostType.NEXT_TALKS -> {
                return PostNextTalksViewHolder(parent.inflate(R.layout.row_post_next_talks_item),
                                                    contract)
            }
            else -> {
                if(!BuildConfig.DEBUG) {
                    Crashlytics.log("Should not come here")
                }
                logE("adapter else!!")
                return PostViewHolder(parent.inflate(R.layout.row_post_default_item),
                                            toggleLikeClicked, onCommentClicked, onMediaClick,
                                            onUserClicked, reportPost,
                                            editPost,
                                            deletePost,
                                            FirebaseAnalytics.getInstance(contract.returnContext()))
            }
        }
    }

    override fun getItemCount(): Int {
        var count = timeline.posts.size
        if(hasValue(timeline.nextTalks.size)){
            count++
        }
        return count
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        currentItem = position
        val alignedPositon = getAlignedPosition(position)

        when (holder) {
            is PostViewHolder -> holder.bind(timeline.posts[alignedPositon])

            is PostNextTalksViewHolder -> {
                holder.bind(timeline.nextTalks)
            }
            is PostCarousselViewHolder -> {
                holder.bind(ArrayList<String>())
            }
        }
    }

    fun getPostAt(position: Int): PostDTO {
        val post: PostDTO
        val alignedPositon = getAlignedPosition(position)
        post = timeline.posts[alignedPositon]

        return post
    }

    override fun getItemId(position: Int): Long {
        val aligned = getAlignedPosition(position)

        return aligned.toLong()
    }

    private fun getAlignedPosition(position: Int): Int {
        var alignedPositon = position

        if (hasValue(timeline.nextTalks.size)){
            alignedPositon--
        }

        return alignedPositon
    }

    override fun getItemViewType(position: Int): Int {
        val hasPinned = timeline.posts.any { it.postType == PostType.PINNED.id }

        if(hasPinned) {
            if(position == 1 && timeline.nextTalks.any()){
                return PostType.NEXT_TALKS.id
            }
        }
        else {
            if(position == 0 && timeline.nextTalks.any()){
                return PostType.NEXT_TALKS.id
            }
        }

        return timeline.posts[getAlignedPosition(position)].postType

    }

    fun updateItemAt(postLocal: PostLocal, commentIndexPost: Int) {
        timeline.posts.removeAt(commentIndexPost)
        timeline.posts.add(commentIndexPost, PostDTO(postLocal))
        notifyItemChanged(commentIndexPost)
    }

    fun addItems(newPosts: TimelineDTO) {
        timeline.posts.addAll(newPosts.posts)
        timeline.nextTalks.addAll(newPosts.nextTalks)

        notifyItemRangeInserted(itemCount, newPosts.posts.size)
    }

    fun resetItems(nextPosts: TimelineDTO) {
        timeline.posts.clear()
        timeline.nextTalks.clear()

        timeline.posts.addAll(nextPosts.posts)
        timeline.nextTalks.addAll(nextPosts.nextTalks)

        notifyDataSetChanged()
    }

    fun removeAt(position: Int) {
        timeline.posts.removeAt(position)
        notifyItemRemoved(position)
        notifyItemRangeChanged(position, timeline.posts.size)
    }
}

1 Ответ

0 голосов
/ 25 июня 2018

Использование notifyItemChanged() может вызвать эффект «исчезновения и исчезновения», который не обязательно желателен (если только вы не используете стабильные идентификаторы или убитую анимацию изменения в аниматоре).

Если вы знаете, что было изменено в элементе, лучше использовать полезную нагрузку обновления ( см. пример здесь ), чтобы частично обновить ваши ViewHolders, не вызывая полное повторное связывание.

В противном случае, если список относительно мал и вы не знаете, что изменилось, вы также можете использовать DiffUtil для создания списка изменений / полезных нагрузок "полуавтоматически".

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...