From 1d3c191153d72d48a4a304b42a1fe1911b95170b Mon Sep 17 00:00:00 2001 From: Nikita Fedrunov <66663241+fedrunov@users.noreply.github.com> Date: Wed, 14 Sep 2022 22:55:01 +0200 Subject: [PATCH] scroll recents carouse to start when item added/moved to start (#7120) --- changelog.d/6776.bugfix | 1 + .../home/header/HomeRoomsHeadersController.kt | 39 +++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 changelog.d/6776.bugfix diff --git a/changelog.d/6776.bugfix b/changelog.d/6776.bugfix new file mode 100644 index 0000000000..ceb1d52ebf --- /dev/null +++ b/changelog.d/6776.bugfix @@ -0,0 +1 @@ +[App Layout] Recents carousel now scrolled to first position when new item added to or moved to this position diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/home/header/HomeRoomsHeadersController.kt b/vector/src/main/java/im/vector/app/features/home/room/list/home/header/HomeRoomsHeadersController.kt index 8be9bf12f9..f7c9eccd0b 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/home/header/HomeRoomsHeadersController.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/home/header/HomeRoomsHeadersController.kt @@ -18,6 +18,7 @@ package im.vector.app.features.home.room.list.home.header import android.content.res.Resources import android.util.TypedValue +import androidx.recyclerview.widget.RecyclerView import com.airbnb.epoxy.Carousel import com.airbnb.epoxy.CarouselModelBuilder import com.airbnb.epoxy.EpoxyController @@ -44,6 +45,25 @@ class HomeRoomsHeadersController @Inject constructor( var recentsRoomListener: RoomListListener? = null var invitesClickListener: (() -> Unit)? = null + private var carousel: Carousel? = null + + private val carouselAdapterObserver = object : RecyclerView.AdapterDataObserver() { + override fun onItemRangeMoved(fromPosition: Int, toPosition: Int, itemCount: Int) { + if (toPosition == 0 || fromPosition == 0) { + carousel?.post { + carousel?.layoutManager?.scrollToPosition(0) + } + } + super.onItemRangeMoved(fromPosition, toPosition, itemCount) + } + + override fun onItemRangeInserted(positionStart: Int, itemCount: Int) { + if (positionStart == 0) { + carousel?.layoutManager?.scrollToPosition(0) + } + } + } + private val recentsHPadding = TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, 4f, @@ -92,9 +112,28 @@ class HomeRoomsHeadersController @Inject constructor( ) ) onBind { _, view, _ -> + host.carousel = view + val colorSurface = MaterialColors.getColor(view, R.attr.vctr_toolbar_background) view.setBackgroundColor(colorSurface) + + try { + view.adapter?.registerAdapterDataObserver(host.carouselAdapterObserver) + } catch (e: IllegalStateException) { + // do nothing + } } + + onUnbind { _, view -> + host.carousel = null + + try { + view.adapter?.unregisterAdapterDataObserver(host.carouselAdapterObserver) + } catch (e: IllegalStateException) { + // do nothing + } + } + withModelsFrom(recents) { roomSummary -> val onClick = host.recentsRoomListener?.let { it::onRoomClicked } val onLongClick = host.recentsRoomListener?.let { it::onRoomLongClicked }