Artık Android Tasarım Destek Kütüphanesi çıktı, kimse Inbox App fab gibi onunla genişletilmiş Fab menüsünü uygulamak biliyor mu?
Şöyle görünmelidir:
Artık Android Tasarım Destek Kütüphanesi çıktı, kimse Inbox App fab gibi onunla genişletilmiş Fab menüsünü uygulamak biliyor mu?
Şöyle görünmelidir:
Yanıtlar:
Şu anda, Tasarım Kitaplığı'nda bir pencere öğesi yoktur. Bunu hızlı ve kolay yapmanın tek yolu üçüncü taraf kütüphaneleri kullanmaktır.
Bunu açıkça Tasarım Kitaplığı'nı kullanarak da yapabilirsiniz, ancak çok büyük bir çalışma olacak ve çok zaman alacaktır. Bunu başarmanıza yardımcı olabilecek bazı yararlı kütüphanelerden bahsettim.
Ben dördüncüsünü kullanıyorum.
Animasyonlu FAB menüsünü herhangi bir kütüphane kullanmadan uygulamak veya animasyonlar için büyük xml kodu yazmak için daha iyi bir yaklaşım var. umarım bu, bunu uygulamak için basit bir yola ihtiyaç duyan biri için gelecekte yardımcı olacaktır.
Sadece animate().translationY()
fonksiyonunu kullanarak , aşağıdaki kodumda yaptığım herhangi bir görünümü yukarı veya aşağı canlandırabilir , github'da tam kodu kontrol edebilirsiniz . Kotlin'de aynı kodu arıyorsanız, kotlin kodu repo Animasyon FAB Menüsünü kontrol edebilirsiniz .
önce tüm FAB'nizi aynı yerde tanımlayın, böylece birbirleriyle örtüşürler, FAB'yi tıklayıp diğerini göstermek istediğiniz olmalıdır. Örneğin:
<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" />
Şimdi java sınıfınızda tüm FAB'nizi tanımlayın ve aşağıda gösterildiği gibi tıklayın:
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();
}
}
});
Kullan animation().translationY()
senin FAB canlandırmak, ben sadece daha yüksek veya daha düşük çözünürlüklü çözünürlüğe sahip ekran uyumluluğu etkileyecek bir int kullanarak beri DP bu yöntemin özelliği kullanmayı tercih ediyorum. Aşağıda gösterildiği gibi:
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);
}
Şimdi yukarıda belirtilen boyutu aşağıda gösterildiği gibi res-> değerleri-> dimens.xml içinde tanımlayın:
<dimen name="standard_55">55dp</dimen>
<dimen name="standard_105">105dp</dimen>
<dimen name="standard_155">155dp</dimen>
Bu çözümün gelecekte basit çözüm arayan insanlara yardımcı olacağını umuyoruz.
REDAKTE
FAB üzerine etiket eklemek istiyorsanız, yatay bir LinearLayout alın ve etiket olarak textview ile FAB'yi koyun ve bunu yaparken herhangi bir sorun bulursanız, düzenleri canlandırın, örnek kodumu github'da kontrol edebilirsiniz, geriye dönük uyumluluğa el koydum Bu örnek koddaki sorunlar. Github'daki FABMenu için örnek kodumu kontrol et
Backpress'teki FAB'yi kapatmak için onBackPress () öğesini aşağıda gösterildiği gibi geçersiz kılın:
@Override
public void onBackPressed() {
if(!isFABOpen){
this.super.onBackPressed();
}else{
closeFABMenu();
}
}
Ekran Görüntüsü FAB ile de başlık var, çünkü ben örnek uygulama mevcut ingithub almak
Önce Etkinlik düzeni xml dosyanızda menü düzenlerini oluşturun. Örneğin, yatay yönlendirmeli doğrusal bir düzen ve etiket için bir TextView, ardından TextView'in yanında bir Kayan İşlem Düğmesi ekleyin.
İhtiyacınıza ve numaranıza göre menü düzenleri oluşturun.
Bir Temel Yüzen Eylem Düğmesi oluşturun ve tıklandığında Menü Düzenlerinin görünürlüğünü değiştirin.
Referans için aşağıdaki kodu kontrol edin ve daha fazla bilgi için github'dan projeme bakın
<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>
Bunlar animasyonlar-
FAB Menüsünün açılış animasyonu:
<?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>
FAB Menüsünün kapanış animasyonu:
<?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>
Ardından, Etkinliğimde FAB menüsünü göstermek ve gizlemek için yukarıdaki animasyonları kullandım:
Fab Menüsünü Göster:
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;
}
Fab Menüsünü Kapat:
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;
}
İşte Activity sınıfı -
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();
}
}
İşte ekran görüntüleri
Materyal Tasarımı yönergelerinden Hızlı Arama'yı uygulayan bir kütüphane daha :
Gelen kutusu yüzen eylem düğmesine benzer bir şey oluşturmaya çalıştığımda kendi özel bileşen oluşturmayı düşündüm.
FAB düğmesi ve 3 tane daha FAB altına yerleştirilmiş sabit yükseklikte (genişletilmiş menü içerecek şekilde) basit çerçeve düzeni olacaktır. FAB'ı tıkladığınızda FAB'nin altından çevirmek için diğer düğmelere animasyon uygulamanız yeterlidir.
Bunu yapan bazı kütüphaneler vardır (örneğin, https://github.com/futuresimple/android-floating-action-button ), ancak kendiniz oluşturursanız her zaman daha eğlencelidir :)
layout_anchor
ve layout_anchorGravity
benim için çalışmıyor
FloatingActionMenu kütüphanesini kullanabilir veya adım adım eğitim için buraya tıklayabilirsiniz . Öğreticinin çıktısı:
Bunu yapmak için bu kütüphaneyi kullanıyorum: https://github.com/futuresimple/android-floating-action-button
Kullanımı oldukça basit;)
layout_anchor
ve layout_anchorGravity
benim için çalışmıyor
ConstraintSet animasyonu ile aynı sonuç için başka bir seçenek:
1) Tüm animasyonlu görünümleri bir ConstraintLayout'a koyun
2) Böyle bir koddan canlandırın (biraz daha fazla efekt istiyorsanız size kalmış .. bu sadece örnek)
menuItem1 ve menuItem2 , menüdeki ilk ve ikinci FAB'lardır, descriptionItem1 ve descriptionItem2 , menünün solundaki açıklamadır, parentConstraintLayout , tüm animasyonlu görünümleri içeren kök ConstraintLayout köküdür, isMenuOpened açık / kapalı bayrağı değiştirmek açık / kapalı bayrağı değiştirmek için kullanılan bir işlevdir
Animasyon kodunu uzantı dosyasına koydum ama gerekli değil.
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)
}