Membuat Tombol Aksi Mengambang Anda Hampir Diperpanjang

Halo semuanya.

Kurang dari setengah tahun kemudian aplikasi saya berfungsi, di mana menu Floating Action Button diimplementasikan oleh perpustakaan pihak ketiga.

Pada titik tertentu, saya ingin membuatnya lebih menyenangkan dan nyaman.

Apakah


Telah menjadi


Hadiahnya adalah saya menemukan kode yang tidak efisien di tempat lain yang berhasil saya optimalkan.

Riwayat Pembuatan Aplikasi
Sejarah Widget Keranjang Belanja

Implementasi

1. Tata letak tombol
fab_layout.xml <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:cardView="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.v7.widget.CardView android:id="@+id/fab_spending" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom|end" android:visibility="invisible" cardView:cardBackgroundColor="@color/red" cardView:cardCornerRadius="12dp" cardView:cardElevation="8dp"> <TextView style="@style/White16" android:layout_width="120dp" android:layout_height="36dp" android:drawableRight="@drawable/remove" android:drawablePadding="6dp" android:gravity="center" android:padding="4dp" android:text="@string/spending"/> </android.support.v7.widget.CardView> <android.support.v7.widget.CardView android:id="@+id/fab_income" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom|end" android:visibility="invisible" cardView:cardBackgroundColor="@color/green" cardView:cardCornerRadius="12dp" cardView:cardElevation="8dp"> <TextView style="@style/White16" android:layout_width="120dp" android:layout_height="36dp" android:drawableRight="@drawable/add" android:drawablePadding="6dp" android:gravity="center" android:text="@string/income"/> </android.support.v7.widget.CardView> <android.support.v7.widget.CardView android:id="@+id/fab_transfer" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom|end" android:visibility="invisible" cardView:cardBackgroundColor="@color/gunmetal" cardView:cardCornerRadius="12dp" cardView:cardElevation="8dp"> <TextView style="@style/White16" android:layout_width="120dp" android:layout_height="36dp" android:drawableRight="@drawable/autorenew" android:drawablePadding="6dp" android:gravity="center" android:text="@string/transfer"/> </android.support.v7.widget.CardView> </FrameLayout> 


2.animation

2.1 penampilan
   <?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:fillAfter="true"> <!--Move--> <translate android:duration="300" android:fromXDelta="125%" android:fromYDelta="25%" android:interpolator="@android:anim/linear_interpolator" android:toXDelta="0%" android:toYDelta="0%"></translate> <!--Fade In--> <alpha android:duration="300" android:fromAlpha="0.0" android:interpolator="@android:anim/decelerate_interpolator" android:toAlpha="1.0"></alpha> </set>  <?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:fillAfter="true"> <!--Move--> <translate android:duration="300" android:fromXDelta="75%" android:fromYDelta="210%" android:interpolator="@android:anim/linear_interpolator" android:toXDelta="0%" android:toYDelta="0%"></translate> <!--Fade In--> <alpha android:duration="300" android:fromAlpha="0.0" android:interpolator="@android:anim/decelerate_interpolator" android:toAlpha="1.0"></alpha> </set>  <?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:fillAfter="true"> <!--Move--> <translate android:duration="300" android:fromXDelta="25%" android:fromYDelta="400%" android:interpolator="@android:anim/linear_interpolator" android:toXDelta="0%" android:toYDelta="0%"></translate> <!--Fade In--> <alpha android:duration="300" android:fromAlpha="0.0" android:interpolator="@android:anim/decelerate_interpolator" android:toAlpha="1.0"></alpha> </set> 


2.1 menghilang
submenu bawah

 <?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:fillAfter="true"> <!--Move--> <translate android:duration="300" android:fromXDelta="-125%" android:fromYDelta="-25%" android:interpolator="@android:anim/linear_interpolator" android:toXDelta="0%" android:toYDelta="0%"></translate> <!--Fade Out--> <alpha android:duration="300" android:fromAlpha="1.0" android:interpolator="@android:anim/accelerate_interpolator" android:toAlpha="0.0"></alpha> </set>  <?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:fillAfter="true"> <!--Move--> <translate android:duration="300" android:fromXDelta="-75%" android:fromYDelta="-210%" android:interpolator="@android:anim/linear_interpolator" android:toXDelta="0%" android:toYDelta="0%"></translate> <!--Fade Out--> <alpha android:duration="300" android:fromAlpha="1.0" android:interpolator="@android:anim/accelerate_interpolator" android:toAlpha="0.0"></alpha> </set>  <?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:fillAfter="true"> <!--Move--> <translate android:duration="300" android:fromXDelta="-25%" android:fromYDelta="-400%" android:interpolator="@android:anim/linear_interpolator" android:toXDelta="0%" android:toYDelta="0%"></translate> <!--Fade Out--> <alpha android:duration="300" android:fromAlpha="1.0" android:interpolator="@android:anim/accelerate_interpolator" android:toAlpha="0.0"></alpha> </set> 


3. Tata letak layar
 <?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" xmlns:card_view="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content"> <ua.karelov.beans.ui.custom.MyRelativeLayout android:id="@+id/l_root" android:layout_width="match_parent" android:layout_height="wrap_content"> <android.support.v7.widget.RecyclerView android:id="@+id/rv_transactions" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="4dp" android:clickable="true" android:fadingEdgeLength="20dp" android:focusable="true" android:requiresFadingEdge="vertical"/> </ua.karelov.beans.ui.custom.MyRelativeLayout> <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_marginRight="16dp" android:layout_marginBottom="46dp" android:rotation="45" android:src="@drawable/close" app:layout_behavior=".ui.custom.FABScroll" /> <include layout="@layout/fab_layout" android:layout_width="match_parent" android:layout_height="500dp" android:layout_gravity="bottom|end" android:layout_marginBottom="46dp"/> </android.support.design.widget.CoordinatorLayout> 


4. Perilaku gulir FAB
 import android.content.Context; import android.support.annotation.NonNull; import android.support.design.widget.CoordinatorLayout; import android.support.design.widget.FloatingActionButton; import android.support.v4.view.ViewCompat; import android.util.AttributeSet; import android.view.View; import android.view.animation.LinearInterpolator; public class FABScroll extends FloatingActionButton.Behavior { public FABScroll(Context context, AttributeSet attrs) { super(); } @Override public void onNestedScroll(CoordinatorLayout coordinatorLayout, FloatingActionButton child, View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) { super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed); //child -> Floating Action Button if (dyConsumed > 0) { CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) child.getLayoutParams(); int fab_bottomMargin = layoutParams.bottomMargin; child.animate().translationY(child.getHeight() + fab_bottomMargin).setInterpolator(new LinearInterpolator()).start(); } else if (dyConsumed < 0) { child.animate().translationY(0).setInterpolator(new LinearInterpolator()).start(); } } @Override public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, FloatingActionButton child, View directTargetChild, View target, int nestedScrollAxes) { return nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL; } } 


5. Kami akan mewarisi dari RelativeLayout untuk menangani klik pada kursi kosong untuk menutup menu
 import android.content.Context; import android.util.AttributeSet; import android.view.MotionEvent; import android.widget.RelativeLayout; public class MyRelativeLayout extends RelativeLayout { private boolean layoutClickable = true; public void setLayoutClickable(boolean layoutClickable) { this.layoutClickable = layoutClickable; } public boolean isLayoutClickable() { return layoutClickable; } public MyRelativeLayout(Context context) { super(context); } public MyRelativeLayout(Context context, AttributeSet attrs) { super(context, attrs); } public MyRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { // true if you do not want the children to be clickable. return !layoutClickable; } } 


6. Hubungkan semua yang ada di fragmen
 private static final double transitionSmall = 0.25; private static final double transitionMediumX = 0.75; private static final double transitionMediumY = 2.1; private static final double transitionBigY = 4; @BindView(R.id.fab) FloatingActionButton fab; @BindView(R.id.fab_spending) CardView fabSpending; @BindView(R.id.fab_income) CardView fabIncome; @BindView(R.id.fab_transfer) CardView fabTransfer; //Animations Animation fadeIn; Animation fadeOut; Animation showFabSpending; Animation hideFabSpending; Animation showFabIncome; Animation hideFabIncome; Animation showFabTransfer; Animation hideFabTransfer; @Override protected void initView() { super.initView(); //Animations fadeIn = AnimationUtils.loadAnimation(getActivity(), R.anim.fade_in); fadeOut = AnimationUtils.loadAnimation(getActivity(), R.anim.fade_out); showFabSpending = AnimationUtils.loadAnimation(getActivity(), R.anim.fab1_show); hideFabSpending = AnimationUtils.loadAnimation(getActivity(), R.anim.fab1_hide); showFabIncome = AnimationUtils.loadAnimation(getActivity(), R.anim.fab2_show); hideFabIncome = AnimationUtils.loadAnimation(getActivity(), R.anim.fab2_hide); showFabTransfer = AnimationUtils.loadAnimation(getActivity(), R.anim.fab3_show); hideFabTransfer = AnimationUtils.loadAnimation(getActivity(), R.anim.fab3_hide); } @OnTouch(R.id.l_root) public boolean clickRoot() { if(!lRoot.isLayoutClickable()) { //Close FAB menu hideFAB(); } return true; } private void expandFAB() { ViewCompat.animate(fab). rotation(-90). withLayer(). setDuration(300). start(); lRoot.setLayoutClickable(false); lRoot.startAnimation(fadeOut); //Floating Action Button 1 FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) fabSpending.getLayoutParams(); layoutParams.rightMargin += (int) (fabSpending.getWidth() * (1 + transitionSmall)); layoutParams.bottomMargin += (int) (fabSpending.getHeight() * transitionSmall); fabSpending.setLayoutParams(layoutParams); fabSpending.startAnimation(showFabSpending); fabSpending.setClickable(true); //Floating Action Button 2 FrameLayout.LayoutParams layoutParams2 = (FrameLayout.LayoutParams) fabIncome.getLayoutParams(); layoutParams2.rightMargin += (int) (fabIncome.getWidth() * transitionMediumX); layoutParams2.bottomMargin += (int) (fabIncome.getHeight() * transitionMediumY); fabIncome.setLayoutParams(layoutParams2); fabIncome.startAnimation(showFabIncome); fabIncome.setClickable(true); //Floating Action Button 3 FrameLayout.LayoutParams layoutParams3 = (FrameLayout.LayoutParams) fabTransfer.getLayoutParams(); layoutParams3.rightMargin += (int) (fabTransfer.getWidth() * transitionSmall); layoutParams3.bottomMargin += (int) (fabTransfer.getHeight() * transitionBigY); fabTransfer.setLayoutParams(layoutParams3); fabTransfer.startAnimation(showFabTransfer); fabTransfer.setClickable(true); } private void hideFAB() { ViewCompat.animate(fab). rotation(45f). withLayer(). setDuration(300). start(); lRoot.setLayoutClickable(true); lRoot.startAnimation(fadeIn); //Floating Action Button 1 FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) fabSpending.getLayoutParams(); layoutParams.rightMargin -= (int) (fabSpending.getWidth() * (1 + transitionSmall)); layoutParams.bottomMargin -= (int) (fabSpending.getHeight() * transitionSmall); fabSpending.setLayoutParams(layoutParams); fabSpending.startAnimation(hideFabSpending); fabSpending.setClickable(false); //Floating Action Button 2 FrameLayout.LayoutParams layoutParams2 = (FrameLayout.LayoutParams) fabIncome.getLayoutParams(); layoutParams2.rightMargin -= (int) (fabIncome.getWidth() * transitionMediumX); layoutParams2.bottomMargin -= (int) (fabIncome.getHeight() * transitionMediumY); fabIncome.setLayoutParams(layoutParams2); fabIncome.startAnimation(hideFabIncome); fabIncome.setClickable(false); //Floating Action Button 3 FrameLayout.LayoutParams layoutParams3 = (FrameLayout.LayoutParams) fabTransfer.getLayoutParams(); layoutParams3.rightMargin -= (int) (fabTransfer.getWidth() * transitionSmall); layoutParams3.bottomMargin -= (int) (fabTransfer.getHeight() * transitionBigY); fabTransfer.setLayoutParams(layoutParams3); fabTransfer.startAnimation(hideFabTransfer); fabTransfer.setClickable(false); } private void initMenu() { fab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if(lRoot.isLayoutClickable()) { //Display FAB menu expandFAB(); } else { //Close FAB menu hideFAB(); } } }); } //     (          ) fab.animate().translationY(0).setInterpolator(new LinearInterpolator()).start(); 

Source: https://habr.com/ru/post/id455728/


All Articles