Scroll to linked message: better control the final scroll position

With scrollToPosition(), the layout will only scroll such that the view
is visible *somewhere* on the screen. Defining a precise offset where to
show it is better, so the user can expect where the message will show
up.

Change-Id: Idd25a062c4be8f45ba804e442d63409f279f2a76
This commit is contained in:
SpiritCroc 2021-08-01 12:22:27 +02:00
parent 6c9c2eaef5
commit ab1fcaca62
2 changed files with 6 additions and 3 deletions

View File

@ -1178,7 +1178,7 @@ class RoomDetailFragment @Inject constructor(
}
}
val stateRestorer = LayoutManagerStateRestorer(layoutManager).register()
scrollOnNewMessageCallback = ScrollOnNewMessageCallback(layoutManager, timelineEventController)
scrollOnNewMessageCallback = ScrollOnNewMessageCallback(layoutManager, timelineEventController, views.timelineRecyclerView)
// Force scroll until the user has scrolled to address the bug where the list would jump during initial loading
scrollOnNewMessageCallback.initialForceScroll = true
scrollOnHighlightedEventCallback = ScrollOnHighlightedEventCallback(views.timelineRecyclerView, layoutManager, timelineEventController)

View File

@ -16,6 +16,7 @@
package im.vector.app.features.home.room.detail
import android.view.View
import androidx.recyclerview.widget.LinearLayoutManager
import im.vector.app.core.platform.DefaultListUpdateCallback
import im.vector.app.features.home.room.detail.timeline.TimelineEventController
@ -24,7 +25,8 @@ import org.matrix.android.sdk.api.extensions.tryOrNull
import java.util.concurrent.CopyOnWriteArrayList
class ScrollOnNewMessageCallback(private val layoutManager: LinearLayoutManager,
private val timelineEventController: TimelineEventController) : DefaultListUpdateCallback {
private val timelineEventController: TimelineEventController,
private val parentView: View) : DefaultListUpdateCallback {
private val newTimelineEventIds = CopyOnWriteArrayList<String>()
private var forceScroll = false
@ -62,7 +64,8 @@ class ScrollOnNewMessageCallback(private val layoutManager: LinearLayoutManager,
layoutManager.scrollToPositionWithOffset(0, 0)
} else {
timelineEventController.searchPositionOfEvent(scrollToEvent)?.let {
layoutManager.scrollToPosition(it)
// Scroll such that the scrolled-to event is moved up 1/4 of the screen
layoutManager.scrollToPositionWithOffset(it, parentView.measuredHeight / 4)
}
}
return