Fix wacky layout while scrolling in thread.

This commit is contained in:
Alex Hart
2023-10-11 14:52:30 -03:00
parent d2d000ef16
commit 985b569d29
2 changed files with 68 additions and 2 deletions

View File

@@ -0,0 +1,65 @@
/*
* Copyright 2023 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
package org.thoughtcrime.securesms.components
import android.animation.LayoutTransition
import android.view.View
import android.view.View.OnAttachStateChangeListener
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
/**
* Helps manage layout transition state inside a RecyclerView.
*
* Because of how RecyclerViews scroll, we need to be very careful about LayoutTransition
* usage inside of them. This class helps wrap up the pattern of finding and listening to
* the scroll events of a parent recycler view, so that we don't need to manually wire
* the scroll state in everywhere.
*/
class RecyclerViewParentTransitionController(
private val child: ViewGroup,
private val transition: LayoutTransition = LayoutTransition()
) : RecyclerView.OnScrollListener(), OnAttachStateChangeListener {
private var recyclerViewParent: RecyclerView? = null
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
child.layoutTransition = transition
} else {
child.layoutTransition = null
}
}
override fun onViewAttachedToWindow(v: View) {
val parent = findRecyclerParent()
if (parent != null) {
onScrollStateChanged(parent, parent.scrollState)
}
parent?.addOnScrollListener(this)
recyclerViewParent = parent
}
override fun onViewDetachedFromWindow(v: View) {
recyclerViewParent?.removeOnScrollListener(this)
child.layoutTransition = null
}
private fun findRecyclerParent(): RecyclerView? {
var target: ViewGroup? = child.parent as? ViewGroup
while (target != null) {
if (target is RecyclerView) {
return target
}
target = target.parent as? ViewGroup
}
return null
}
}

View File

@@ -4,7 +4,6 @@
*/
package org.thoughtcrime.securesms.components.transfercontrols
import android.animation.LayoutTransition
import android.annotation.SuppressLint
import android.content.Context
import android.os.Build
@@ -23,6 +22,7 @@ import org.greenrobot.eventbus.ThreadMode
import org.signal.core.util.logging.Log
import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.attachments.Attachment
import org.thoughtcrime.securesms.components.RecyclerViewParentTransitionController
import org.thoughtcrime.securesms.database.AttachmentTable
import org.thoughtcrime.securesms.databinding.TransferControlsViewBinding
import org.thoughtcrime.securesms.events.PartProgressEvent
@@ -45,10 +45,11 @@ class TransferControlView @JvmOverloads constructor(context: Context, attrs: Att
binding = TransferControlsViewBinding.inflate(LayoutInflater.from(context), this)
visibility = GONE
isLongClickable = false
layoutTransition = LayoutTransition()
disposables += store.stateFlowable.distinctUntilChanged().observeOn(AndroidSchedulers.mainThread()).subscribe {
applyState(it)
}
addOnAttachStateChangeListener(RecyclerViewParentTransitionController(child = this))
}
override fun onAttachedToWindow() {