Skip to content
This repository has been archived by the owner on Sep 30, 2024. It is now read-only.

Commit

Permalink
Support using getInsetsIgnoringVisibility (#121)
Browse files Browse the repository at this point in the history
  • Loading branch information
ivaniskandar authored Oct 13, 2021
1 parent ebdee25 commit 85f2f0c
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 17 deletions.
4 changes: 3 additions & 1 deletion library/api/library.api
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ public final class dev/chrisbanes/insetter/Insetter {
public static final field CONSUME_AUTO I
public static final field CONSUME_NONE I
public static final field Companion Ldev/chrisbanes/insetter/Insetter$Companion;
public synthetic fun <init> (Ldev/chrisbanes/insetter/SideApply;Ldev/chrisbanes/insetter/SideApply;Ldev/chrisbanes/insetter/OnApplyInsetsListener;IILjava/util/List;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
public synthetic fun <init> (Ldev/chrisbanes/insetter/SideApply;Ldev/chrisbanes/insetter/SideApply;Ldev/chrisbanes/insetter/OnApplyInsetsListener;IILjava/util/List;ZLkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun applyInsetsToView (Landroid/view/View;Landroidx/core/view/WindowInsetsCompat;Ldev/chrisbanes/insetter/ViewState;)V
public final fun applyToView (Landroid/view/View;)V
public static final fun builder ()Ldev/chrisbanes/insetter/Insetter$Builder;
Expand All @@ -13,6 +13,7 @@ public final class dev/chrisbanes/insetter/Insetter$Builder {
public final fun applyToView (Landroid/view/View;)Ldev/chrisbanes/insetter/Insetter;
public final fun build ()Ldev/chrisbanes/insetter/Insetter;
public final fun consume (I)Ldev/chrisbanes/insetter/Insetter$Builder;
public final fun ignoreVisibility (Z)Ldev/chrisbanes/insetter/Insetter$Builder;
public final fun margin (I)Ldev/chrisbanes/insetter/Insetter$Builder;
public final fun margin (II)Ldev/chrisbanes/insetter/Insetter$Builder;
public final fun margin (IIZ)Ldev/chrisbanes/insetter/Insetter$Builder;
Expand Down Expand Up @@ -62,6 +63,7 @@ public final class dev/chrisbanes/insetter/InsetterApplyTypeDsl {
public final class dev/chrisbanes/insetter/InsetterDsl {
public final fun consume (I)V
public final fun consume (Z)V
public final fun ignoreVisibility (Z)V
public final fun syncTranslationTo ([Landroid/view/View;)V
public final fun type (ILkotlin/jvm/functions/Function1;)V
public final fun type (ZZZZZZZZLkotlin/jvm/functions/Function1;)V
Expand Down
71 changes: 55 additions & 16 deletions library/src/main/java/dev/chrisbanes/insetter/Insetter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ class Insetter private constructor(
@ConsumeOptions private val consume: Int,
private val animatingTypes: Int,
private val animateSyncViews: List<View>,
private val ignoreVisibility: Boolean,
) {
@IntDef(value = [CONSUME_NONE, CONSUME_ALL, CONSUME_AUTO])
@Retention(AnnotationRetention.SOURCE)
Expand Down Expand Up @@ -92,6 +93,8 @@ class Insetter private constructor(

private var consume = CONSUME_NONE

private var ignoreVisibility = false

private var animatingTypes = 0
private var animateSyncViews = ArrayList<View>()

Expand Down Expand Up @@ -318,6 +321,15 @@ class Insetter private constructor(
return this
}

/**
* @param ignoreVisibility true to return the insets regardless of whether the given type is
* currently visible or not.
*/
fun ignoreVisibility(ignoreVisibility: Boolean): Builder {
this.ignoreVisibility = ignoreVisibility
return this
}

/**
* Builds the [Insetter] instance and sets it as an
* [OnApplyWindowInsetsListener][androidx.core.view.OnApplyWindowInsetsListener] on
Expand All @@ -341,6 +353,7 @@ class Insetter private constructor(
animatingTypes = animatingTypes,
animateSyncViews = animateSyncViews,
consume = consume,
ignoreVisibility = ignoreVisibility,
)
}

Expand Down Expand Up @@ -382,11 +395,11 @@ class Insetter private constructor(
CONSUME_ALL -> WindowInsetsCompat.CONSUMED
CONSUME_AUTO -> {
WindowInsetsCompat.Builder(insets)
.consumeType(Type.statusBars(), insets, persistentTypes)
.consumeType(Type.navigationBars(), insets, persistentTypes)
.consumeType(Type.ime(), insets, persistentTypes)
.consumeType(Type.systemGestures(), insets, persistentTypes)
.consumeType(Type.displayCutout(), insets, persistentTypes)
.consumeType(Type.statusBars(), insets, persistentTypes, ignoreVisibility)
.consumeType(Type.navigationBars(), insets, persistentTypes, ignoreVisibility)
.consumeType(Type.ime(), insets, persistentTypes, ignoreVisibility)
.consumeType(Type.systemGestures(), insets, persistentTypes, ignoreVisibility)
.consumeType(Type.displayCutout(), insets, persistentTypes, ignoreVisibility)
.build()
}
else -> insets
Expand Down Expand Up @@ -505,12 +518,14 @@ class Insetter private constructor(
view.applyPadding(
insets = insets,
typesToApply = paddingTypes - currentlyDeferredTypes,
initialPaddings = initialState.paddings
initialPaddings = initialState.paddings,
ignoreVisibility = ignoreVisibility
)
view.applyMargins(
insets = insets,
typesToApply = marginTypes - currentlyDeferredTypes,
initialMargins = initialState.margins
initialMargins = initialState.margins,
ignoreVisibility = ignoreVisibility
)
}

Expand Down Expand Up @@ -620,25 +635,26 @@ private fun View.applyPadding(
insets: WindowInsetsCompat,
typesToApply: SideApply,
initialPaddings: ViewDimensions,
ignoreVisibility: Boolean,
) {
// If there's no types to apply, nothing to do...
if (typesToApply.isEmpty) return

val paddingLeft = when (typesToApply.left) {
Side.NONE -> paddingLeft
else -> initialPaddings.left + insets.getInsets(typesToApply.left).left
else -> initialPaddings.left + insets.getInsets(typesToApply.left, ignoreVisibility).left
}
val paddingTop = when (typesToApply.top) {
Side.NONE -> paddingTop
else -> initialPaddings.top + insets.getInsets(typesToApply.top).top
else -> initialPaddings.top + insets.getInsets(typesToApply.top, ignoreVisibility).top
}
val paddingRight = when (typesToApply.right) {
Side.NONE -> paddingRight
else -> initialPaddings.right + insets.getInsets(typesToApply.right).right
else -> initialPaddings.right + insets.getInsets(typesToApply.right, ignoreVisibility).right
}
val paddingBottom = when (typesToApply.bottom) {
Side.NONE -> paddingBottom
else -> initialPaddings.bottom + insets.getInsets(typesToApply.bottom).bottom
else -> initialPaddings.bottom + insets.getInsets(typesToApply.bottom, ignoreVisibility).bottom
}

// setPadding() does it's own value change check, so no need to do our own to avoid layout
Expand All @@ -655,6 +671,7 @@ private fun View.applyMargins(
insets: WindowInsetsCompat,
typesToApply: SideApply,
initialMargins: ViewDimensions,
ignoreVisibility: Boolean,
) {
// If there's no types to apply, nothing to do...
if (typesToApply.isEmpty) return
Expand All @@ -667,19 +684,19 @@ private fun View.applyMargins(

val marginLeft = when (typesToApply.left) {
Side.NONE -> lp.leftMargin
else -> initialMargins.left + insets.getInsets(typesToApply.left).left
else -> initialMargins.left + insets.getInsets(typesToApply.left, ignoreVisibility).left
}
val marginTop = when (typesToApply.top) {
Side.NONE -> lp.topMargin
else -> initialMargins.top + insets.getInsets(typesToApply.top).top
else -> initialMargins.top + insets.getInsets(typesToApply.top, ignoreVisibility).top
}
val marginRight = when (typesToApply.right) {
Side.NONE -> lp.rightMargin
else -> initialMargins.right + insets.getInsets(typesToApply.right).right
else -> initialMargins.right + insets.getInsets(typesToApply.right, ignoreVisibility).right
}
val marginBottom = when (typesToApply.bottom) {
Side.NONE -> lp.bottomMargin
else -> initialMargins.bottom + insets.getInsets(typesToApply.bottom).bottom
else -> initialMargins.bottom + insets.getInsets(typesToApply.bottom, ignoreVisibility).bottom
}

// Update the layoutParams margins. Will return true if any value has changed
Expand Down Expand Up @@ -724,12 +741,13 @@ private fun WindowInsetsCompat.Builder.consumeType(
type: Int,
windowInsets: WindowInsetsCompat,
applied: SideApply,
ignoreVisibility: Boolean,
): WindowInsetsCompat.Builder {
// Fast path. If this type wasn't applied at all, no need to do anything
if (applied.all and type != type) return this

// First we get the original insets for the type
val insets = windowInsets.getInsets(type)
val insets = windowInsets.getInsets(type, ignoreVisibility)

// If the insets are empty, nothing to do
if (insets == Insets.NONE) return this
Expand All @@ -746,3 +764,24 @@ private fun WindowInsetsCompat.Builder.consumeType(
)
return this
}

/**
* Returns the insets of a specific set of windows causing insets, denoted by the
* [typeMask] bit mask of [Type]s.
*
* @param typeMask Bit mask of [Type]s to query the insets for.
* @param ignoreVisibility True to return the insets regardless of whether that type is currently
* visible or not.
* @see WindowInsetsCompat.getInsets
* @see WindowInsetsCompat.getInsetsIgnoringVisibility
*/
private fun WindowInsetsCompat.getInsets(
@Type.InsetsType typeMask: Int,
ignoreVisibility: Boolean
): Insets {
return if (ignoreVisibility) {
getInsetsIgnoringVisibility(typeMask)
} else {
getInsets(typeMask)
}
}
9 changes: 9 additions & 0 deletions library/src/main/java/dev/chrisbanes/insetter/InsetterDsl.kt
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,15 @@ class InsetterDsl internal constructor() {
builder = builder.consume(consume)
}

/**
* @param ignoreVisibility true to return the insets regardless of whether the given type is
* currently visible or not.
* @see Insetter.Builder.ignoreVisibility
*/
fun ignoreVisibility(ignoreVisibility: Boolean) {
builder = builder.ignoreVisibility(ignoreVisibility)
}

/**
* When reacting to window insets animations it is often useful to apply the same
* animated translation X and Y to other views. The views provided to this function
Expand Down

0 comments on commit 85f2f0c

Please sign in to comment.