Як створити плаваючу кнопку дії (FAB) в Android, використовуючи AppCompat v21?


79

Я хотів би створити плаваючу кнопку дії (для додавання елементів до перегляду списку), як-от календар Google, підтримуючи сумісність із версіями Android до льодяника (до 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>

Стилі style.xml

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

Результат подібний, але немає затінення, характерного для дизайну матеріалу:

Плаваюча кнопка дії календаря:

Плаваюча кнопка дії календаря

Плаваюча кнопка дії мого додатка:

Плаваюча кнопка дії мого додатка

Як я можу додати затінення до своєї кнопки?

Я вже використовував атрибут elevation, але не працює


1
API висоти призначений лише для льодяників, чи ви пробували пристрій для льодяників?
— Марк Плано-Лесай

2
Напевно, пора прийняти одну з поданих відповідей.
— Phantômaxx

Насправді на моєму 4.4.2 Samsung Galaxy S III тінь є завдяки 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" із вашої теми. Однак ви також можете використовувати floatingActionButton.setRippleColor (колір), не дозволяйте назві `` пульсація '' вас лякати, це також працює на пристроях перед льодяником.
— 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, який можна малювати, і який можна використовувати на пристроях перед льодяником для імітації висоти плаваючої кнопки дії.

<?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 як синглтон; встановити один раз, щоб більше не малювати. Можливо, ви можете отримати drawable як статичну змінну та встановити його як фон у onCreate?
— Джастін Поллард,

Також я додав вдосконалення, ви можете додати ефект пульсацій дуже просто, нижче наведено код.
— Амілкар Андраде

2
Для подальших довідок це чудовий приклад для уникнення тіней і підняття -> curious-creature.com/2008/12/18/avoid-memory-leaks-on-android/…
— Амілкар Андраде



4

@Justin Pollard xml-код працює дуже добре. Як додаткову примітку ви можете додати ефект пульсації за допомогою наступних рядків 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.