Во фрагменте есть EditText для выполнения поиска и RecyclerView для отображения результатов. Первоначальное заполнение RecyclerView данными работает нормально, но после первого взаимодействия с EditText при вводе данных и отображении Soft Keyboard RecyclerView перестает обновлять данные визуально.
Методы адаптера notifyDataSetChanged() notifyItemRangeRemoved() не обновляют RecyclerView визуально, а использование DiffUtil не решает проблему. Адаптер получает новые данные, но визуально RecyclerView не обновляется , если вы не прокрутите их вручную.
У вас есть идеи или подсказки, почему это может произойти? Любая помощь приветствуется.

Код макета:

<?xml version="1.0" encoding="utf-8"?>

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/colorPrimary">

    <FrameLayout
        android:id="@+id/fl_search"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/colorPrimaryDark"
        android:padding="@dimen/10dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <EditText
            android:id="@+id/et_search"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
    </FrameLayout>

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rv_results"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:clipToPadding="false"
        android:orientation="vertical"
        android:overScrollMode="never"
        android:padding="@dimen/default_padding"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/fl_search" />

</androidx.constraintlayout.widget.ConstraintLayout>

Код фрагмента:

...
        adapter = MyRecyclerViewAdapter( object : MyRVClickListener {
                override fun onItemClicked(
                    position: Int,
                    myDAO: MyDAO
                ) {
                  //  My click action                    
                }
            }
        )

        resultListRV = view.rv_results
        layoutManager =
            LinearLayoutManager(activity!!)

        resultListRV?.layoutManager = layoutManager!!

        val divider = DividerItemDecoration(
            resultListRV?.context,
            DividerItemDecoration.VERTICAL
        )

        divider.setDrawable(
            ContextCompat.getDrawable(appContext, R.drawable.divider_hor)!!
        )

        resultListRV?.addItemDecoration(divider)
        resultListRV?.adapter = adapter

        myViewModel.dataList.observe(viewLifecycleOwner, Observer {
            adapter.submitList(it)
        })
...

Код адаптера:

class MyRecyclerViewAdapter(
    val listener: MyRVClickListener
) : ListAdapter<MyDAO, RecyclerView.ViewHolder>(DiffCallback) {

    companion object DiffCallback : DiffUtil.ItemCallback<MyDAO>() {
        override fun areItemsTheSame(
            oldItem: MyDAO,
            newItem: MyDAO
        ): Boolean {
            return oldItem === newItem
        }

        override fun areContentsTheSame(
            oldItem: MyDAO,
            newItem: MyDAO
        ): Boolean {
            return oldItem.id== newItem.id
        }
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        val item = getItem(position)
        (holder as SearchItemVH).bind(item, position)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        return SearchItemVH(
            LayoutInflater.from(parent.context).inflate(
                R.layout.search_list_item,
                parent,
                false
            )
        )
    }

    inner class SearchItemVH(itemView: View) : RecyclerView.ViewHolder(itemView) {
        var title: TextView = itemView.list_item_tv_title

        fun bind(listItem: MyDAO, position: Int) {
            title.text = listItem.details.description
            itemView.setOnClickListener { listener.onItemClicked(position, listItem) }
        }
    }
}
0
Sergii Litvinenko 15 Апр 2020 в 16:21

1 ответ

Лучший ответ

После некоторых экспериментов я нашел обходной путь: recycler.smoothScrollBy(1, 1) успешно обновляет ресайклер после изменений. До сих пор не известна первопричина этой проблемы, надеюсь, это решение поможет, если кто-то столкнется с этой проблемой.

1
Sergii Litvinenko 4 Май 2020 в 11:21