Pustaka Dukungan Desain Android dengan menu Floating Action Button (FAB) yang dapat diperluas

172

Sekarang setelah Pustaka Dukungan Desain Android keluar, apakah ada yang tahu cara menerapkan menu Fab yang diperluas dengannya, seperti hebat di Aplikasi Kotak Masuk?

Seharusnya terlihat seperti ini:

masukkan deskripsi gambar di sini

EkKoZ
sumber
Saya sudah memeriksa semua dokumentasi tetapi ternyata tidak ada tanda-tanda menu FAB :(
EkKoZ
8
Anda dapat melihat di perpustakaan FloatingActionButton ini .
Markus Rubey
3
@MarkusRubey terima kasih, sebenarnya itulah yang saya gunakan saat ini, hanya saja saya ingin membuatnya dengan yang asli, tetapi tampaknya itu belum memungkinkan.
EkKoZ
Ada banyak perpustakaan open source, yang bisa menyelesaikan pekerjaan. Periksa yang ini: github.com/futuresimple/android-floating-action-button
capt.swag

Jawaban:

143

Saat ini, tidak ada widget yang disediakan di Perpustakaan Desain. Satu-satunya cara untuk melakukannya dengan cepat dan mudah adalah dengan menggunakan perpustakaan pihak ketiga.

Anda jelas dapat melakukan ini menggunakan Perpustakaan Desain juga, tetapi itu akan menjadi pekerjaan besar dan membutuhkan banyak waktu. Saya telah menyebutkan beberapa perpustakaan yang bermanfaat, yang dapat membantu Anda mencapai ini.

  1. Tombol Apung Cepat (wangjiegulu)
  2. Tombol Aksi Terapung (Klan)
  3. Tombol Aksi Mengambang (makovkastar)
  4. Android Floating Action Button (futuresimple)

Saya menggunakan yang ke-4.

Aritra Roy
sumber
31
baik, idenya adalah untuk melakukannya dengan perpustakaan desain asli, saya tahu ada banyak perpustakaan yang sudah melakukan fitur ini. terima kasih untuk balasan Anda.
EkKoZ
Apakah Anda menemukan masalah dengan yang keempat? Milik saya tidak muncul di perangkat lollipop +. Juga warna latar belakang teks dan teks tidak berfungsi
Ajith Memana
@AjithMemana Tidak. Aplikasi saya sedang dalam produksi untuk lebih dari 100 ribu pengguna dan saya tidak pernah mengalami masalah seperti yang Anda sebutkan.
Aritra Roy
Bisakah Anda memberi saya tautan ke aplikasi Anda? Saya perlu sesuatu yang mirip dengan yang ditunjukkan di atas, bersama dengan latar belakang transparan yang menutupi layar ketika tombol diklik.
Ajith Memana
2
Sebagai catatan, Klan dan makovkastar tidak lagi didukung. Saya menduga ini adalah karena perbaikan di perpustakaan desain FAB
Keberatan Jujur
162

Mendapat pendekatan yang lebih baik untuk menerapkan menu FAB animating tanpa menggunakan pustaka atau untuk menulis kode xml besar untuk animasi. Semoga ini akan membantu di masa depan bagi seseorang yang membutuhkan cara sederhana untuk mengimplementasikan ini.

Hanya dengan menggunakan animate().translationY()fungsi, Anda dapat menggerakkan tampilan mana pun naik atau turun seperti yang saya lakukan pada kode di bawah ini, periksa kode lengkap di github . Jika Anda mencari kode yang sama di kotlin, Anda dapat checkout kode kotlin repo Menu FAB Bergerak .

pertama-tama tentukan semua FAB Anda di tempat yang sama sehingga mereka saling tumpang tindih, ingat di atas FAB seharusnya Anda ingin mengklik dan menunjukkan yang lain. misalnya:

    <android.support.design.widget.FloatingActionButton
    android:id="@+id/fab3"
    android:layout_width="@dimen/standard_45"
    android:layout_height="@dimen/standard_45"
    android:layout_gravity="bottom|end"
    android:layout_margin="@dimen/standard_21"
    app:srcCompat="@android:drawable/ic_btn_speak_now" />

<android.support.design.widget.FloatingActionButton
    android:id="@+id/fab2"
    android:layout_width="@dimen/standard_45"
    android:layout_height="@dimen/standard_45"
    android:layout_gravity="bottom|end"
    android:layout_margin="@dimen/standard_21"
    app:srcCompat="@android:drawable/ic_menu_camera" />

<android.support.design.widget.FloatingActionButton
    android:id="@+id/fab1"
    android:layout_width="@dimen/standard_45"
    android:layout_height="@dimen/standard_45"
    android:layout_gravity="bottom|end"
    android:layout_margin="@dimen/standard_21"
    app:srcCompat="@android:drawable/ic_dialog_map" />

<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:layout_margin="@dimen/fab_margin"
    app:srcCompat="@android:drawable/ic_dialog_email" />

Sekarang di kelas java Anda cukup tentukan semua FAB Anda dan lakukan klik seperti yang ditunjukkan di bawah ini:

 FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
    fab1 = (FloatingActionButton) findViewById(R.id.fab1);
    fab2 = (FloatingActionButton) findViewById(R.id.fab2);
    fab3 = (FloatingActionButton) findViewById(R.id.fab3);
    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            if(!isFABOpen){
                showFABMenu();
            }else{
                closeFABMenu();
            }
        }
    });

Gunakan animation().translationY()untuk menghidupkan FAB Anda, saya lebih suka Anda menggunakan atribut metode ini di DP karena hanya menggunakan int akan mempengaruhi kompatibilitas tampilan dengan resolusi yang lebih tinggi atau resolusi yang lebih rendah. seperti yang ditunjukkan di bawah ini:

 private void showFABMenu(){
    isFABOpen=true;
    fab1.animate().translationY(-getResources().getDimension(R.dimen.standard_55));
    fab2.animate().translationY(-getResources().getDimension(R.dimen.standard_105));
    fab3.animate().translationY(-getResources().getDimension(R.dimen.standard_155));
}

private void closeFABMenu(){
    isFABOpen=false;
    fab1.animate().translationY(0);
    fab2.animate().translationY(0);
    fab3.animate().translationY(0);
}

Sekarang tentukan dimensi yang disebutkan di atas dalam res-> values-> dimens.xml seperti yang ditunjukkan di bawah ini:

    <dimen name="standard_55">55dp</dimen>
<dimen name="standard_105">105dp</dimen>
<dimen name="standard_155">155dp</dimen>

Itu semua berharap solusi ini akan membantu orang-orang di masa depan, yang sedang mencari solusi sederhana.

Diedit

Jika Anda ingin menambahkan label di atas FAB maka cukup ambil LinearLayout horizontal dan tempatkan FAB dengan tampilan teks sebagai label, dan hidupkan tata letak jika menemukan masalah saat melakukan ini, Anda dapat memeriksa kode sampel saya di github, saya telah menangani semua kompatibilitas mundur masalah dalam kode sampel itu. periksa kode sampel saya untuk FABMenu di Github

untuk menutup FAB pada Backpress, timpa onBackPress () seperti yang ditunjukkan di bawah ini:

    @Override
public void onBackPressed() {
    if(!isFABOpen){
        this.super.onBackPressed();
    }else{
        closeFABMenu();
    }
}

Screenshot memiliki judul juga dengan FAB, karena saya mengambilnya dari ingithub aplikasi sampel saya

masukkan deskripsi gambar di sini

HAXM
sumber
8
bahkan menambahkan label ke menu juga sederhana, Anda hanya perlu menambahkan FAB di dalam Linearlayout dengan beberapa textview sebagai label, dan setelah itu menghidupkan seluruh tata letak linier jangan lupa untuk menyembunyikan dan menampilkan tata letak linear di dalam fungsi buka dan tutup
HAXM
1
tetapi prashant telah membuat xml terpisah untuk animasi, tetapi solusi saya tidak memerlukan xml tambahan untuk animasi, jadi percayalah jawaban saya lebih baik, karena tidak perlu baris kode tambahan untuk menghidupkan tampilan.
HAXM
2
Itu jawaban terbaik. Anda dapat menggunakan FAB nyata dari pustaka desain dan itu tidak begitu penting.
Stephane Mathis
3
Apa yang saya juga suka tentang pendekatan ini adalah bahwa karena kita menggunakan FAB android, banyak pekerjaan dasar telah dilakukan. misalnya, alih-alih menulis perilaku tampilan khusus dari awal (karena perpustakaan tidak memperpanjang FAB), Anda hanya dapat memperluas perilaku fab asli, yang merupakan kumpulan besar kode yang sudah tersedia
RJFares
1
@droidHeaven mengambil framelayout dan tempatkan semua FAB Anda di dalamnya
HAXM
31
  • Pertama-tama buat layout menu di file xml Layout aktivitas Anda. Untuk misalnya tata letak linier dengan orientasi horizontal dan sertakan label TextView untuk kemudian Tombol Tindakan yang Mengambang di samping TextView.

  • Buat tata letak menu sesuai kebutuhan dan nomor Anda.

  • Buat Tombol Tindakan Mengambang Basis dan klik itu yang mengubah visibilitas Tata Letak Menu.

Silakan periksa kode di bawah ini untuk referensi dan untuk info lebih lanjut checkout proyek saya dari github

Proyek checkout dari Github

<android.support.constraint.ConstraintLayout
            android:id="@+id/activity_main"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            tools:context="com.app.fabmenu.MainActivity">

            <android.support.design.widget.FloatingActionButton
                android:id="@+id/baseFloatingActionButton"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginBottom="16dp"
                android:layout_marginEnd="16dp"
                android:layout_marginRight="16dp"
                android:clickable="true"
                android:onClick="@{FabHandler::onBaseFabClick}"
                android:tint="@android:color/white"
                app:fabSize="normal"
                app:layout_constraintBottom_toBottomOf="@+id/activity_main"
                app:layout_constraintRight_toRightOf="@+id/activity_main"
                app:srcCompat="@drawable/ic_add_black_24dp" />

            <LinearLayout
                android:id="@+id/shareLayout"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginBottom="12dp"
                android:layout_marginEnd="24dp"
                android:layout_marginRight="24dp"
                android:gravity="center_vertical"
                android:orientation="horizontal"
                android:visibility="invisible"
                app:layout_constraintBottom_toTopOf="@+id/createLayout"
                app:layout_constraintLeft_toLeftOf="@+id/createLayout"
                app:layout_constraintRight_toRightOf="@+id/activity_main">

                <TextView
                    android:id="@+id/shareLabelTextView"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginEnd="8dp"
                    android:layout_marginRight="8dp"
                    android:background="@drawable/shape_fab_label"
                    android:elevation="2dp"
                    android:fontFamily="sans-serif"
                    android:padding="5dip"
                    android:text="Share"
                    android:textColor="@android:color/white"
                    android:typeface="normal" />


                <android.support.design.widget.FloatingActionButton
                    android:id="@+id/shareFab"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:clickable="true"
                    android:onClick="@{FabHandler::onShareFabClick}"
                    android:tint="@android:color/white"
                    app:fabSize="mini"
                    app:srcCompat="@drawable/ic_share_black_24dp" />

            </LinearLayout>

            <LinearLayout
                android:id="@+id/createLayout"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginBottom="24dp"
                android:layout_marginEnd="24dp"
                android:layout_marginRight="24dp"
                android:gravity="center_vertical"
                android:orientation="horizontal"
                android:visibility="invisible"
                app:layout_constraintBottom_toTopOf="@+id/baseFloatingActionButton"
                app:layout_constraintRight_toRightOf="@+id/activity_main">

                <TextView
                    android:id="@+id/createLabelTextView"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginEnd="8dp"
                    android:layout_marginRight="8dp"
                    android:background="@drawable/shape_fab_label"
                    android:elevation="2dp"
                    android:fontFamily="sans-serif"
                    android:padding="5dip"
                    android:text="Create"
                    android:textColor="@android:color/white"
                    android:typeface="normal" />

                <android.support.design.widget.FloatingActionButton
                    android:id="@+id/createFab"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:clickable="true"
                    android:onClick="@{FabHandler::onCreateFabClick}"
                    android:tint="@android:color/white"
                    app:fabSize="mini"
                    app:srcCompat="@drawable/ic_create_black_24dp" />

            </LinearLayout>

        </android.support.constraint.ConstraintLayout>

Ini adalah animasi-

Animasi pembukaan Menu FAB:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="true">
<scale
    android:duration="300"
    android:fromXScale="0"
    android:fromYScale="0"
    android:interpolator="@android:anim/linear_interpolator"
    android:pivotX="50%"
    android:pivotY="50%"
    android:toXScale="1"
    android:toYScale="1" />
<alpha
    android:duration="300"
    android:fromAlpha="0.0"
    android:interpolator="@android:anim/accelerate_interpolator"
    android:toAlpha="1.0" />

</set>

Animasi Penutupan Menu FAB:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="true">
<scale
    android:duration="300"
    android:fromXScale="1"
    android:fromYScale="1"
    android:interpolator="@android:anim/linear_interpolator"
    android:pivotX="50%"
    android:pivotY="50%"
    android:toXScale="0.0"
    android:toYScale="0.0" />
<alpha
    android:duration="300"
    android:fromAlpha="1.0"
    android:interpolator="@android:anim/accelerate_interpolator"
    android:toAlpha="0.0" />
</set>

Kemudian di Aktivitas saya, saya cukup menggunakan animasi di atas untuk menampilkan dan menyembunyikan menu FAB:

Tampilkan Menu Hebat:

  private void expandFabMenu() {

    ViewCompat.animate(binding.baseFloatingActionButton).rotation(45.0F).withLayer().setDuration(300).setInterpolator(new OvershootInterpolator(10.0F)).start();
    binding.createLayout.startAnimation(fabOpenAnimation);
    binding.shareLayout.startAnimation(fabOpenAnimation);
    binding.createFab.setClickable(true);
    binding.shareFab.setClickable(true);
    isFabMenuOpen = true;

}

Tutup Menu Luar Biasa:

private void collapseFabMenu() {

    ViewCompat.animate(binding.baseFloatingActionButton).rotation(0.0F).withLayer().setDuration(300).setInterpolator(new OvershootInterpolator(10.0F)).start();
    binding.createLayout.startAnimation(fabCloseAnimation);
    binding.shareLayout.startAnimation(fabCloseAnimation);
    binding.createFab.setClickable(false);
    binding.shareFab.setClickable(false);
    isFabMenuOpen = false;

}

Ini adalah kelas Activity -

package com.app.fabmenu;

import android.databinding.DataBindingUtil;
import android.os.Bundle;
import android.support.design.widget.Snackbar;
import android.support.v4.view.ViewCompat;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.OvershootInterpolator;

import com.app.fabmenu.databinding.ActivityMainBinding;

public class MainActivity extends AppCompatActivity {

private ActivityMainBinding binding;
private Animation fabOpenAnimation;
private Animation fabCloseAnimation;
private boolean isFabMenuOpen = false;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    binding = DataBindingUtil.setContentView(this,    R.layout.activity_main);
    binding.setFabHandler(new FabHandler());

    getAnimations();


}

private void getAnimations() {

    fabOpenAnimation = AnimationUtils.loadAnimation(this, R.anim.fab_open);

    fabCloseAnimation = AnimationUtils.loadAnimation(this, R.anim.fab_close);

}

private void expandFabMenu() {

    ViewCompat.animate(binding.baseFloatingActionButton).rotation(45.0F).withLayer().setDuration(300).setInterpolator(new OvershootInterpolator(10.0F)).start();
    binding.createLayout.startAnimation(fabOpenAnimation);
    binding.shareLayout.startAnimation(fabOpenAnimation);
    binding.createFab.setClickable(true);
    binding.shareFab.setClickable(true);
    isFabMenuOpen = true;


}

private void collapseFabMenu() {

    ViewCompat.animate(binding.baseFloatingActionButton).rotation(0.0F).withLayer().setDuration(300).setInterpolator(new OvershootInterpolator(10.0F)).start();
    binding.createLayout.startAnimation(fabCloseAnimation);
    binding.shareLayout.startAnimation(fabCloseAnimation);
    binding.createFab.setClickable(false);
    binding.shareFab.setClickable(false);
    isFabMenuOpen = false;

}


public class FabHandler {

    public void onBaseFabClick(View view) {

        if (isFabMenuOpen)
            collapseFabMenu();
        else
            expandFabMenu();


    }

    public void onCreateFabClick(View view) {

        Snackbar.make(binding.coordinatorLayout, "Create FAB tapped", Snackbar.LENGTH_SHORT).show();

    }

    public void onShareFabClick(View view) {

        Snackbar.make(binding.coordinatorLayout, "Share FAB tapped", Snackbar.LENGTH_SHORT).show();

    }


}

@Override
public void onBackPressed() {

    if (isFabMenuOpen)
        collapseFabMenu();
    else
        super.onBackPressed();
}
}

Berikut screenshotnya

Floating Action Menu dengan Label Textview di Cursive Font Family baru Android

Floating Action Menu dengan Label Textview di Roboto Font Family baru Android

Prashant
sumber
7

Ketika saya mencoba untuk membuat sesuatu yang mirip dengan tombol aksi mengambang inbox saya berpikir tentang membuat komponen kustom sendiri.

Ini akan menjadi tata letak bingkai sederhana dengan ketinggian tetap (berisi menu yang diperluas) yang berisi tombol FAB dan 3 lagi ditempatkan di bawah FAB. ketika Anda mengklik FAB, Anda cukup menghidupkan tombol lain untuk menerjemahkan dari bawah FAB.

Ada beberapa perpustakaan yang melakukan itu (misalnya https://github.com/futuresimple/android-floating-action-button ), tetapi selalu lebih menyenangkan jika Anda membuatnya sendiri :)

rwojcik
sumber
Penjelasan yang bagus! Saya menjelajahi perpustakaan itu tetapi saya mengalami kesulitan menggunakannya untuk menyelaraskan FAB antara dua Tampilan. Agak apa yang ditanyakan dalam pertanyaan ini stackoverflow.com/questions/24459352/… . Adakah yang tahu bagaimana melakukannya? layout_anchordan layout_anchorGravitytidak bekerja untuk saya
acrespo
Pustaka Futuresimple tidak mengizinkan ikon unik pada plus yang datang secara default ke elemen FloatingActionMenu
Odaym
7

Anda dapat menggunakan perpustakaan FloatingActionMenu atau klik di sini untuk tutorial langkah demi langkah. Output dari tutorial:

masukkan deskripsi gambar di sini

Pasifik P. Regmi
sumber
Sederhana dan berfungsi dengan baik. Saya menyarankan Anda menambahkan rincian di sini daripada menautkan tutorial jika tautannya turun di masa mendatang. Hal lain, saya baru tahu bahwa perpustakaan tidak lagi dalam pengembangan, sayangnya.
Ahmed salah
3

Saya menggunakan perpustakaan ini untuk melakukan ini: https://github.com/futuresimple/android-floating-action-button

Cukup mudah digunakan;)

masukkan deskripsi gambar di sini

sampanye kemerahan
sumber
Beberapa komentar yang saya buat untuk jawaban serupa lainnya. Saya mengalami kesulitan menggunakannya untuk menyelaraskan FAB antara dua Tampilan. Agak apa yang ditanyakan dalam pertanyaan ini stackoverflow.com/questions/24459352/… . Adakah yang tahu bagaimana melakukannya? layout_anchordan layout_anchorGravitytidak bekerja untuk saya
acrespo
0

Pilihan lain untuk hasil yang sama dengan animasi ConstraintSet:

contoh animasi hebat

1) Letakkan semua tampilan animasi dalam satu ConstraintLayout

2) Buat animasi dari kode seperti ini (jika Anda ingin beberapa efek lagi terserah Anda..ini hanya contoh)

menuItem1 dan menuItem2 adalah FAB pertama dan kedua dalam menu, descriptionItem1 dan descriptionItem2 adalah deskripsi di sebelah kiri menu, parentConstraintLayout adalah root ConstraintLayout yang berisi semua tampilan animasi, adalahMenuOpened adalah beberapa fungsi untuk mengubah bendera terbuka / tertutup di negara bagian

Saya memasukkan kode animasi dalam file ekstensi tetapi itu tidak perlu.

fun FloatingActionButton.expandMenu(
    menuItem1: View,
    menuItem2: View,
    descriptionItem1: TextView,
    descriptionItem2: TextView,
    parentConstraintLayout: ConstraintLayout,
    isMenuOpened: (Boolean)-> Unit
) {
    val constraintSet = ConstraintSet()
    constraintSet.clone(parentConstraintLayout)

    constraintSet.setVisibility(descriptionItem1.id, View.VISIBLE)
    constraintSet.clear(menuItem1.id, ConstraintSet.TOP)
    constraintSet.connect(menuItem1.id, ConstraintSet.BOTTOM, this.id, ConstraintSet.TOP, 0)
    constraintSet.connect(menuItem1.id, ConstraintSet.START, this.id, ConstraintSet.START, 0)
    constraintSet.connect(menuItem1.id, ConstraintSet.END, this.id, ConstraintSet.END, 0)

    constraintSet.setVisibility(descriptionItem2.id, View.VISIBLE)
    constraintSet.clear(menuItem2.id, ConstraintSet.TOP)
    constraintSet.connect(menuItem2.id, ConstraintSet.BOTTOM, menuItem1.id, ConstraintSet.TOP, 0)
    constraintSet.connect(menuItem2.id, ConstraintSet.START, this.id, ConstraintSet.START, 0)
    constraintSet.connect(menuItem2.id, ConstraintSet.END, this.id, ConstraintSet.END, 0)

    val transition = AutoTransition()
    transition.duration = 150
    transition.interpolator = AccelerateInterpolator()

    transition.addListener(object: Transition.TransitionListener {
        override fun onTransitionEnd(p0: Transition) {
            isMenuOpened(true)
        }
        override fun onTransitionResume(p0: Transition) {}
        override fun onTransitionPause(p0: Transition) {}
        override fun onTransitionCancel(p0: Transition) {}
        override fun onTransitionStart(p0: Transition) {}
    })

    TransitionManager.beginDelayedTransition(parentConstraintLayout, transition)
    constraintSet.applyTo(parentConstraintLayout)
}
Konstantin Kuznetsov
sumber