Hide floating date above unread messages line

Change-Id: I44b00d41a77c0fe0fd08126502430723541dc7ae
This commit is contained in:
SpiritCroc 2022-05-14 12:20:44 +02:00
parent 3201c629c4
commit cc96b2e198
2 changed files with 32 additions and 19 deletions

View File

@ -15,6 +15,7 @@ import android.view.ViewGroup
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.airbnb.epoxy.EpoxyController import com.airbnb.epoxy.EpoxyController
import com.airbnb.epoxy.EpoxyModel
import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.extensions.orFalse
abstract class StickyHeaderItemDecoration( abstract class StickyHeaderItemDecoration(
@ -47,20 +48,29 @@ abstract class StickyHeaderItemDecoration(
val currentHeader = getHeaderViewForItem(headerPos, parent) val currentHeader = getHeaderViewForItem(headerPos, parent)
fixLayoutSize(parent, currentHeader) fixLayoutSize(parent, currentHeader)
val contactPoint = currentHeader.bottom val contactPoint = currentHeader.bottom
val childInContact = getChildInContact(parent, contactPoint, headerPos)
if (childInContact != null && isHeader(parent.getChildAdapterPosition(childInContact))) { val childInContact = getChildInContact(parent, contactPoint, headerPos)
updateOverlaidHeaders(parent, headerPos) val childBelow = getChildInContact(parent, currentHeader.top, headerPos)
moveHeader(c, currentHeader, childInContact) val childInContactModel = childInContact?.let { epoxyController.adapter.getModelAtPosition(parent.getChildAdapterPosition(childInContact)) }
return val childBelowModel = childBelow?.let { epoxyController.adapter.getModelAtPosition(parent.getChildAdapterPosition(childBelow)) }
if (childInContact != null) {
if (isHeader(childInContactModel)) {
updateOverlaidHeaders(parent, headerPos)
moveHeader(c, currentHeader, childInContact)
return
}
if (preventOverlay(childInContactModel) || preventOverlay(childBelowModel)) {
// Hide header temporarily
return
}
} }
// Un-hide views early, so we don't get flashing headers while scrolling // Un-hide views early, so we don't get flashing headers while scrolling
val childBellow = getChildInContact(parent, currentHeader.top, headerPos) val overlaidHeaderPos: Int? = if (childBelow != childInContact &&
val overlaidHeaderPos: Int? = if (childBellow != childInContact && childBelow != null &&
childBellow != null && isHeader(childBelowModel) &&
isHeader(parent.getChildAdapterPosition(childBellow)) && contactPoint - childBelow.bottom < (childBelow.bottom - childBelow.top)/8
contactPoint - childBellow.bottom < (childBellow.bottom - childBellow.top)/8
) { ) {
null null
} else { } else {
@ -126,7 +136,9 @@ abstract class StickyHeaderItemDecoration(
c.restore() c.restore()
} }
abstract fun isHeader(itemPosition: Int): Boolean abstract fun isHeader(model: EpoxyModel<*>?): Boolean
open fun preventOverlay(model: EpoxyModel<*>?): Boolean = false
private fun getChildInContact(parent: RecyclerView, contactPoint: Int, currentHeaderPos: Int): View? { private fun getChildInContact(parent: RecyclerView, contactPoint: Int, currentHeaderPos: Int): View? {
var childInContact: View? = null var childInContact: View? = null
@ -136,7 +148,7 @@ abstract class StickyHeaderItemDecoration(
//measure height tolerance with child if child is another header //measure height tolerance with child if child is another header
if (currentHeaderPos != i) { if (currentHeaderPos != i) {
val isChildHeader = isHeader(parent.getChildAdapterPosition(child)) val isChildHeader = isHeader(epoxyController.adapter.getModelAtPosition(parent.getChildAdapterPosition(child)))
if (isChildHeader) { if (isChildHeader) {
heightTolerance = mStickyHeaderHeight - child.height heightTolerance = mStickyHeaderHeight - child.height
} }
@ -172,7 +184,7 @@ abstract class StickyHeaderItemDecoration(
var headerPosition = RecyclerView.NO_POSITION var headerPosition = RecyclerView.NO_POSITION
val directionAdd = if (reverse) 1 else -1 val directionAdd = if (reverse) 1 else -1
do { do {
if (isHeader(tempPosition)) { if (isHeader(epoxyController.adapter.getModelAtPosition(tempPosition))) {
headerPosition = tempPosition headerPosition = tempPosition
break break
} }

View File

@ -179,6 +179,7 @@ import im.vector.app.features.home.room.detail.timeline.item.MessageInformationD
import im.vector.app.features.home.room.detail.timeline.item.MessageTextItem import im.vector.app.features.home.room.detail.timeline.item.MessageTextItem
import im.vector.app.features.home.room.detail.timeline.item.MessageVoiceItem import im.vector.app.features.home.room.detail.timeline.item.MessageVoiceItem
import im.vector.app.features.home.room.detail.timeline.item.ReadReceiptData import im.vector.app.features.home.room.detail.timeline.item.ReadReceiptData
import im.vector.app.features.home.room.detail.timeline.item.TimelineReadMarkerItem
import im.vector.app.features.home.room.detail.timeline.reactions.ViewReactionsBottomSheet import im.vector.app.features.home.room.detail.timeline.reactions.ViewReactionsBottomSheet
import im.vector.app.features.home.room.detail.timeline.url.PreviewUrlRetriever import im.vector.app.features.home.room.detail.timeline.url.PreviewUrlRetriever
import im.vector.app.features.home.room.detail.upgrade.MigrateRoomBottomSheet import im.vector.app.features.home.room.detail.upgrade.MigrateRoomBottomSheet
@ -1486,12 +1487,12 @@ class TimelineFragment @Inject constructor(
if (vectorPreferences.floatingDate()) { if (vectorPreferences.floatingDate()) {
views.timelineRecyclerView.addItemDecoration( views.timelineRecyclerView.addItemDecoration(
object : StickyHeaderItemDecoration(timelineEventController, reverse = true) { object : StickyHeaderItemDecoration(timelineEventController, reverse = true) {
override fun isHeader(itemPosition: Int): Boolean { override fun isHeader(model: EpoxyModel<*>?): Boolean {
if (itemPosition != RecyclerView.NO_POSITION) { return model is DaySeparatorItem
val model = timelineEventController.adapter.getModelAtPosition(itemPosition) }
return model is DaySeparatorItem
} override fun preventOverlay(model: EpoxyModel<*>?): Boolean {
return false return model is TimelineReadMarkerItem
} }
override fun getHeaderViewForItem(headerPosition: Int, parent: RecyclerView): View { override fun getHeaderViewForItem(headerPosition: Int, parent: RecyclerView): View {