Jak utworzyć pływający przycisk akcji (FAB) w systemie Android za pomocą AppCompat v21?


79

Chciałbym utworzyć pływający przycisk akcji (aby dodać elementy do widoku listy), taki jak kalendarz Google, zachowując zgodność z wersjami Androida sprzed wersji Lollipop (przed 5.0).

Stworzyłem ten układ:

Aktywność 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>

Rysowany 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 styles.xml

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

Rezultat jest podobny, ale nie ma cieniowania, charakterystycznego dla Material Design:

Pływający przycisk akcji kalendarza:

Pływający przycisk akcji kalendarza

Pływający przycisk akcji mojej aplikacji:

Pływający przycisk akcji mojej aplikacji

Jak mogę dodać cieniowanie do mojego przycisku?

Użyłem już podniesienia atrybutu, ale nie działa


1
Interfejs API elewacji jest dostępny tylko w wersji Lollipop. Czy wypróbowałeś urządzenie Lollipop?
— Marc Plano-Lesay

2
Prawdopodobnie już czas, abyś zaakceptował jedną z podanych odpowiedzi.
— Phantômaxx

W rzeczywistości na moim Samsungu Galaxy S III 4.4.2 cień jest dzięki AppCompat.
— FractalBob

Odpowiedzi:


100

Nie ma już potrzeby tworzenia własnego FABa ani korzystania z biblioteki innej firmy, zostało to uwzględnione w AppCompat 22.

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

Po prostu dodaj nową bibliotekę wsparcia o nazwie projektowanie w swoim pliku gradle:

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

... i jesteś gotowy:

<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
jak zmienić kolor tła?
— Jjang

2
Domyślnym kolorem tła będzie „colorAccent” z motywu. Możesz jednak również użyć floatingActionButton.setRippleColor (color), nie pozwól, aby nazwa „ripple” Cię przestraszyła, działa również na urządzeniach typu pre-Lollipop.
— user1354603

Nie mam colorAccent, a jeśli dodam jeden i ustawię kolor na inny, to nie działa - kolor przykleja się do zielonego / turkusowego.
— Jjang

Używałem do tego osoby trzeciej. Naprawdę bardzo mi pomogło. Dzięki. Jednym z problemów jest to, że nadal wydaje się, że nie jest całkowicie rozwinięty.
— V_J,

1
@Jjang @ user1354603 from docsThe 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).
— Muhammad Babar

43

Generalnie używałem elementów rysunkowych XML do tworzenia cienia / elewacji na widżecie pre-lollipop. Tutaj, na przykład, jest plik XML do rysowania, którego można używać na urządzeniach typu pre-Lollipop do symulowania podniesienia pływającego przycisku akcji.

<?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>

W jej miejsce ?attr/colorPrimarymożesz wybrać dowolny kolor. Oto zrzut ekranu z wynikiem:

wprowadź opis obrazu tutaj


1
Dziękuję za udostępnienie tego. Bałem się ponownie wykopać kod XML, aby go odtworzyć.
— Cookster

Zaimplementowałem właśnie teraz i jest super, jest tylko jedna dziwna rzecz. Wygląda na to, że podczas obracania telefonu gubi się cień / elewacja. Jakieś przemyślenia na ten temat? Z góry dziękuję Justin
— Amilcar Andrade

@AmilcarAndrade to dobre pytanie. Napotkałem podobne rzeczy z innymi elementami rysunkowymi XML, ale w rzeczywistości wyodrębniłem mapę bitową z samego rysunku. Aby to rozwiązać, zasadniczo użyłem drawable jako singletona; ustawiony raz, aby nie był ponownie rysowany. Być może uda Ci się pobrać tę możliwą do rysowania jako zmienną statyczną i ustawić jako tło w onCreate?
— Justin Pollard,

Dodałem również ulepszenie, które można dodać bardzo łatwo, poniżej jest kod.
— Amilcar Andrade

2
Dla przyszłych odniesień jest to świetny przykład unikania cieni i wzniesień -> curious-creature.com/2008/12/18/avoid-memory-leaks-on-android/ ...
— Amilcar Andrade



4

Kod xml @Justina Pollarda działa naprawdę dobrze. Na marginesie możesz dodać efekt tętnienia za pomocą następujących linii 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>


0

Dodaj dopełnienie i wysokość:

 android:elevation="10dp"
 android:padding="10dp"
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.