Как создать кнопку с плавающим действием (FAB) в Android с помощью AppCompat v21?


79

Я хотел бы создать кнопку с плавающим действием (для добавления элементов в список), например календарь Google, с сохранением совместимости с версиями Android до Lollipop (до 5.0).

Я создал этот макет:

Действие main_activity.xml:

<LinearLayout ... >

     <include
         layout="@layout/toolbar"/>

     <RelativeLayout ... >

     <!-- My rest of the layout -->

          <!-- Floating action button -->
          <ImageButton style="@style/AppTheme"
                     android:layout_width="60dp"
                     android:layout_height="60dp"
                     android:text="New Button"
                     android:id="@+id/button"
                     android:src="@drawable/ic_fab"
                     android:background="@drawable/fab"
                     android:layout_alignParentBottom="true"
                     android:layout_alignParentRight="true"
                     android:layout_marginBottom="24dp"
                     android:layout_marginRight="24dp"/>

     </RelativeLayout>

 </LinearLayout>

Возможность рисования fab.xml:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="oval">
    <solid android:color="#ffa48bc0"/>
</shape>

Стиль styles.xml

<resources>
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="colorPrimary">#ff1d79b1</item>
        <item name="colorPrimaryDark">#ff084d95</item>
    </style>
</resources>

Результат аналогичен, но отсутствует штриховка, характерная для материального дизайна:

Плавающая кнопка действия календаря:

Плавающая кнопка действия календаря

Плавающая кнопка действия моего приложения:

Плавающая кнопка действия моего приложения

Как я могу добавить затенение к моей кнопке?

Я уже использовал высоту атрибута, но не работает


1
API повышения уровня предназначен только для Lollipop, вы пробовали использовать устройство Lollipop?
Marc Plano-Lesay

2
Вероятно, пора принять один из приведенных ответов.
Phantômaxx

На самом деле, на моем Samsung Galaxy S III 4.4.2 тень есть, благодаря AppCompat.
FractalBob

Ответы:


100

Больше нет необходимости создавать свой собственный FAB или использовать стороннюю библиотеку, он был включен в AppCompat 22.

https://developer.android.com/reference/android/support/design/widget/FloatingActionButton.html

Просто добавьте новую библиотеку поддержки под названием design в свой файл gradle:

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

... и все готово:

<android.support.design.widget.FloatingActionButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        android:layout_margin="16dp"
        android:clickable="true"
        android:src="@drawable/ic_happy_image" />

1
как изменить цвет фона?
Jjang

2
По умолчанию цвет фона будет «colorAccent» из вашей темы. Однако вы также можете использовать floatActionButton.setRippleColor (color), не позволяйте имени «рябь» пугать вас, он также работает на устройствах pre-lollipop.
user1354603

У меня нет colorAccent, и если я добавлю его и установлю другой цвет, это не сработает - цвет останется зеленым / бирюзовым.
Jjang

Я использовал для этого стороннюю программу. Мне действительно очень помогло. Благодарю. Одна проблема заключается в том, что он все еще кажется, что он не полностью разработан.
V_J

1
@Jjang @ user1354603 из документацииThe background color of this view defaults to the your theme's colorAccent. If you wish to change this at runtime then you can do so via setBackgroundTintList(ColorStateList).
Мухаммад Бабар,

43

Я обычно использовал чертежи xml для создания тени / возвышения на виджете до леденца на палочке. Вот, например, XML-файл для рисования, который можно использовать на устройствах pre-lollipop для имитации высоты кнопки с плавающим действием.

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:top="8px">
    <layer-list>
        <item>
            <shape android:shape="oval">
                <solid android:color="#08000000"/>
                <padding
                    android:bottom="3px"
                    android:left="3px"
                    android:right="3px"
                    android:top="3px"
                    />
            </shape>
        </item>
        <item>
            <shape android:shape="oval">
                <solid android:color="#09000000"/>
                <padding
                    android:bottom="2px"
                    android:left="2px"
                    android:right="2px"
                    android:top="2px"
                    />
            </shape>
        </item>
        <item>
            <shape android:shape="oval">
                <solid android:color="#10000000"/>
                <padding
                    android:bottom="2px"
                    android:left="2px"
                    android:right="2px"
                    android:top="2px"
                    />
            </shape>
        </item>
        <item>
            <shape android:shape="oval">
                <solid android:color="#11000000"/>
                <padding
                    android:bottom="1px"
                    android:left="1px"
                    android:right="1px"
                    android:top="1px"
                    />
            </shape>
        </item>
        <item>
            <shape android:shape="oval">
                <solid android:color="#12000000"/>
                <padding
                    android:bottom="1px"
                    android:left="1px"
                    android:right="1px"
                    android:top="1px"
                    />
            </shape>
        </item>
        <item>
            <shape android:shape="oval">
                <solid android:color="#13000000"/>
                <padding
                    android:bottom="1px"
                    android:left="1px"
                    android:right="1px"
                    android:top="1px"
                    />
            </shape>
        </item>
        <item>
            <shape android:shape="oval">
                <solid android:color="#14000000"/>
                <padding
                    android:bottom="1px"
                    android:left="1px"
                    android:right="1px"
                    android:top="1px"
                    />
            </shape>
        </item>
        <item>
            <shape android:shape="oval">
                <solid android:color="#15000000"/>
                <padding
                    android:bottom="1px"
                    android:left="1px"
                    android:right="1px"
                    android:top="1px"
                    />
            </shape>
        </item>
        <item>
            <shape android:shape="oval">
                <solid android:color="#16000000"/>
                <padding
                    android:bottom="1px"
                    android:left="1px"
                    android:right="1px"
                    android:top="1px"
                    />
            </shape>
        </item>
        <item>
            <shape android:shape="oval">
                <solid android:color="#17000000"/>
                <padding
                    android:bottom="1px"
                    android:left="1px"
                    android:right="1px"
                    android:top="1px"
                    />
            </shape>
        </item>
    </layer-list>
</item>
<item>
    <shape android:shape="oval">
        <solid android:color="?attr/colorPrimary"/>
    </shape>
</item>
</layer-list>

На место ?attr/colorPrimaryможно выбрать любой цвет. Вот скриншот результата:

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


1
Спасибо за то, что поделился этим. Я боялся снова откопать XML-код, чтобы воссоздать его.
Cookster

Я реализовал только что, и это здорово, есть только одна странность. Кажется, что при повороте телефона теряется тень / высота. Есть мысли по этому поводу? Заранее спасибо Джастин
Амилкар Андраде

@AmilcarAndrade, это хороший вопрос. Я сталкивался с подобными вещами с другими чертежами xml, но на самом деле я извлекал растровое изображение из самого объекта рисования. Чтобы решить эту проблему, я, по сути, использовал drawable как синглтон; установить один раз, чтобы он больше не рисовался. Возможно, вы можете получить объект для рисования как статическую переменную и установить его в качестве фона в onCreate?
Джастин Поллард,

Также я добавил улучшение, вы можете очень легко добавить эффект riple, ниже приведен код.
Амилкар Андраде,

2
Для будущих ссылок это отличный пример того, как избегать теней и возвышений -> curious-creature.com/2008/12/18/avoid-memory-leaks-on-android/…
Амилкар Андраде

20

Существует множество библиотек, которые добавляют в ваше приложение FAB (плавающую кнопку действия). Вот некоторые из них, которые я знаю.

FAB от маковкастара

Композитный FAB от Futuersimple

Библиотека материального дизайна, которая также включает FAB

Все эти библиотеки поддерживаются на устройствах pre-lollipop, минимум до api 8



4

XML-код @Justin Pollard работает действительно хорошо. В качестве примечания вы можете добавить эффект пульсации с помощью следующих строк xml.

    <item>
    <ripple
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:color="?android:colorControlHighlight" >
        <item android:id="@android:id/mask">
            <shape android:shape="oval" >
                <solid android:color="#FFBB00" />
            </shape>
        </item>
        <item>
            <shape android:shape="oval" >
                <solid android:color="@color/ColorPrimary" />
            </shape>
        </item>
    </ripple>
</item>


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.