Skip to content

Instantly share code, notes, and snippets.

@Terenfear
Created August 21, 2019 13:35
Show Gist options
  • Save Terenfear/4917fca893b1e9cb15a1711e7ccf2f53 to your computer and use it in GitHub Desktop.
Save Terenfear/4917fca893b1e9cb15a1711e7ccf2f53 to your computer and use it in GitHub Desktop.
Helps to mimic the "adjustPan" behaviour for a particular layout when its parent activity has the "adjustResize" behaviour.
import android.animation.ObjectAnimator
import android.app.Activity
import android.view.View
import android.view.ViewGroup
fun ViewGroup.doOnPanRequest(f: (v: View, requestedTranslationY: Float) -> Unit) {
val initTranslationY = translationY
setOnApplyWindowInsetsListener { layout, insets ->
(this.context as? Activity)?.window?.let { w ->
w.currentFocus?.let { focusedView ->
val focusedViewY = IntArray(2).also(focusedView::getLocationInWindow)[1]
val focusedViewBottom = focusedViewY + focusedView.height
val windowHeight = w.decorView.height
val insetFromBottom = insets.systemWindowInsetBottom
val distanceFromBottomToView = windowHeight - focusedViewBottom
val deltaFromBottom = insetFromBottom - distanceFromBottomToView
val isInsetOverlappingView = insetFromBottom > distanceFromBottomToView
// if the inset isn't overlapping the view now maybe it will when we reset translationY
val translationDelta = initTranslationY - layout.translationY
val willInsetOverlapView = insetFromBottom > distanceFromBottomToView - translationDelta
val newTranslationY = if (isInsetOverlappingView || willInsetOverlapView) {
// translate the layout up when deltaFromBottom is positive (isInsetOverlappingView == true)
// or down when delta is negative (willInsetOverlapView == true)
layout.translationY - deltaFromBottom
} else {
initTranslationY
}
f(layout, newTranslationY)
}
} ?: f(layout, initTranslationY)
insets
}
viewTreeObserver.addOnGlobalFocusChangeListener { oldFocus, newFocus ->
requestApplyInsets()
}
}
fun View.animateTranslationYChange(newTranslationY: Float, duration: Long) {
ObjectAnimator.ofFloat(this, "translationY", newTranslationY).apply {
this.duration = duration
start()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment