Для начала создайте пустой Android проект.

Добавьте зависимость Android Design, потому что FAB находится в этой библиотеке. Скопируйте и вставьте её в свой проект.

implementation 'com.android.support:design:28.0.0'

Если вы не знаете, что такое привязка данных и как она работает, рекомендую почитать статьи и документацию.

Я расскажу о привязке данных только то, что понадобится для этого проекта. Для привязки данных вам больше не нужно писать findViewById. Вы можете хранить XML в одной переменной и использовать его в FAB activity.

Чтобы включить привязку данных, вставьте в build.gradle (app level) эти строки:

dataBinding{
    enabled true
}

После запуска Activity_fab должен выглядеть так:

Теперь оберните этот код в тег <layout> для того, чтобы привязка данных работала.

<layout> tag

coordinatorLayout — это мощный FrameLayout. Используйте его, если хотите взаимодействовать с более чем одним дочерним представлением или макетом верхнего уровня decor/chrome.

Давайте добавим LinearLayout в coordinatorLayout. Добавьте следующий код:

<LinearLayout
    android:gravity="center_horizontal"
    android:layout_gravity="bottom|end|right"
    android:orientation="vertical"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">
</LinearLayout>

Теперь можно добавить плавающую кнопку действия (FAB) в linear layout.

<android.support.design.widget.FloatingActionButton
    android:id="@+id/fabAdd"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginLeft="18dp"
    android:layout_marginTop="10dp"
    android:layout_marginRight="18dp"
    android:layout_marginBottom="18dp"
    app:fabSize="normal"
    app:rippleColor="@color/white" />

Добавьте этот код в colors.xml.

<color name="white">#ffff</color>
<color name="grey_20">#cccccc</color>
<color name="grey_80">#37474F</color>

Нам нужно добавить три иконки, которые будут отображаться на кнопках. Я использую иконки Android Material. Вы можете использовать свои собственные иконки.

Привязываем иконку add к кнопке FAB. Ваш код должен выглядеть так:

<android.support.design.widget.FloatingActionButton
    android:id="@+id/fabAdd"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginLeft="18dp"
    android:layout_marginTop="10dp"
    android:layout_marginRight="18dp"
    android:layout_marginBottom="18dp"
    android:src="@drawable/ic_add"  //добавленная иконка add
    app:fabSize="normal"
    app:rippleColor="@color/white" />

Приступим к анимации FAB.

Создайте класс аниматора с именем ViewAnimation.java. Далее добавьте в этот класс все наши методы анимации.

Добавьте следующий метод в класс анимации:

public static boolean rotateFab(final View v, boolean rotate) {
    v.animate().setDuration(200)
            .setListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    super.onAnimationEnd(animation);
                }
            })
            .rotation(rotate ? 135f : 0f);
    return rotate;
}

Вот что должно быть в классе анимации:

ViewAnimation.java

Теперь давайте перейдём к классу activity и реализуем нашу анимацию для FAB.

Код activity:

Давайте разберём этот этап:

ActivityFabBinding: нужно для привязки данных. Сначала вы должны написать Activity, затем его имя (я присвоил имя Fab), а затем добавить привязку.

isRotate: логическое значение. Оно зависит от состояния кнопки. Если true, значит FAB повёрнут, а если false — то нет.

bi: я сохранил весь XML в этой переменной, используя методы привязки данных.

Запустите приложение, и вы увидите красивую, плавную анимацию FAB!

Отлично!

Теперь добавим дочерние кнопки FAB, которые будут появляться сверху при нажатии на кнопку add. Вот так:

Чтобы сделать это, откройте свой основной XML, где мы ранее добавили кнопку FAB, и вставьте следующий код FAB:

<android.support.design.widget.FloatingActionButton
    android:id="@+id/fabMic"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerInParent="true"
    android:layout_margin="10dp"
    android:src="@drawable/ic_mic"
    android:tint="@color/grey_80"
    app:backgroundTint="@color/grey_20"
    app:fabSize="mini"
    app:rippleColor="@color/white" />

<android.support.design.widget.FloatingActionButton
    android:id="@+id/fabCall"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_margin="10dp"
    android:src="@drawable/ic_call"
    android:tint="@color/grey_80"
    app:backgroundTint="@color/grey_20"
    app:fabSize="mini"
    app:rippleColor="@color/white" />

Это дочерние кнопки.

Обратите внимание, что значение fabSize установлено как mini. Сверьте свой код с этим:

Давайте добавим несколько новых функций в файл ViewAnimation.java.

public static void showIn(final View v) {
    v.setVisibility(View.VISIBLE);
    v.setAlpha(0f);
    v.setTranslationY(v.getHeight());
    v.animate()
            .setDuration(200)
            .translationY(0)
            .setListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    super.onAnimationEnd(animation);
                }
            })
            .alpha(1f)
            .start();
}
public static void showOut(final View v) {
    v.setVisibility(View.VISIBLE);
    v.setAlpha(1f);
    v.setTranslationY(0);
    v.animate()
            .setDuration(200)
            .translationY(v.getHeight())
            .setListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    v.setVisibility(View.GONE);
                    super.onAnimationEnd(animation);
                }
            }).alpha(0f)
            .start();
}

public static void init(final View v) {
    v.setVisibility(View.GONE);
    v.setTranslationY(v.getHeight());
    v.setAlpha(0f);
}

Эти три функции позволяют добиться плавной анимации для наших мини FAB-ов.

showIn(): отвечает за сворачивание FAB-ов внутрь при нажатии.

showOut(): отвечает за появление FAB-ов при нажатии.

init(): отвечает за то, чтобы кнопки при запуске приложения были скрыты.

Запустим приложение.

Пока ничего не происходит. Давайте шаг за шагом реализуем остальной функционал.

Во-первых, нужно спрятать мини FAB-ы при инициализации. Добавьте следующий код в метод onCreate и запустите приложение.

ViewAnimation.init(bi.fabMic);
ViewAnimation.init(bi.fabCall);

Теперь сделаем так, чтобы они появлялись после нажатия на основную кнопку FAB.

Добавьте код в метод onCreate:

bi.fabAdd.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        isRotate = ViewAnimation.rotateFab(v, !isRotate);
        if(isRotate){
            ViewAnimation.showIn(bi.fabCall);
            ViewAnimation.showIn(bi.fabMic);
        }else{
            ViewAnimation.showOut(bi.fabCall);
            ViewAnimation.showOut(bi.fabMic);
        }

    }

Запускаем.

Давайте добавим прослушиватели для мини FAB-ов.

bi.fabCall.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Toast.makeText(FABActivity.this, "Calling", Toast.LENGTH_SHORT).show();
    }
});

bi.fabMic.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {

        Toast.makeText(FABActivity.this, "mic", Toast.LENGTH_SHORT).show();
    }
});

И снова запускаем приложение.

Вот и все.

Читайте также:


Перевод статьи Mustufa Ansari: Animated Floating Action Button With More Options!

Предыдущая статьяReact Native vs Flutter
Следующая статьяПрокачка Jupyter Notebooks