Como posso adicionar o novo "Botão de ação flutuante" entre dois widgets / layouts

287

Eu acho que você viu as novas diretrizes de design para Android, com o novo "Botão de ação flutuante", também conhecido como "FAB"

Por exemplo, este botão rosa:

insira a descrição da imagem aqui

Minha pergunta parece estúpida, e eu já tentei muitas coisas, mas qual é a melhor maneira de colocar esse botão na interseção de dois layouts?

No exemplo acima, esse botão está perfeitamente posicionado entre o que podemos imaginar como um ImageView e um relativoLayout.

Eu já tentei muitos ajustes, mas estou convencido de que existe uma maneira adequada de fazer isso.

Waza_Be
fonte
Você pode posicionar os layouts dentro de um layout e posicione o botão em que o layout
Chrome Pinguim Studios
1
Acho que esta biblioteca pode ajudar muito: github.com/ksoichiro/Android-ObservableScrollView
desenvolvedor android
Como ocultá-lo durante a rolagem? Estou enfrentando um problema, onde, se eu rolar a página, a Fab permanece no topo e não está escondida! Por favor ajude
Anish Kumar

Respostas:

473

Melhor prática:

  • Adicionar compile 'com.android.support:design:25.0.1'ao arquivo gradle
  • Use CoordinatorLayoutcomo visualização raiz.
  • Adicione layout_anchorao FAB e defina-o para a vista superior
  • Adicione layout_anchorGravityao FAB e configure-o para:bottom|right|end

insira a descrição da imagem aqui

<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <LinearLayout
            android:id="@+id/viewA"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="0.6"
            android:background="@android:color/holo_purple"
            android:orientation="horizontal"/>

        <LinearLayout
            android:id="@+id/viewB"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="0.4"
            android:background="@android:color/holo_orange_light"
            android:orientation="horizontal"/>

    </LinearLayout>

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="16dp"
        android:clickable="true"
        android:src="@drawable/ic_done"
        app:layout_anchor="@id/viewA"
        app:layout_anchorGravity="bottom|right|end"/>

</android.support.design.widget.CoordinatorLayout>
David
fonte
3
@ Aprendiz Eu também gostaria de uma citação, mas posso ver por que essa é uma resposta melhor do que a de HughJeffner. Acho que é mais simples, mais flexível e menos burro. Você não codifica nenhum valor de layout_height ou margin, que pode variar no tempo ou ser definido dinamicamente. A resposta de Hugh poderia funcionar em alguns casos simples, e talvez poderia ser uma solução para algumas bibliotecas de terceiros que não suportam totalmente CoordinatorLayoute layout_anchore layout_anchorGravitycaracterísticas, como o que ele está usando, futuresimples .
acrespo
1
Btw futuresimples é uma biblioteca IMPRESSIONANTE, e, caso alguém esteja se perguntando se existe um garfo que combine essa CoordinatorLayoutabordagem com essa biblioteca, veja . E também há um garfo para versões mais antigas.
acrespo
2
Eu estava procurando exatamente isso. +1 por simplicidade.
Emiliano De Santis
29
Por que tudo isso não está na documentação do Android?
Mostafa
3
usando app: layout_anchor me causando um problema de renderização (LinearLayout layoutparams não pode ser convertido para coordinatorlayout :(.
DAVIDBALAS1
91

Parece que a maneira mais limpa neste exemplo é:

  • Use um RelativeLayout
  • Posicione as 2 vistas adjacentes uma abaixo da outra
  • Alinhe o FAB à direita / final pai e adicione uma margem direita / final
  • Alinhe o FAB na parte inferior da visualização do cabeçalho e adicione uma margem negativa , metade do tamanho do FAB, incluindo sombra

Exemplo adaptado da implementação de shamanland, use o FAB que você desejar. Suponha que o FAB tenha 64dp de altura, incluindo sombra:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <View
        android:id="@+id/header"
        android:layout_width="match_parent"
        android:layout_height="120dp"
    />

    <View
        android:id="@+id/body"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@id/header"
    />

    <fully.qualified.name.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_alignBottom="@id/header"
        android:layout_marginBottom="-32dp"
        android:layout_marginRight="20dp"
    />

</RelativeLayout>

Exemplo de layout da FAB

Hugh Jeffner
fonte
Esse layout fez o truque para mim! Estou usando FABpor futuresimple - é muito simples de adicionar e usar, divirta-se!
Roman
Como você disse: "Posicione as duas vistas adjacentes uma abaixo da outra" -> esse foi o problema que eu tive, mas eu esqueci que meu "layout do contêiner" estava estragado por não combinar colchetes: D Obrigado: P
Martin Pfeffer
Esta não é uma boa solução. A margem negativa parece eliminar a metade inferior do alvo de toque do botão. Os cliques não são registrados se eu pressionar a metade inferior da marca.
Doronz
1
@Doronz Hmm, parece que não tenho esse problema. Suas opiniões estão na ordem certa, ou seja, a FAB é a camada superior?
precisa saber é o seguinte
23
android: layout_marginBottom = "- 32dp" o valor codificado com o wrap_content do botão é uma solução ruim
Lester
51

Você pode importar o projeto de amostra do Google no Android Studio clicando em Arquivo> Importar amostra ...

Amostra de importação

Este exemplo contém uma exibição FloatingActionButton que herda de FrameLayout.

Editar Com a nova Biblioteca de Design de Suporte, você pode implementá-la como neste exemplo: https://github.com/chrisbanes/cheesesquare

Roel
fonte
1
Você deve ter o android-21 para executá-lo.
Yuliia Ashomok
Você deve usar a Biblioteca de Design de Suporte se desejar usar um FloatingActionButton. Veja o quadrado de queijo do Google.
Roel
16

Com o AppCompat 22, o FAB é suportado para dispositivos mais antigos.

Adicione a nova biblioteca de suporte ao seu build.gradle (app):

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

Então você pode usá-lo em seu xml:

<android.support.design.widget.FloatingActionButton
    android:id="@+id/fab"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom|end"
    android:src="@android:drawable/ic_menu_more"
    app:elevation="6dp"
    app:pressedTranslationZ="12dp" />

Para usar elevatione pressedTranslationZpropriedades, appé necessário um espaço para nome; portanto, adicione esse espaço para seu layout: xmlns:app="http://schemas.android.com/apk/res-auto"

Oded Breiner
fonte
3
adicionar informações sobre o appespaço para nome
Lukasz 'Severiaan' Grela 07/07/2015
14

Agora faz parte da Biblioteca oficial de suporte a projetos.

No seu gradle:

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

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

Veronnie
fonte
5
Sua resposta é um pouco clara e vaga. Você poderia explicar melhor o que faz parte da DSL e talvez citar as informações relevantes dessa página.
SuperBiasedMan
Desculpe, eu já vi muitas referências a bibliotecas externas, então eu queria apontar para a biblioteca oficial. A biblioteca pode criar apenas um botão, mas o posicionamento está nos desenvolvedores. Portanto, meu post não é muito relevante, desculpe.
Veronnie
12

Experimente esta biblioteca (o javadoc está aqui ), o nível mínimo da API é 7:

dependencies {
    compile 'com.shamanland:fab:0.0.8'
}

Ele fornece um único widget com a capacidade de personalizá-lo via Theme, xml ou java-code.

luz entre

É muito simples de usar. Há disponibilidade normale miniimplementação de acordo com o padrão de Ações Promovidas .

<com.shamanland.fab.FloatingActionButton
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/ic_action_my"
    app:floatingActionButtonColor="@color/my_fab_color"
    app:floatingActionButtonSize="mini"
    />

Tente compilar o aplicativo de demonstração . Há um exemplo exaustivo: temas claros e escuros, usando com ListView, alinhar entre dois modos de exibição .

Oleksii K.
fonte
3
Apenas para adicionar a esta resposta ^ Você também pode usar as outras bibliotecas de backport disponíveis, como: github.com/FaizMalkani/FloatingActionButton e github.com/makovkastar/FloatingActionButton . Ambos podem parecer ter mais apoio. Mas basta seguir a exibição Detalhes da fonte listada nesta resposta. Funciona bem.
John Shelley
é a biblioteca oficial?
Cocorico
não há biblioteca oficial. este é o meu lib com fontes abertas.
precisa
Este botão de ação flutuante é um mau exemplo de como implementá-lo. Ele não segue as verdadeiras diretrizes de design de material.
Michael Michael
@ Mike Milla, o que há de errado com esta lib? quais requisitos não são atendidos?
precisa
6

Mantenha-o simples Adicionando botão de ação flutuante usando o TextView, fornecendo um fundo xml arredondado. - Adicionar compilação com.android.support:design:23.1.1ao arquivo gradle

  • Use o CoordinatorLayout como visualização raiz.
  • Antes de finalizar o CoordinatorLayout, introduza um textView.
  • Dentro de Drawable, desenhe um círculo.

O círculo Xml é

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

    <solid
        android:color="@color/colorPrimary"/>
    <size
        android:width="30dp"
        android:height="30dp"/>
</shape>

O xml de layout é

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">


<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:weightSum="5"
    >

    <RelativeLayout
        android:id="@+id/viewA"
        android:layout_height="0dp"
        android:layout_width="match_parent"
        android:layout_weight="1.6"
        android:background="@drawable/contact_bg"
        android:gravity="center_horizontal|center_vertical"
        >
        </RelativeLayout>

    <LinearLayout
        android:layout_height="0dp"
        android:layout_width="match_parent"
        android:layout_weight="3.4"
        android:orientation="vertical"
        android:padding="16dp"
        android:weightSum="10"
        >

        <LinearLayout
            android:layout_height="0dp"
            android:layout_width="match_parent"
            android:layout_weight="1"
            >
            </LinearLayout>

        <LinearLayout
            android:layout_height="0dp"
            android:layout_width="match_parent"
            android:layout_weight="1"
            android:weightSum="4"
            android:orientation="horizontal"
            >
            <TextView
                android:layout_height="match_parent"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:text="Name"
                android:textSize="22dp"
                android:textColor="@android:color/black"
                android:padding="3dp"
                />

            <TextView
                android:id="@+id/name"
                android:layout_height="match_parent"
                android:layout_width="0dp"
                android:layout_weight="3"
                android:text="Ritesh Kumar Singh"
                android:singleLine="true"
                android:textSize="22dp"
                android:textColor="@android:color/black"
                android:padding="3dp"
                />

            </LinearLayout>



        <LinearLayout
            android:layout_height="0dp"
            android:layout_width="match_parent"
            android:layout_weight="1"
            android:weightSum="4"
            android:orientation="horizontal"
            >
            <TextView
                android:layout_height="match_parent"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:text="Phone"
                android:textSize="22dp"
                android:textColor="@android:color/black"
                android:padding="3dp"
                />

            <TextView
                android:id="@+id/number"
                android:layout_height="match_parent"
                android:layout_width="0dp"
                android:layout_weight="3"
                android:text="8283001122"
                android:textSize="22dp"
                android:textColor="@android:color/black"
                android:singleLine="true"
                android:padding="3dp"
                />

        </LinearLayout>



        <LinearLayout
            android:layout_height="0dp"
            android:layout_width="match_parent"
            android:layout_weight="1"
            android:weightSum="4"
            android:orientation="horizontal"
            >
            <TextView
                android:layout_height="match_parent"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:text="Email"
                android:textSize="22dp"
                android:textColor="@android:color/black"
                android:padding="3dp"
                />

            <TextView
                android:layout_height="match_parent"
                android:layout_width="0dp"
                android:layout_weight="3"
                android:text="[email protected]"
                android:textSize="22dp"
                android:singleLine="true"
                android:textColor="@android:color/black"
                android:padding="3dp"
                />

        </LinearLayout>


        <LinearLayout
            android:layout_height="0dp"
            android:layout_width="match_parent"
            android:layout_weight="1"
            android:weightSum="4"
            android:orientation="horizontal"
            >
            <TextView
                android:layout_height="match_parent"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:text="City"
                android:textSize="22dp"
                android:textColor="@android:color/black"
                android:padding="3dp"
                />

            <TextView
                android:layout_height="match_parent"
                android:layout_width="0dp"
                android:layout_weight="3"
                android:text="Panchkula"
                android:textSize="22dp"
                android:textColor="@android:color/black"
                android:singleLine="true"
                android:padding="3dp"
                />

        </LinearLayout>

    </LinearLayout>

</LinearLayout>


    <TextView
        android:id="@+id/floating"
        android:transitionName="@string/transition_name_circle"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_margin="16dp"
        android:clickable="false"
        android:background="@drawable/circle"
        android:elevation="10dp"
        android:text="R"
        android:textSize="40dp"
        android:gravity="center"
        android:textColor="@android:color/black"
        app:layout_anchor="@id/viewA"
        app:layout_anchorGravity="bottom"/>

        </android.support.design.widget.CoordinatorLayout>

Clique aqui para ver como será

Ritesh
fonte
5

Adicione isso ao seu arquivo gradle

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:23.0.0'
    compile 'com.android.support:design:23.0.1'
}

Isso para o seu activity_main.xml

<android.support.design.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <LinearLayout android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

            <LinearLayout
                android:id="@+id/viewOne"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_weight="0.6"
                android:background="@android:color/holo_blue_light"
                android:orientation="horizontal"/>

            <LinearLayout
                android:id="@+id/viewTwo"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_weight="0.4"
                android:background="@android:color/holo_orange_light"
                android:orientation="horizontal"/>

        </LinearLayout>

        <android.support.design.widget.FloatingActionButton
            android:id="@+id/floatingButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="16dp"
            android:clickable="true"
            android:src="@drawable/ic_done"
            app:layout_anchor="@id/viewOne"
            app:layout_anchorGravity="bottom|right|end"
            app:backgroundTint="#FF0000"
            app:rippleColor="#FFF" />

    </android.support.design.widget.CoordinatorLayout>

Você pode encontrar o exemplo completo com o projeto android studio para fazer o download em http://www.ahotbrew.com/android-floating-action-button/

Gurinder Singh
fonte
1

aqui está o código de trabalho.

eu uso appBarLayout para ancorar meu floatingActionButton.Espero que isso possa ser útil.

CÓDIGO XML.

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appbar"
        android:layout_height="192dp"
        android:layout_width="match_parent">

        <android.support.design.widget.CollapsingToolbarLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:toolbarId="@+id/toolbar"
            app:titleEnabled="true"
            app:layout_scrollFlags="scroll|enterAlways|exitUntilCollapsed"
            android:id="@+id/collapsingbar"
            app:contentScrim="?attr/colorPrimary">

            <android.support.v7.widget.Toolbar
                app:layout_collapseMode="pin"
                android:id="@+id/toolbarItemDetailsView"
                android:layout_height="?attr/actionBarSize"
                android:layout_width="match_parent"></android.support.v7.widget.Toolbar>
        </android.support.design.widget.CollapsingToolbarLayout>
    </android.support.design.widget.AppBarLayout>

    <android.support.v4.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="android.support.design.widget.AppBarLayout$ScrollingViewBehavior">

        <android.support.constraint.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            tools:context="com.example.rktech.myshoplist.Item_details_views">
            <RelativeLayout
                android:orientation="vertical"
                android:focusableInTouchMode="true"
                android:layout_width="match_parent"
                android:layout_height="match_parent">


                <!--Put Image here -->
                <ImageView
                    android:visibility="gone"
                    android:layout_marginTop="56dp"
                    android:layout_width="match_parent"
                    android:layout_height="230dp"
                    android:scaleType="centerCrop"
                    android:src="@drawable/third" />


                <ScrollView
                    android:layout_width="match_parent"
                    android:layout_height="match_parent">

                    <RelativeLayout
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        android:layout_gravity="center"
                        android:orientation="vertical">

                        <android.support.v7.widget.CardView
                            android:layout_width="match_parent"
                            android:layout_height="match_parent"
                            app:cardCornerRadius="4dp"
                            app:cardElevation="4dp"
                            app:cardMaxElevation="6dp"
                            app:cardUseCompatPadding="true">

                            <RelativeLayout
                                android:layout_width="match_parent"
                                android:layout_height="match_parent"
                                android:layout_margin="8dp"
                                android:padding="3dp">


                                <LinearLayout
                                    android:layout_width="match_parent"
                                    android:layout_height="match_parent"
                                    android:orientation="vertical">


                                    <TextView
                                        android:id="@+id/txtDetailItemTitle"
                                        style="@style/TextAppearance.AppCompat.Title"
                                        android:layout_width="match_parent"
                                        android:layout_height="wrap_content"
                                        android:layout_marginLeft="4dp"
                                        android:text="Title" />

                                    <LinearLayout
                                        android:layout_width="match_parent"
                                        android:layout_height="match_parent"
                                        android:layout_marginTop="8dp"
                                        android:orientation="horizontal">

                                        <TextView
                                            android:id="@+id/txtDetailItemSeller"
                                            style="@style/TextAppearance.AppCompat.Subhead"
                                            android:layout_width="wrap_content"
                                            android:layout_height="wrap_content"
                                            android:layout_marginLeft="4dp"
                                            android:layout_weight="1"
                                            android:text="Shope Name" />

                                        <TextView
                                            android:id="@+id/txtDetailItemDate"
                                            style="@style/TextAppearance.AppCompat.Subhead"
                                            android:layout_width="wrap_content"
                                            android:layout_height="wrap_content"
                                            android:layout_marginRight="4dp"
                                            android:gravity="right"
                                            android:text="Date" />


                                    </LinearLayout>

                                    <TextView
                                        android:id="@+id/txtDetailItemDescription"
                                        style="@style/TextAppearance.AppCompat.Medium"
                                        android:layout_width="match_parent"
                                        android:minLines="5"
                                        android:layout_height="wrap_content"
                                        android:layout_marginLeft="4dp"
                                        android:layout_marginTop="16dp"
                                        android:text="description" />

                                    <LinearLayout
                                        android:layout_width="match_parent"
                                        android:layout_height="wrap_content"
                                        android:layout_marginBottom="8dp"
                                        android:orientation="horizontal">

                                        <TextView
                                            android:id="@+id/txtDetailItemQty"
                                            style="@style/TextAppearance.AppCompat.Medium"
                                            android:layout_width="wrap_content"
                                            android:layout_height="wrap_content"
                                            android:layout_marginLeft="4dp"
                                            android:layout_weight="1"
                                            android:text="Qunatity" />

                                        <TextView
                                            android:id="@+id/txtDetailItemMessure"
                                            style="@style/TextAppearance.AppCompat.Medium"
                                            android:layout_width="wrap_content"
                                            android:layout_height="wrap_content"
                                            android:layout_marginRight="4dp"
                                            android:layout_weight="1"
                                            android:gravity="right"
                                            android:text="Messure in Gram" />
                                    </LinearLayout>


                                    <TextView
                                        android:id="@+id/txtDetailItemPrice"
                                        style="@style/TextAppearance.AppCompat.Headline"
                                        android:layout_width="match_parent"
                                        android:layout_height="wrap_content"
                                        android:layout_marginRight="4dp"
                                        android:layout_weight="1"
                                        android:gravity="right"
                                        android:text="Price" />
                                </LinearLayout>

                            </RelativeLayout>
                        </android.support.v7.widget.CardView>
                    </RelativeLayout>
                </ScrollView>
            </RelativeLayout>

        </android.support.constraint.ConstraintLayout>

    </android.support.v4.widget.NestedScrollView>

    <android.support.design.widget.FloatingActionButton
        android:layout_width="wrap_content"
        app:layout_anchor="@id/appbar"
        app:fabSize="normal"
        app:layout_anchorGravity="bottom|right|end"
        android:layout_marginEnd="@dimen/_6sdp"
        android:src="@drawable/ic_done_black_24dp"
        android:layout_height="wrap_content" />

</android.support.design.widget.CoordinatorLayout>

Agora, se você colar o código acima. você verá o seguinte resultado no seu dispositivo. Imagem do resultado

Rk215 Tech
fonte