Пример FloatingActionButton с библиотекой поддержки

129

Недавно я прочитал эти сообщения:

Библиотека поддержки дизайна Android

Библиотека поддержки Android, версия 22.2.0

FloatingActionButton

Но ни один из них не дает мне подробного примера создания нового FloatingActionButton. Так сложно понять, я задаю этот вопрос.

Кто-нибудь может привести мне пример об этом?

Любая помощь очень ценится. Заранее спасибо.

РЕДАКТИРОВАТЬ

Я только что обнаружил некоторые проблемы на FloatingActionButton(FAB) и хочу улучшить другой ответ. Смотрите мой ответ ниже.

Ангграюди H
источник
stackoverflow.com/questions/30483210/…
Габриэле Мариотти

Ответы:

274

Итак, в свой build.gradleфайл добавьте это:

compile 'com.android.support:design:27.1.1'

Примечание для AndroidX: Google представляет новые библиотеки расширений AndroidX, которые заменят старые библиотеки поддержки. Чтобы использовать AndroidX, сначала убедитесь, что вы обновили свой gradle.propertiesфайл , отредактировали, build.gradleчтобы установить compileSdkVersionзначение 28(или выше), и используйте следующую строку вместо предыдущей compile.

implementation 'com.google.android.material:material:1.0.0'

Далее, в вашем themes.xmlили styles.xmlили любой другой , убедитесь , что вы установили this- это вашего приложения акцент color-- и цвет вашего FAB , если не переопределить его (смотрите ниже):

        <item name="colorAccent">@color/floating_action_button_color</item>

В XML макета:

<RelativeLayout
 ...
 xmlns:app="http://schemas.android.com/apk/res-auto">

       <android.support.design.widget.FloatingActionButton
            android:id="@+id/myFAB"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/ic_plus_sign"
            app:elevation="4dp"
            ... />

</RelativeLayout>

Или, если вы используете библиотеку материалов AndroidX, указанную выше, вы бы вместо этого использовали это:

<RelativeLayout
 ...
 xmlns:app="http://schemas.android.com/apk/res-auto">

       <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:id="@+id/myFAB"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:srcCompat="@drawable/ic_plus_sign"
            app:elevation="4dp"
            ... />

</RelativeLayout>

Вы можете увидеть больше опций в документации (материалы здесь) ( setRippleColorи т. Д.), Но следует отметить следующее:

    app:fabSize="mini"

Еще один интересный вариант - чтобы изменить цвет фона только одного FAB, добавьте:

    app:backgroundTint="#FF0000"

(например, чтобы изменить его на красный) в XML выше.

Во всяком случае, в коде, после того, как представление Activity / Fragment раздувается ....

    FloatingActionButton myFab = (FloatingActionButton)  myView.findViewById(R.id.myFAB);
    myFab.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            doMyThing();
        }
    });

Замечания:

  • Если у вас есть одна из этих кнопок, которая находится на «стыке», разделяющем два представления (например, с использованием RelativeLayout), например, с отрицательным нижним полем макета для перекрытия границы, вы заметите проблему: размер FAB на самом деле сильно отличается на леденце от леденца на палочке. Вы действительно можете увидеть это в редакторе визуального макета AS, когда переключаетесь между API-интерфейсами - он внезапно «выпадает», когда вы переключаетесь на pre-lollipop. Причина дополнительного размера, по-видимому, в том, что тень увеличивает размер обзора во всех направлениях. Так что вы должны учитывать это, когда настраиваете поля FAB, если они близки к другим параметрам.
  • Вот способ удалить или изменить отступ, если его слишком много:

    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
        RelativeLayout.LayoutParams p = (RelativeLayout.LayoutParams) myFab.getLayoutParams();
        p.setMargins(0, 0, 0, 0); // get rid of margins since shadow area is now the margin
        myFab.setLayoutParams(p);
    }
  • Кроме того, я собирался программно разместить FAB на «стыке» между двумя областями в RelativeLayout, взяв высоту FAB, разделив на два и используя это как смещение поля. Но myFab.getHeight () вернул ноль, казалось, даже после того, как представление было раздутым. Вместо этого я использовал ViewTreeObserver, чтобы получить высоту только после того, как она выложена, а затем установила позицию. См. Этот совет здесь . Выглядело это так:

        ViewTreeObserver viewTreeObserver = closeButton.getViewTreeObserver();
        if (viewTreeObserver.isAlive()) {
            viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                @Override
                public void onGlobalLayout() {
                    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
                        closeButton.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                    } else {
                        closeButton.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                    }
                    // not sure the above is equivalent, but that's beside the point for this example...
                    RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) closeButton.getLayoutParams();
                    params.setMargins(0, 0, 16, -closeButton.getHeight() / 2); // (int left, int top, int right, int bottom)
                    closeButton.setLayoutParams(params);
                }
            });
        }

    Не уверен, что это правильный способ, но, похоже, он работает.

  • Кажется, вы можете уменьшить теневое пространство кнопки, уменьшив высоту.
  • Если вы хотите, чтобы FAB находился на «шве», вы можете использовать его, layout_anchorи layout_anchorGravityвот пример:

    <android.support.design.widget.FloatingActionButton
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        app:layout_anchor="@id/appbar"
        app:layout_anchorGravity="bottom|right|end"
        android:src="@drawable/ic_discuss"
        android:layout_margin="@dimen/fab_margin"
        android:clickable="true"/>

Помните, что вы можете автоматически отскакивать от кнопки, когда появляется Snackbar , обернув ее в CoordinatorLayout .

Больше:

fattire
источник
1
Конечно. Просто добавьте, android:backgroundTint="#FF0000"например, к FloatingActionBar в XML. (добавление к ответу)
fattire 02
1
Хм. Хорошо, тогда я изменю это выше. Спасибо! Dark Leonhart - я ничего не видел о встроенном быстром возврате, но есть примеры того, как это сделать в другом месте в stackoverflow, которые, как я полагаю, все еще будут работать. К тому же доступны некоторые библиотеки, которые тоже это делают.
fattire
1
Этот компонент по состоянию на 22.2.0, на мой взгляд, не готов к производству. Кстати, это может быть опечатка, но не используйте spв свойстве evelation. Должно бытьapp:elevation="4dp"
Жоао Соуза
1
Обратите внимание, что если вы добавляете a FloatingActionButtonк a CoordinatorLayout, вы можете использовать app:layout_anchor="element_with_seam"и, app:layout_anchorGravity="bottom|right|end"чтобы правильно расположить FAB над швом - см. Макет activity_detail из cheesesquare
ianhanniballake
2
@DarkLeonhart - посмотрите мой пример отображения / скрытия FAB при прокрутке , расширяя его поведение.
ianhanniballake 07
49

Я только что обнаружил некоторые проблемы в FAB, и я хочу улучшить другой ответ.


setRippleColor проблема

Итак, проблема возникнет, когда вы программно установите цвет пульсации (цвет FAB включен) setRippleColor. Но у нас все еще есть альтернативный способ установить его, то есть путем вызова:

FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
ColorStateList rippleColor = ContextCompat.getColorStateList(context, R.color.fab_ripple_color);
fab.setBackgroundTintList(rippleColor);

Ваш проект должен иметь такую ​​структуру:

/res/color/fab_ripple_color.xml

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

И код от fab_ripple_color.xml:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" android:color="@color/fab_color_pressed" />
    <item android:state_focused="true" android:color="@color/fab_color_pressed" />
    <item android:color="@color/fab_color_normal"/>
</selector>

Наконец, немного измените свой FAB:

<android.support.design.widget.FloatingActionButton
    android:id="@+id/fab"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/ic_action_add"
    android:layout_alignParentBottom="true"
    android:layout_alignParentRight="true"
    app:fabSize="normal"
    app:borderWidth="0dp"
    app:elevation="6dp"
    app:pressedTranslationZ="12dp"
    app:rippleColor="@android:color/transparent"/> <!-- set to transparent color -->

Для уровня API 21 и выше установите маржу справа и снизу на 24dp:

...
android:layout_marginRight="24dp"
android:layout_marginBottom="24dp" />

Руководства по проектированию FloatingActionButton

Как вы можете видеть в моем коде FAB xml выше, я установил:

        ...
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        app:elevation="6dp"
        app:pressedTranslationZ="12dp"
        ...
  • Устанавливая эти атрибуты, вам не нужно устанавливать layout_marginTopи layout_marginRightснова (только на pre-Lollipop). Android автоматически разместит его в правой части экрана, что аналогично обычному FAB в Android Lollipop.

        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"

Или вы можете использовать это в CoordinatorLayout:

        android:layout_gravity="end|bottom"

Правила FAB

Ангграюди H
источник
5
одобряет исследования. плюс 1 за pressedTranslationZ. Я этого не знал.
Жоао Соуза
app: elevation = "6dp" app: PressTranslationZ = "12dp" делает трюк для pre-lollipop, но моя фабрика находится буквально в углу экрана на Lollipop
Тьяго
1
Вы используете неверное значение для "olvedTranslationZ ". Это не значение высоты в нажатом состоянии. PressedElevation = высота + PressTranslationZ. Итак, правильные значения: app: elevation = "6dp" app :hibitedTranslationZ = "6dp"
e.shishkin
3
На самом деле вам не нужно устанавливать app:elevationи app:pressedTranslationZзначение. Их значение по умолчанию - это значение, определенное в руководстве по дизайну материалов. Во всяком случае, прав Э.Шишкин, значения есть app:elevation:6dpи pressedTranslationZ:6dp. Вы можете проверить это в исходном коде
Christian García
12

FloatingActionButtonрасширяется ImageView. Итак, это просто, как если бы вы добавили ImageViewв ваш макет. Вот образец XML.

<android.support.design.widget.FloatingActionButton   xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/fab"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/somedrawable"
    android:layout_gravity="right|bottom"
    app:borderWidth="0dp"
    app:rippleColor="#ffffff"/>

app:borderWidth="0dp" добавлен как обходной путь для проблем с высотой.

siriscac
источник
4

для AndroidX используйте как

<com.google.android.material.floatingactionbutton.FloatingActionButton
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:srcCompat="@drawable/ic_add" />
Дэн Альботяну
источник
1

Если вы уже добавили все библиотеки, а он по-прежнему не работает, используйте:

<com.google.android.material.floatingactionbutton.FloatingActionButton
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:srcCompat="@drawable/ic_add" 
/>

вместо того:

<android.support.design.widget.FloatingActionButton
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   app:srcCompat="@drawable/ic_add"
 />

И все будет нормально работать :)

Макс Швед
источник