Як створити плаваючу кнопку дії (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.