Циркулярная развертка не работает, когда гравитация FAB снизу

Я работаю над преобразованием кнопки плавающего действия (FAB) на панель инструментов, и все работает плавно и отлично со следующим кодом:

файл макета:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="sg.com.saurabh.designlibraryexpirements.ToolbarMorphActivity">

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="top|right"
        android:layout_marginTop="@dimen/activity_vertical_margin"
        android:layout_marginRight="@dimen/activity_vertical_margin"
        android:layout_marginBottom="@dimen/activity_vertical_margin"
        android:src="@drawable/ic_add" />

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        style="@style/ToolBarTheme"
        android:layout_height="?attr/actionBarSize"
        android:layout_gravity="top"
        android:layout_marginTop="@dimen/activity_vertical_margin"
        android:layout_marginBottom="@dimen/activity_vertical_margin"
        android:visibility="invisible"
        tools:visibility="visible" />

</FrameLayout>

активность:

package sg.com.saurabh.designlibraryexpirements;

import android.animation.Animator;
import android.os.Bundle;
import android.os.Handler;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.view.animation.FastOutLinearInInterpolator;
import android.support.v4.view.animation.LinearOutSlowInInterpolator;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.ViewAnimationUtils;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.AnticipateOvershootInterpolator;

public class ToolbarMorphActivity extends AppCompatActivity {

    Toolbar toolbar;
    FloatingActionButton fab;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_toolbar_morph);

        toolbar = (Toolbar) findViewById(R.id.toolbar);
        fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(mFabClickListener);
    }

    private View.OnClickListener mFabClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            fab.animate()
                    .rotationBy(45)
                    .setInterpolator(new AnticipateOvershootInterpolator())
                    .setDuration(250)
                    .start();

            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    fab.setVisibility(View.GONE);
                }
            },50);

            revealToolbar();
        }
    };

    private void revealToolbar() {
        toolbar.setVisibility(View.VISIBLE);

        int x = (int)fab.getX() + fab.getWidth()/2;
        int y = (int)fab.getY() + fab.getHeight()/2;

        Animator animator = ViewAnimationUtils.createCircularReveal(toolbar, x, y, 0, toolbar.getWidth())
                .setDuration(400);
        animator.setInterpolator(new FastOutLinearInInterpolator());
        animator.start();
    }

    private void dismissToolbar() {
        int x = (int)fab.getX() + fab.getWidth()/2;
        int y = (int)fab.getY() + fab.getHeight()/2;

        Animator animator = ViewAnimationUtils.createCircularReveal(toolbar, x, y, toolbar.getWidth(), 0)
                .setDuration(400);
        animator.setInterpolator(new LinearOutSlowInInterpolator());
        animator.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {

            }

            @Override
            public void onAnimationEnd(Animator animation) {
                toolbar.setVisibility(View.INVISIBLE);
            }

            @Override
            public void onAnimationCancel(Animator animation) {

            }

            @Override
            public void onAnimationRepeat(Animator animation) {

            }
        });
        animator.start();

        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                fab.setVisibility(View.VISIBLE);

                fab.animate()
                        .rotationBy(-45)
                        .setInterpolator(new AccelerateInterpolator())
                        .setDuration(100)
                        .start();
            }
        },200);
    }

    @Override
    public void onBackPressed() {
        if(toolbar.getVisibility() == View.VISIBLE) {
            dismissToolbar();
        }
        else
            super.onBackPressed();
    }
}

Круговое раскрытие работает, как и ожидалось для вышеуказанной компоновки. Однако вещь разрушается, когда я изменяю layout_gravity панели fab и панели инструментов на bottom вместо top. Работает анимация вращения, а затем панель инструментов появляется без круговой анимации. Я полностью потрясен тем, как это нарушает круговую анимацию.

Ответ 1

введите описание изображения здесь

Исправление для вас будет заменено:

private void revealToolbar() {
    ....
    int x = (int)fab.getX() + fab.getWidth()/2;
    int y = (int)fab.getY() + fab.getHeight()/2;
    ....
}

по

 private void revealToolbar() {
    ...
    int x = (int)fab.getX() + fab.getWidth()/2;
    int y = fab.getHeight()/2;
    ...
 }

Причина заключается в том, что createCircularReveal принимает параметры centerY и centerX в качестве координат центра анимационного круга относительно вида (т.е. Toolbar, в нашем случае).

См. метод ViewAnimationUtils.createCircularReveal определение:

 ........
 * @param view The View will be clipped to the animating circle.
 * @param centerX The x coordinate of the center of the animating circle, relative to
 *                <code>view</code>.
 * @param centerY The y coordinate of the center of the animating circle, relative to
 *                <code>view</code>.
 * @param startRadius The starting radius of the animating circle.
 * @param endRadius The ending radius of the animating circle.
 */