android / user-interface-samples

Multiple samples showing the best practices in the user interface on Android.
Apache License 2.0
4.44k stars 1.65k forks source link

WindowInsetsAnimation Compatibility issues #329

Closed erleizh closed 2 years ago

erleizh commented 2 years ago

https://user-images.githubusercontent.com/15859155/153391289-8767f5c4-401f-401e-83e9-b0497a863e2b.mp4

device-2022-02-10-183228

    override fun onProgress(
        insets: WindowInsetsCompat,
        runningAnimations: List<WindowInsetsAnimationCompat>
    ): WindowInsetsCompat {
        // onProgress() is called when any of the running animations progress...

        // First we get the insets which are potentially deferred
        val typesInset = insets.getInsets(deferredInsetTypes)
        // Then we get the persistent inset types which are applied as padding during layout
        val otherInset = insets.getInsets(persistentInsetTypes)

        // Now that we subtract the two insets, to calculate the difference. We also coerce
        // the insets to be >= 0, to make sure we don't use negative insets.
        val diff = Insets.subtract(typesInset, otherInset).let {
            Insets.max(it, Insets.NONE)
        }
        // The resulting `diff` insets contain the values for us to apply as a translation
        // to the view
        view.translationX = (diff.left - diff.right).toFloat()
        view.translationY = (diff.top - diff.bottom).toFloat()

        log("onProgress typesInset:${typesInset} otherInset:${otherInset} diff:${diff} translationY:${diff.top - diff.bottom}")
        return insets
    }

    override fun onEnd(animation: WindowInsetsAnimationCompat) {
        log("onEnd:==================")
        // Once the animation has ended, reset the translation values
        view.translationX = 0f
        view.translationY = 0f
    }
onProgress typesInset:Insets{left=0, top=0, right=0, bottom=0} otherInset:Insets{left=0, top=227, right=0, bottom=0} diff:Insets{left=0, top=0, right=0, bottom=0} translationY:0
onProgress typesInset:Insets{left=0, top=0, right=0, bottom=0} otherInset:Insets{left=0, top=227, right=0, bottom=0} diff:Insets{left=0, top=0, right=0, bottom=0} translationY:0
onProgress typesInset:Insets{left=0, top=0, right=0, bottom=22} otherInset:Insets{left=0, top=227, right=0, bottom=4} diff:Insets{left=0, top=0, right=0, bottom=18} translationY:-18
onProgress typesInset:Insets{left=0, top=0, right=0, bottom=112} otherInset:Insets{left=0, top=227, right=0, bottom=20} diff:Insets{left=0, top=0, right=0, bottom=92} translationY:-92
onProgress typesInset:Insets{left=0, top=0, right=0, bottom=691} otherInset:Insets{left=0, top=227, right=0, bottom=126} diff:Insets{left=0, top=0, right=0, bottom=565} translationY:-565
onProgress typesInset:Insets{left=0, top=0, right=0, bottom=238} otherInset:Insets{left=0, top=227, right=0, bottom=43} diff:Insets{left=0, top=0, right=0, bottom=195} translationY:-195
onProgress typesInset:Insets{left=0, top=0, right=0, bottom=691} otherInset:Insets{left=0, top=227, right=0, bottom=126} diff:Insets{left=0, top=0, right=0, bottom=565} translationY:-565
onProgress typesInset:Insets{left=0, top=0, right=0, bottom=387} otherInset:Insets{left=0, top=227, right=0, bottom=70} diff:Insets{left=0, top=0, right=0, bottom=317} translationY:-317
onProgress typesInset:Insets{left=0, top=0, right=0, bottom=698} otherInset:Insets{left=0, top=227, right=0, bottom=126} diff:Insets{left=0, top=0, right=0, bottom=572} translationY:-572
onProgress typesInset:Insets{left=0, top=0, right=0, bottom=387} otherInset:Insets{left=0, top=227, right=0, bottom=70} diff:Insets{left=0, top=0, right=0, bottom=317} translationY:-317
onProgress typesInset:Insets{left=0, top=0, right=0, bottom=698} otherInset:Insets{left=0, top=227, right=0, bottom=126} diff:Insets{left=0, top=0, right=0, bottom=572} translationY:-572
onProgress typesInset:Insets{left=0, top=0, right=0, bottom=518} otherInset:Insets{left=0, top=227, right=0, bottom=94} diff:Insets{left=0, top=0, right=0, bottom=424} translationY:-424
onProgress typesInset:Insets{left=0, top=0, right=0, bottom=717} otherInset:Insets{left=0, top=227, right=0, bottom=126} diff:Insets{left=0, top=0, right=0, bottom=591} translationY:-591
onProgress typesInset:Insets{left=0, top=0, right=0, bottom=609} otherInset:Insets{left=0, top=227, right=0, bottom=111} diff:Insets{left=0, top=0, right=0, bottom=498} translationY:-498
onProgress typesInset:Insets{left=0, top=0, right=0, bottom=741} otherInset:Insets{left=0, top=227, right=0, bottom=126} diff:Insets{left=0, top=0, right=0, bottom=615} translationY:-615
onProgress typesInset:Insets{left=0, top=0, right=0, bottom=664} otherInset:Insets{left=0, top=227, right=0, bottom=121} diff:Insets{left=0, top=0, right=0, bottom=543} translationY:-543
onProgress typesInset:Insets{left=0, top=0, right=0, bottom=768} otherInset:Insets{left=0, top=227, right=0, bottom=126} diff:Insets{left=0, top=0, right=0, bottom=642} translationY:-642
onProgress typesInset:Insets{left=0, top=0, right=0, bottom=686} otherInset:Insets{left=0, top=227, right=0, bottom=125} diff:Insets{left=0, top=0, right=0, bottom=561} translationY:-561
onProgress typesInset:Insets{left=0, top=0, right=0, bottom=790} otherInset:Insets{left=0, top=227, right=0, bottom=126} diff:Insets{left=0, top=0, right=0, bottom=664} translationY:-664
onProgress typesInset:Insets{left=0, top=0, right=0, bottom=691} otherInset:Insets{left=0, top=227, right=0, bottom=126} diff:Insets{left=0, top=0, right=0, bottom=565} translationY:-565
onProgress typesInset:Insets{left=0, top=0, right=0, bottom=805} otherInset:Insets{left=0, top=227, right=0, bottom=126} diff:Insets{left=0, top=0, right=0, bottom=679} translationY:-679
onProgress typesInset:Insets{left=0, top=0, right=0, bottom=691} otherInset:Insets{left=0, top=227, right=0, bottom=126} diff:Insets{left=0, top=0, right=0, bottom=565} translationY:-565
onEnd ==================
onProgress typesInset:Insets{left=0, top=0, right=0, bottom=813} otherInset:Insets{left=0, top=227, right=0, bottom=126} diff:Insets{left=0, top=0, right=0, bottom=687} translationY:-687
onProgress typesInset:Insets{left=0, top=0, right=0, bottom=816} otherInset:Insets{left=0, top=227, right=0, bottom=126} diff:Insets{left=0, top=0, right=0, bottom=690} translationY:-690
onProgress typesInset:Insets{left=0, top=0, right=0, bottom=817} otherInset:Insets{left=0, top=227, right=0, bottom=126} diff:Insets{left=0, top=0, right=0, bottom=691} translationY:-691
onProgress typesInset:Insets{left=0, top=0, right=0, bottom=817} otherInset:Insets{left=0, top=227, right=0, bottom=126} diff:Insets{left=0, top=0, right=0, bottom=691} translationY:-691
onEnd ==================
erleizh commented 2 years ago
class FixTranslateDeferringInsetsAnimationCallback(
    private val proxy: WindowInsetsAnimationCompat.Callback,
    private val deferredInsetTypes: Int,
    dispatchMode: Int = DISPATCH_MODE_STOP
) : WindowInsetsAnimationCompat.Callback(dispatchMode) {

    private var typeMask = -1

    override fun onProgress(insets: WindowInsetsCompat, runningAnimations: MutableList<WindowInsetsAnimationCompat>): WindowInsetsCompat {
        runningAnimations.find { it.typeMask == typeMask }?.let {
            proxy.onProgress(insets, runningAnimations)
        }
        return insets
    }

    override fun onPrepare(animation: WindowInsetsAnimationCompat) {
        super.onPrepare(animation)
        if (typeMask == -1 && animation.typeMask and deferredInsetTypes != 0) {
            typeMask = animation.typeMask
            proxy.onPrepare(animation)
        }
    }

    override fun onStart(animation: WindowInsetsAnimationCompat, bounds: WindowInsetsAnimationCompat.BoundsCompat): WindowInsetsAnimationCompat.BoundsCompat {
        if (typeMask == animation.typeMask) {
            return proxy.onStart(animation, bounds)
        }
        return super.onStart(animation, bounds)
    }

    override fun onEnd(animation: WindowInsetsAnimationCompat) {
        super.onEnd(animation)
        if (typeMask == animation.typeMask) {
            proxy.onEnd(animation)
            typeMask = -1
        }
    }
}