mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-21 00:59:49 +01:00
Better insets propagation.
This commit is contained in:
@@ -3,7 +3,6 @@ package org.thoughtcrime.securesms.components
|
||||
import android.content.Context
|
||||
import android.content.res.Configuration
|
||||
import android.util.AttributeSet
|
||||
import android.view.View
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.constraintlayout.widget.Guideline
|
||||
import androidx.core.content.withStyledAttributes
|
||||
@@ -14,9 +13,7 @@ import androidx.core.view.WindowInsetsCompat
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||
import org.thoughtcrime.securesms.main.VerticalInsets
|
||||
import org.thoughtcrime.securesms.util.ViewUtil
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
/**
|
||||
* A specialized [ConstraintLayout] that sets guidelines based on the window insets provided
|
||||
@@ -62,11 +59,10 @@ open class InsetAwareConstraintLayout @JvmOverloads constructor(
|
||||
private val keyboardAnimator = KeyboardInsetAnimator()
|
||||
private var overridingKeyboard: Boolean = false
|
||||
private var previousKeyboardHeight: Int = 0
|
||||
private var applyRootInsets: Boolean = false
|
||||
private var previousStatusBarInset: Int = 0
|
||||
|
||||
private var insets: WindowInsetsCompat? = null
|
||||
private var windowTypes: Int = InsetAwareConstraintLayout.windowTypes
|
||||
private var verticalInsetOverride: VerticalInsets = VerticalInsets.Zero
|
||||
|
||||
private val windowInsetsListener = androidx.core.view.OnApplyWindowInsetsListener { _, insets ->
|
||||
this.insets = insets
|
||||
@@ -80,39 +76,25 @@ open class InsetAwareConstraintLayout @JvmOverloads constructor(
|
||||
override fun onAttachedToWindow() {
|
||||
super.onAttachedToWindow()
|
||||
|
||||
ViewCompat.setOnApplyWindowInsetsListener(insetTarget(), windowInsetsListener)
|
||||
ViewCompat.setOnApplyWindowInsetsListener(this, windowInsetsListener)
|
||||
}
|
||||
|
||||
override fun onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow()
|
||||
|
||||
ViewCompat.setOnApplyWindowInsetsListener(insetTarget(), null)
|
||||
ViewCompat.setOnApplyWindowInsetsListener(this, null)
|
||||
}
|
||||
|
||||
init {
|
||||
if (attrs != null) {
|
||||
context.withStyledAttributes(attrs, R.styleable.InsetAwareConstraintLayout) {
|
||||
applyRootInsets = getBoolean(R.styleable.InsetAwareConstraintLayout_applyRootInsets, false)
|
||||
|
||||
if (getBoolean(R.styleable.InsetAwareConstraintLayout_animateKeyboardChanges, false)) {
|
||||
ViewCompat.setWindowInsetsAnimationCallback(insetTarget(), keyboardAnimator)
|
||||
ViewCompat.setWindowInsetsAnimationCallback(this@InsetAwareConstraintLayout, keyboardAnimator)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun insetTarget(): View = if (applyRootInsets) rootView else this
|
||||
|
||||
fun setApplyRootInsets(useRootInsets: Boolean) {
|
||||
if (applyRootInsets == useRootInsets) {
|
||||
return
|
||||
}
|
||||
|
||||
ViewCompat.setOnApplyWindowInsetsListener(insetTarget(), null)
|
||||
applyRootInsets = useRootInsets
|
||||
ViewCompat.setOnApplyWindowInsetsListener(insetTarget(), windowInsetsListener)
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies whether or not window insets should be accounted for when applying
|
||||
* insets. This is useful when choosing whether to display the content in this
|
||||
@@ -130,14 +112,6 @@ open class InsetAwareConstraintLayout @JvmOverloads constructor(
|
||||
}
|
||||
}
|
||||
|
||||
fun applyInsets(insets: VerticalInsets) {
|
||||
verticalInsetOverride = insets
|
||||
|
||||
if (this.insets != null) {
|
||||
applyInsets(this.insets!!.getInsets(windowTypes), this.insets!!.getInsets(keyboardType))
|
||||
}
|
||||
}
|
||||
|
||||
fun addKeyboardStateListener(listener: KeyboardStateListener) {
|
||||
keyboardStateListeners += listener
|
||||
}
|
||||
@@ -157,18 +131,24 @@ open class InsetAwareConstraintLayout @JvmOverloads constructor(
|
||||
private fun applyInsets(windowInsets: Insets, keyboardInsets: Insets) {
|
||||
val isLtr = ViewUtil.isLtr(this)
|
||||
|
||||
val statusBar = if (verticalInsetOverride == VerticalInsets.Zero) windowInsets.top else verticalInsetOverride.statusBar.roundToInt()
|
||||
val navigationBar = if (verticalInsetOverride == VerticalInsets.Zero) windowInsets.bottom else verticalInsetOverride.navBar.roundToInt()
|
||||
val statusBar = windowInsets.top
|
||||
val navigationBar = windowInsets.bottom
|
||||
val parentStart = if (isLtr) windowInsets.left else windowInsets.right
|
||||
val parentEnd = if (isLtr) windowInsets.right else windowInsets.left
|
||||
|
||||
statusBarGuideline?.setGuidelineBegin(statusBar)
|
||||
navigationBarGuideline?.setGuidelineEnd(navigationBar)
|
||||
parentStartGuideline?.setGuidelineBegin(parentStart)
|
||||
parentEndGuideline?.setGuidelineEnd(parentEnd)
|
||||
val statusBarShrinking = previousStatusBarInset > 0 && statusBar < previousStatusBarInset
|
||||
|
||||
windowInsetsListeners.forEach {
|
||||
it.onApplyWindowInsets(statusBar, navigationBar, parentStart, parentEnd)
|
||||
if (!statusBarShrinking) {
|
||||
statusBarGuideline?.setGuidelineBegin(statusBar)
|
||||
navigationBarGuideline?.setGuidelineEnd(navigationBar)
|
||||
parentStartGuideline?.setGuidelineBegin(parentStart)
|
||||
parentEndGuideline?.setGuidelineEnd(parentEnd)
|
||||
|
||||
windowInsetsListeners.forEach {
|
||||
it.onApplyWindowInsets(statusBar, navigationBar, parentStart, parentEnd)
|
||||
}
|
||||
|
||||
previousStatusBarInset = statusBar
|
||||
}
|
||||
|
||||
if (keyboardInsets.bottom > 0) {
|
||||
|
||||
Reference in New Issue
Block a user