aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/app/src/main/java/com/wireguard/android/widget/fab/FloatingActionButtonBehavior.java
blob: 3741c29ee9bf3e787fb4b78491b887fcd6c9ad5a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
/*
 * Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
 * SPDX-License-Identifier: Apache-2.0
 */

package com.wireguard.android.widget.fab;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.TimeInterpolator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.Snackbar;
import android.support.v4.view.animation.FastOutSlowInInterpolator;
import android.util.AttributeSet;
import android.view.View;

public class FloatingActionButtonBehavior extends CoordinatorLayout.Behavior<FloatingActionsMenu> {

    private static final long ANIMATION_DURATION = 250;
    private static final TimeInterpolator FAST_OUT_SLOW_IN_INTERPOLATOR = new FastOutSlowInInterpolator();

    public FloatingActionButtonBehavior(final Context context, final AttributeSet attrs) {
        super(context, attrs);
    }

    private static void animateChange(final FloatingActionsMenu child, final float destination, final float fullSpan) {
        final float origin = child.getBehaviorYTranslation();
        if (Math.abs(destination - origin) < fullSpan / 2) {
            child.setBehaviorYTranslation(destination);
            return;
        }
        final ValueAnimator animator = new ValueAnimator();
        animator.setFloatValues(origin, destination);
        animator.setInterpolator(FAST_OUT_SLOW_IN_INTERPOLATOR);
        animator.setDuration((long) (ANIMATION_DURATION * (Math.abs(destination - origin) / fullSpan)));
        animator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(final Animator a) {
                child.setBehaviorYTranslation(destination);
            }
        });
        animator.addUpdateListener(a -> child.setBehaviorYTranslation((float) a.getAnimatedValue()));
        animator.start();
    }

    @Override
    public boolean layoutDependsOn(final CoordinatorLayout parent, final FloatingActionsMenu child,
                                   final View dependency) {
        return dependency instanceof Snackbar.SnackbarLayout;
    }

    @Override
    public boolean onDependentViewChanged(final CoordinatorLayout parent, final FloatingActionsMenu child,
                                          final View dependency) {
        animateChange(child, Math.min(0, dependency.getTranslationY() - dependency.getMeasuredHeight()), dependency.getMeasuredHeight());
        return true;
    }

    @Override
    public void onDependentViewRemoved(final CoordinatorLayout parent, final FloatingActionsMenu child,
                                       final View dependency) {
        animateChange(child, 0, dependency.getMeasuredHeight());
    }
}