جعل الخاص بك تقريبا الموسعة زر العمل العائم

مرحبا بالجميع.

بعد أقل من نصف عام ، يعمل طلبي ، حيث تم تنفيذ قائمة Floating Action Button بواسطة مكتبة تابعة لجهة خارجية.

في مرحلة ما ، كنت أرغب في جعلها أكثر متعة وملاءمة.

كان


أصبح


كانت الهدية أنني صادفت رمزًا غير فعال في مكان آخر قمت بتحسينه بنجاح.

تاريخ إنشاء التطبيق
سلة التسوق التاريخ القطعة

تطبيق

1. تصميم زر
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.animatsiya

2.1 المظهر
   <?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 الاختفاء
القائمة الفرعية السفلية

 <?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. تخطيط الشاشة
 <?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 سلوك التمرير
 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. سوف نرث من RelativeLayout لمعالجة النقرات على مقعد فارغ لإغلاق القائمة
 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. ربط كل شيء في الجزء
 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/ar455728/


All Articles