متحرک سازی دکمه اکشن شناور در اندروید

متحرک سازی دکمه اکشن شناور در اندروید


با معرفی متریال دیزاین دکمه اکشن شناور یا همان FAB به یکی از ساده ترین کامپوننت ها تبدیل شد که به راحتی قابل پیاده سازی است و چندی نگذشت که این عنصر در بین طراحان و توسعه دهندگان محبوبیت فراوانی یافت.

در این مطلب آموزشی نحوه تعاملی کردن FAB و ساختن انیمیشن های منحصر به فرد را فرا خواهید گرفت، کار را با افزودن یک FAB به پروژه اندروید آغاز می کنیم.

دکمه اکشن شناور در فایل لی اوت قرار می گیرد و چنانچه اقدام به ساخت یک پروژه اندروید استودیو با Blank Activity کنید به طور خودکار تولید می شود.

blog_16457_1

<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"

android:src="@android:drawable/ic_menu_help"

/>

Floating Action Button

دکمه های اکشن شناور در دو اندازه در دسترس می باشند، اندازه پیش فرض یعنی 56dp و اندازه کوچک که 40dp است. به منظور آشنایی با مقدمات طراحی جهت استفاده از FAB می توانید از این لینک استفاده کنید.

در بسیاری از اپلیکیشن های اخیر اندروید FAB به یک فهرست اسکرولینگ از عناصر واکنش نشان می دهد و باید در هنگام اسکرولینگ مخفی باشد، بدین صورت که:

blog_16457_2

برای نمایش این انیمیشن یک recyclerView ساخته شده و FAB می تواند به اسکرولینگ صورت گرفته واکنش نشان دهد.

لایبری های متعددی انجام کار را برای شما سهولت بخشیده اند و تنها با 1 یا 2 خط کد می توانید آنها را مورد استفاده قرار دهید، در زیر مثالی گویا جهت نمایش نحوه کار آورده شده است:

public class FAB_Hide_on_Scroll extends FloatingActionButton.Behavior {

public FAB_Hide_on_Scroll(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 (child.getVisibility() == View.VISIBLE && dyConsumed > 0) {

child.hide();

} else if (child.getVisibility() == View.GONE && dyConsumed < 0) {

child.show();

}

}

@Override

public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, FloatingActionButton child, View directTargetChild, View target, int nestedScrollAxes) {

return nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL;

}

}

در اینجا از کلاس ()FloatingActionButton.Behavior استفاده می کنیم که برای حرکت دادن ویوهای FloatingActionButton استفاده می شود و هیچ Snackbars قادر به پوشش دادن آنها نیست. از آنجایی که کلاس اکستند شده می توانیم عملیات مورد نظر خود را پیاده سازی کنیم.

در زمان آغاز فرآیند اسکرولینگ متد ()onStartNestedScroll این کلاس در صورتی که اسکرول عمودی باشد مقدار true را بر می گرداند و متد ()onNestedScroll به مخفی کردن و یا نمایش دکمه اکشن شناور با توجه به وضعیت کنونی آن می پردازد.

public FAB_Hide_on_Scroll(Context context, AttributeSet attrs) {

super();

}

به منظور استفاده از این عملکرد ویژگی layout_behavior را به دکمه اکشن شناور خود بیفزایید. این ویژگی دربرگیرنده نام پکیج همراه با نام کلاس در آخر آن می باشد، به بیان دیگر موقعیت دقیق این کلاس در پروژه را مشخص می سازد که در این مورد به صورت زیر است:

app:layout_behavior="com.valdio.valdioveliu.floatingactionbuttonproject.Scrolling_Floating_Action_Button.FAB_Hide_on_Scroll"

این انیمیشن جالب و هیجان انگیز به نظر می رسد اما می توان بر جذابیت آن افزود، برای نمونه می توان در زمان اسکرول در محتوای اپلیکیشن FAB را به بیرون صفحه برد، به صورت زیر:

blog_16457_3

منطق مشابه قبل می باشد با این تفاوت که نحوه مخفی سازی FAB تغییر پیدا کرده است.

این انیمیشن ساده است و این FAB به طور عمودی و با استفاده از LinearInterplolator خارج می شود. FAB به اندازه ارتفاع به علاوه حاشیه بخش زیر جابجا می شود تا به طور کامل از صفحه پاک شود در صورت اسکرول به سمت بالا به مکان اولیه خود باز می گردد.

همانطور که در کد نیز مشاهده می کنید View.VISIBLE و View.GONE در عبارت شرطی حذف شده اند، زیرا ویو در این حالت مخفی نمی شود و تنها در صفحه شناور می گردد.

public class FAB_Float_on_Scroll extends FloatingActionButton.Behavior {

public FAB_Float_on_Scroll(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;

}

}

ساخت منویی از دکمه های اکشن شناور

بسیاری از اپلیکیشن های اندروید از دکمه های اکشن شناور جهت ساخت منوهای خود استفاده می کنند و در زیر نیز یک نمونه نشان داده شده است:

blog_16457_4

حال که یک ایده کلی پیدا کردید می توانیم کار ساخت این عناصر را آغاز نماییم.

گام نخست ساخت لی اوتی دربرگیرنده 3 دکمه کوچک می باشد.

تمامی دکمه های کوچک مخفی اند و در بخش زیرین لی اوت قرار دارند، یعنی جایی در زیر FAB اولیه.

در داخل fab_layout.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:app="http://schemas.android.com/apk/res-auto"

android:layout_width="match_parent"

android:layout_height="match_parent">

<android.support.design.widget.FloatingActionButton

android:id="@+id/fab_1"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_gravity="bottom|end"

android:layout_margin="@dimen/fab_margin"

android:src="@android:drawable/ic_menu_compass"

android:visibility="invisible"

app:backgroundTint="@color/colorFAB"

app:fabSize="mini" />

<android.support.design.widget.FloatingActionButton

android:id="@+id/fab_2"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_gravity="bottom|end"

android:layout_margin="@dimen/fab_margin"

android:src="@android:drawable/ic_menu_myplaces"

android:visibility="invisible"

app:backgroundTint="@color/colorFAB"

app:fabSize="mini" />

<android.support.design.widget.FloatingActionButton

android:id="@+id/fab_3"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_gravity="bottom|end"

android:layout_margin="@dimen/fab_margin"

android:src="@android:drawable/ic_menu_share"

android:visibility="invisible"

app:backgroundTint="@color/colorFAB"

app:fabSize="mini" />

</FrameLayout>

این لی اوت را در لی اوت اکتیویتی و در زیر FAB اولیه قرار دهید.

<include layout="@layout/fab_layout" />

اکنون که لی اوت نشانده شد گام بعدی ساخت انیمیشن هایی به منظور نمایش و مخفی سازی هریک از FAB های کوچک می باشد.

هشدار

هنگام ساخت این انیمیشن ها به مشکل ایونت های تاچ و FAB های کوچک برمی خورید. با اتمام انیمیشن مکان حقیقی FAB های کوچک تغییر پیدا نمی کند، تنها ویو در مکان جدید ظاهر می شود، در نتیجه قادر به اجرای ایونت های تاچ در مکان صحیح نمی باشیم. به منظور حل این مشکل باید پارمترهای لی اوت هریک از FAB ها به موقعیت جدید ست کرده و با کشیدن ویو به موقعیت جدید انیمیشن را به اجرا در آوریم.

در ادامه این مطلب آموزشی فرآیند متحرک سازی یکی از FABهای کوچک نمایش داده می شود. فرآیند مشابه سایر حالات است اما با پارامترهای جابجایی متفاوت.

نمایش منوی دکمه های اکشن شناور

FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) fab1.getLayoutParams();

layoutParams.rightMargin += (int) (fab1.getWidth() * 1.7);

layoutParams.bottomMargin += (int) (fab1.getHeight() * 0.25);

fab1.setLayoutParams(layoutParams);

fab1.startAnimation(show_fab_1);

fab1.setClickable(true);

در اینجا fab1 با افزودن حاشیه های راست و پایین به layoutParams جابجا شده است.

مخفی کردن دکمه های اکشن شناور

FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) fab1.getLayoutParams();

layoutParams.rightMargin -= (int) (fab1.getWidth() * 1.7);

layoutParams.bottomMargin -= (int) (fab1.getHeight() * 0.25);

fab1.setLayoutParams(layoutParams);

fab1.startAnimation(hide_fab_1);

fab1.setClickable(false);

فرآیند مخفی کردن برعکس انیمیشن قبلی است.

انیمیشن های استفاده شده در این FAB به صورت زیر می باشند:

//Animations

Animation show_fab_1 = AnimationUtils.loadAnimation(getApplication(), R.anim.fab1_show);

Animation hide_fab_1 = AnimationUtils.loadAnimation(getApplication(), R.anim.fab1_hide);

در داخل فولدر /res/anim فایل هایی برای تمامی انیمیشن ها ساخته شده است. به منظور درک بهتر و بیشتر هر تگ یا ویژگی می توانید نگاهی به این لینک بیندازید.

در داخل fab1_show.xml:

<?xml version="1.0" encoding="utf-8"?>

<set xmlns:android="http://schemas.android.com/apk/res/android"

android:fillAfter="true">

<!-- Rotate -->

<rotate

android:duration="500"

android:fromDegrees="30"

android:interpolator="@android:anim/linear_interpolator"

android:pivotX="50%"

android:pivotY="50%"

android:repeatCount="4"

android:repeatMode="reverse"

android:toDegrees="0"></rotate>

<!--Move-->

<translate

android:duration="1000"

android:fromXDelta="170%"

android:fromYDelta="25%"

android:interpolator="@android:anim/linear_interpolator"

android:toXDelta="0%"

android:toYDelta="0%"></translate>

<!--Fade In-->

<alpha

android:duration="2000"

android:fromAlpha="0.0"

android:interpolator="@android:anim/decelerate_interpolator"

android:toAlpha="1.0"></alpha>

</set>

در داخل fab1_hide.xml:

<?xml version="1.0" encoding="utf-8"?>

<set xmlns:android="http://schemas.android.com/apk/res/android"

android:fillAfter="true">

<!--Move-->

<translate

android:duration="1000"

android:fromXDelta="-170%"

android:fromYDelta="-25%"

android:interpolator="@android:anim/linear_interpolator"

android:toXDelta="0%"

android:toYDelta="0%"></translate>

<!--Fade Out-->

<alpha

android:duration="2000"

android:fromAlpha="1.0"

android:interpolator="@android:anim/accelerate_interpolator"

android:toAlpha="0.0"></alpha>

</set>

اگر به تگ ترنزلیت که برای جابجایی ویو استفاده شده نگاه کنید، فاکتوری که توسط آن جابجایی (170% و 25%) FAB صورت گرفته با فاکتورهایی از حاشیه ها مطابقت دارد که در کد جاوا اضافه و حذف شده اند.

فرآیند مشابهی برای FAB نیز صدق می کند، اما با فاکتورهای جابجایی (150% و 150%) fab2 و (25% و 170%) fab3.

پروژه نهایی چیزی مشابه زیر می باشد:

blog_16457_5

به منظور ساخت انیمیشن های منحصر به فرد خود می توانید از Animation Resources اندروید استفاده کنید. کدهای پروژه نهایی در GitHub قرار داده شده و در صورت تمایل می توانید آنها را دانلود کرده و مورد استفاده قرار دهید.

 

http://www.sitepoint.com برگرفته از

اینها را هم بخوانید