Skip to content

Commit

Permalink
Handle resizes when system animations are disabled
Browse files Browse the repository at this point in the history
  • Loading branch information
Nain57 committed Sep 28, 2024
1 parent 7989e2e commit 96dbb20
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ import android.widget.ImageButton
import androidx.annotation.CallSuper
import androidx.annotation.IdRes
import androidx.annotation.StyleRes
import androidx.core.view.children
import androidx.core.view.forEach
import androidx.lifecycle.Lifecycle

Expand Down Expand Up @@ -215,7 +214,7 @@ abstract class OverlayMenu(
backgroundViewGroup = menuBackground,
resizedContainer = buttonsContainer,
maximumSize = getWindowMaximumSize(menuBackground),
windowSizeListener = { size -> onNewWindowSize(size.width, size.height) }
windowResizer = ::onNewWindowSize,
)

// Add the overlay, if any. It needs to be below the menu or user won't be able to click on the menu.
Expand Down Expand Up @@ -475,25 +474,16 @@ abstract class OverlayMenu(
}

private fun forceWindowResize() {
buttonsContainer.measure(MeasureSpec.EXACTLY, MeasureSpec.EXACTLY)

// Get the height of all children + the padding
val height = buttonsContainer.children.fold(0) { acc, child ->
acc + (if (child.visibility == View.GONE) 0 else child.height)
} + buttonsContainer.paddingTop + buttonsContainer.paddingBottom

onNewWindowSize(
width = menuLayout.width,
height = height,
)
Log.d(TAG, "Force window resize")
onNewWindowSize(resizeController.measureMenuSize())
}

private fun onNewWindowSize(width: Int, height: Int) {
menuLayoutParams.width = width
menuLayoutParams.height = height
private fun onNewWindowSize(size: Size) {
menuLayoutParams.width = size.width
menuLayoutParams.height = size.height

if (lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)) {
Log.d(TAG, "Updating menu window size: $width/$height")
Log.d(TAG, "Updating menu window size: ${size.width}/${size.height}")
windowManager.updateViewLayout(menuLayout, menuLayoutParams)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ import android.animation.LayoutTransition
import android.util.Log
import android.util.Size
import android.view.View
import android.view.View.MeasureSpec
import android.view.ViewGroup
import androidx.core.view.children

/**
* Controls the resize of an overlay window.
Expand All @@ -37,13 +39,13 @@ import android.view.ViewGroup
* @param backgroundViewGroup the view displaying the background of the overlay
* @param resizedContainer the view originally resized and that triggers the window resizing.
* @param maximumSize the maximum width and height the window can have between all its states.
* @param windowSizeListener called when the window needs to be resized.
* @param windowResizer called when the window needs to be resized.
*/
internal class OverlayMenuResizeController(
private val backgroundViewGroup: ViewGroup,
private val resizedContainer: ViewGroup,
private val maximumSize: Size,
private val windowSizeListener: (size: Size) -> Unit,
private val windowResizer: (size: Size) -> Unit,
) {

/** True if the window resize animation is running, false if not. */
Expand All @@ -63,6 +65,7 @@ internal class OverlayMenuResizeController(
) {
if (view == null) return

Log.d(TAG, "Layout changes animations start for ${view.id}")
runningTransitions.add(OverlayTransition(view.id, transitionType))
}

Expand All @@ -74,12 +77,15 @@ internal class OverlayMenuResizeController(
) {
if (view == null) return

Log.d(TAG, "Layout changes animations complete for ${view.id}")
runningTransitions.remove(OverlayTransition(view.id, transitionType))

if (runningTransitions.isEmpty()) {
Log.d(TAG, "Layout changes animations completed")
Log.d(TAG, "All layout changes animations completed")

// The view resize animation is over, restore the window size to wrap the content.
windowSizeListener(Size(backgroundViewGroup.measuredWidth, backgroundViewGroup.measuredHeight))
windowResizer(measureMenuSize())

isAnimating = false
}
}
Expand All @@ -104,7 +110,7 @@ internal class OverlayMenuResizeController(
Log.d(TAG, "Starting layout changes animations")

// Freeze window size to expanded size
windowSizeListener(maximumSize)
windowResizer(maximumSize)

// Execute layout changes that will cause a resize
layoutChanges()
Expand All @@ -114,6 +120,27 @@ internal class OverlayMenuResizeController(
fun release() {
resizedContainer.layoutTransition?.removeTransitionListener(transitionListener)
}

fun measureMenuSize(): Size {
resizedContainer.measure(MeasureSpec.EXACTLY, MeasureSpec.EXACTLY)

// Get the height of all children + the padding
val height = resizedContainer.children.fold(0) { acc, child ->
acc + (if (child.visibility == View.GONE) 0 else child.height)
} + resizedContainer.paddingTop + resizedContainer.paddingBottom

val firstChild = (backgroundViewGroup.getChildAt(0) as? ViewGroup)
val width = if (firstChild == null || firstChild.id == resizedContainer.id) {
resizedContainer.width
} else {
// Case for the view with debug layout
firstChild.children.fold(0) { acc, child ->
acc + (if (child.visibility == View.GONE) 0 else child.width)
}
}

return Size(width, height)
}
}

private data class OverlayTransition(
Expand Down

0 comments on commit 96dbb20

Please sign in to comment.