Erstellen Sie Ihre fast erweiterte schwebende Aktionstaste

Hallo an alle.

Weniger als ein halbes Jahr später funktioniert meine Anwendung , in der das Floating Action Button-Menü von einer Drittanbieter-Bibliothek implementiert wurde.

Irgendwann wollte ich es angenehmer und bequemer machen.

War


Ist geworden


Das Geschenk war, dass ich an einer anderen Stelle auf einen ineffizienten Code gestoßen bin, den ich erfolgreich optimiert habe.

Anwendungserstellungsverlauf
Warenkorb-Widget-Verlauf

Implementierung

1. Tastenlayout
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 Aussehen
   <?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 Verschwinden
unteres Untermenü

 <?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. Bildschirmlayout
 <?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. FAB-Bildlaufverhalten
 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. Wir erben von RelativeLayout, um Klicks auf einen leeren Platz zu verarbeiten und das Menü zu schließen
 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. Verbinden Sie alles im Fragment
 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/de455728/


All Articles