Skip to content

Instantly share code, notes, and snippets.

@TemMax
Last active January 7, 2021 14:59
Show Gist options
  • Save TemMax/8220982e4445462e7b76460b7f1fa6cf to your computer and use it in GitHub Desktop.
Save TemMax/8220982e4445462e7b76460b7f1fa6cf to your computer and use it in GitHub Desktop.
// ======================= WINDOW INSETS =======================
fun View.addSystemTopPadding(
targetView: View = this,
isConsumed: Boolean = false
) {
doOnApplyWindowInsets { _, insets, initialPadding ->
targetView.updatePadding(
top = initialPadding.top + insets.systemWindowInsetTop
)
if (isConsumed) {
val modified = Insets.of(
insets.systemWindowInsetLeft,
0,
insets.systemWindowInsetRight,
insets.systemWindowInsetBottom
)
WindowInsetsCompat.Builder(insets)
.setSystemWindowInsets(modified)
.build()
} else {
insets
}
}
}
fun View.addSystemBottomPadding(
targetView: View = this,
isConsumed: Boolean = false
) {
doOnApplyWindowInsets { _, insets, initialPadding ->
targetView.updatePadding(
bottom = initialPadding.bottom + insets.systemWindowInsetBottom
)
if (isConsumed) {
val modified = Insets.of(
insets.systemWindowInsetLeft,
insets.systemWindowInsetTop,
insets.systemWindowInsetRight,
0
)
WindowInsetsCompat.Builder(insets)
.setSystemWindowInsets(modified)
.build()
} else {
insets
}
}
}
fun View.doOnApplyWindowInsets(block: (View, insets: WindowInsetsCompat, initialPadding: Rect) -> WindowInsetsCompat) {
val initialPadding = recordInitialPaddingForView(this)
ViewCompat.setOnApplyWindowInsetsListener(this) { v, insets ->
block(v, insets, initialPadding)
}
requestApplyInsetsWhenAttached()
}
typealias KeyboardStateListener = (isShowed: Boolean) -> Unit
private val keyboardSize = 100.dp
/**
* @note Keyboard aware state adds navigation bar height to bottom padding when keyboard is hidden or showed too
*/
fun View.keyboardAware(
updatePaddingWithKeyboard: Boolean = true,
keyboardCallback: KeyboardStateListener = {}
) {
doOnApplyWindowInsets { _, insets, initialPadding ->
if (updatePaddingWithKeyboard) {
updatePadding(bottom = initialPadding.bottom + insets.systemWindowInsetBottom)
}
keyboardCallback(insets.systemWindowInsetBottom >= keyboardSize)
insets
}
}
private fun recordInitialPaddingForView(view: View) =
Rect(view.paddingLeft, view.paddingTop, view.paddingRight, view.paddingBottom)
private fun View.requestApplyInsetsWhenAttached() {
if (isAttachedToWindow) {
ViewCompat.requestApplyInsets(this)
} else {
addOnAttachStateChangeListener(object : View.OnAttachStateChangeListener {
override fun onViewAttachedToWindow(v: View) {
v.removeOnAttachStateChangeListener(this)
ViewCompat.requestApplyInsets(v)
}
override fun onViewDetachedFromWindow(v: View) = Unit
})
}
}
// ======================= WINDOW INSETS =======================
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment