Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 18ea005b authored by Jerry Chang's avatar Jerry Chang Committed by Android (Google) Code Review
Browse files

Merge "Add fling animation when snapping split divider bar"

parents a72217f7 5935f559
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -112,7 +112,7 @@ public class DividerView extends FrameLayout implements View.OnTouchListener {
                }
                if (mMoving) {
                    final int position = mSplitLayout.getDividePosition() + touchPos - mStartPos;
                    mSplitLayout.updateDividePosition(position);
                    mSplitLayout.updateDivideBounds(position);
                }
                break;
            case MotionEvent.ACTION_UP:
@@ -131,7 +131,7 @@ public class DividerView extends FrameLayout implements View.OnTouchListener {
                final int position = mSplitLayout.getDividePosition() + touchPos - mStartPos;
                final DividerSnapAlgorithm.SnapTarget snapTarget =
                        mSplitLayout.findSnapTarget(position, velocity);
                mSplitLayout.setSnapTarget(snapTarget);
                mSplitLayout.snapToTarget(position, snapTarget);
                break;
        }
        return true;
+35 −6
Original line number Diff line number Diff line
@@ -22,6 +22,9 @@ import static android.view.WindowManager.DOCKED_TOP;
import static com.android.internal.policy.DividerSnapAlgorithm.SnapTarget.FLAG_DISMISS_END;
import static com.android.internal.policy.DividerSnapAlgorithm.SnapTarget.FLAG_DISMISS_START;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
@@ -31,6 +34,7 @@ import android.view.SurfaceControl;
import androidx.annotation.Nullable;

import com.android.internal.policy.DividerSnapAlgorithm;
import com.android.wm.shell.animation.Interpolators;

/**
 * Records and handles layout of splits. Helps to calculate proper bounds when configuration or
@@ -145,16 +149,22 @@ public class SplitLayout {
     * Updates bounds with the passing position. Usually used to update recording bounds while
     * performing animation or dragging divider bar to resize the splits.
     */
    public void updateDividePosition(int position) {
    void updateDivideBounds(int position) {
        updateBounds(position);
        mLayoutChangeListener.onBoundsChanging(this);
    }

    void setDividePosition(int position) {
        mDividePosition = position;
        updateBounds(mDividePosition);
        mLayoutChangeListener.onBoundsChanged(this);
    }

    /**
     * Sets new divide position and updates bounds correspondingly. Notifies listener if the new
     * target indicates dismissing split.
     */
    public void setSnapTarget(DividerSnapAlgorithm.SnapTarget snapTarget) {
    public void snapToTarget(int currentPosition, DividerSnapAlgorithm.SnapTarget snapTarget) {
        switch (snapTarget.flag) {
            case FLAG_DISMISS_START:
                mLayoutChangeListener.onSnappedToDismiss(false /* snappedToEnd */);
@@ -163,9 +173,7 @@ public class SplitLayout {
                mLayoutChangeListener.onSnappedToDismiss(true /* snappedToEnd */);
                break;
            default:
                mDividePosition = snapTarget.position;
                updateBounds(mDividePosition);
                mLayoutChangeListener.onBoundsChanged(this);
                flingDividePosition(currentPosition, snapTarget.position);
                break;
        }
    }
@@ -189,6 +197,27 @@ public class SplitLayout {
                isLandscape ? DOCKED_LEFT : DOCKED_TOP /* dockSide */);
    }

    private void flingDividePosition(int from, int to) {
        ValueAnimator animator = ValueAnimator
                .ofInt(from, to)
                .setDuration(250);
        animator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
        animator.addUpdateListener(
                animation -> updateDivideBounds((int) animation.getAnimatedValue()));
        animator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                setDividePosition(to);
            }

            @Override
            public void onAnimationCancel(Animator animation) {
                setDividePosition(to);
            }
        });
        animator.start();
    }

    private static boolean isLandscape(Rect bounds) {
        return bounds.width() > bounds.height();
    }
+13 −10
Original line number Diff line number Diff line
@@ -69,24 +69,27 @@ public class SplitLayoutTests extends ShellTestCase {
    }

    @Test
    public void testUpdateDividePosition() {
        mSplitLayout.updateDividePosition(anyInt());
    public void testUpdateDivideBounds() {
        mSplitLayout.updateDivideBounds(anyInt());
        verify(mLayoutChangeListener).onBoundsChanging(any(SplitLayout.class));
    }

    @Test
    public void testSetSnapTarget() {
        DividerSnapAlgorithm.SnapTarget snapTarget = getSnapTarget(0,
    @UiThreadTest
    public void testSnapToTarget() {
        DividerSnapAlgorithm.SnapTarget snapTarget = getSnapTarget(0 /* position */,
                DividerSnapAlgorithm.SnapTarget.FLAG_NONE);
        mSplitLayout.setSnapTarget(snapTarget);
        verify(mLayoutChangeListener).onBoundsChanged(any(SplitLayout.class));
        mSplitLayout.snapToTarget(0 /* currentPosition */, snapTarget);
        verify(mLayoutChangeListener).onBoundsChanging(any(SplitLayout.class));

        // verify it callbacks properly when the snap target indicates dismissing split.
        snapTarget = getSnapTarget(0, DividerSnapAlgorithm.SnapTarget.FLAG_DISMISS_START);
        mSplitLayout.setSnapTarget(snapTarget);
        snapTarget = getSnapTarget(0 /* position */,
                DividerSnapAlgorithm.SnapTarget.FLAG_DISMISS_START);
        mSplitLayout.snapToTarget(0 /* currentPosition */, snapTarget);
        verify(mLayoutChangeListener).onSnappedToDismiss(eq(false));
        snapTarget = getSnapTarget(0, DividerSnapAlgorithm.SnapTarget.FLAG_DISMISS_END);
        mSplitLayout.setSnapTarget(snapTarget);
        snapTarget = getSnapTarget(0 /* position */,
                DividerSnapAlgorithm.SnapTarget.FLAG_DISMISS_END);
        mSplitLayout.snapToTarget(0 /* currentPosition */, snapTarget);
        verify(mLayoutChangeListener).onSnappedToDismiss(eq(true));
    }