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

devpelux
źródło
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" />
user1354603
źródło
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

Justin Pollard
źródło
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>
Amilcar Andrade
źródło
2

Wypróbuj tę bibliotekę , obsługuje cień, istnieje minSdkVersion=7i obsługuje niejawnie android:elevationatrybut dla API-21.

Oryginalny post jest tutaj .

Oleksii K.
źródło
0

Dodaj dopełnienie i wysokość:

 android:elevation="10dp"
 android:padding="10dp"
Simas
źródło