کار با Snackbar متریال دیزاین
معرفی Snackbar یا اسنک بار در اندروید:
به نام خدا. Snackbar را می توان نسخه جدیدی از Toast دانست. شاید واژه “جایگزین” مناسب نباشد اما در موارد زیادی استفاده از اسنک بار به جای Toast می تواند رضایت بخش بوده و زیبایی بیشتری به اپ ما بدهد. ضمن اینکه در اسنک بار، شخصی سازی بیشتری در اختیار داریم.
به تصویر زیر دقت کنید:
بعد از اینکه کاربر در اپلیکیشنی مانند Gmail، ایمیلی را حذف می کند، پیغام Message is deleted بجای نمایش در قالب Toast، به صورت نواری با پس زمینه تیره رنگ و به حالت انیمیشن از پایین صفحه ظاهر شده و پس از پایان زمان تعیین شده به همانصورت به طرف پایین برگشته و محو می شود.
یا یک مثال دیگر از اسنک بار:
در اینجا پیغامی مبنی بر عدم دسترسی به شبکه به کاربر اعلام شده است.
در هر دو مثال بالا، علاوه بر نمایش پیغام، یک Action نیز در سمت راست اضافه شده که کاربر می تواند عملی را انجام دهد. مانند لغو حذف ایمیل در مثال اول و تلاش مجدد برای اتصال به شبکه در مثال دوم. پس یکی از مزیت های اسنک بار نسب به Toast همین قابلیت اضافه کردن دکمه و اکشن است.
دموی یک اسنک بار:
در ادامه به بررسی Snackbar در قالب یک پروژه می پردازم.
ساخت و بررسی Snackbar:
یک پروژه با نام Snackbar و MinSDK 17 در اندروید استودیو ایجاد کردم. مانند مباحث گذشته، اسنک بار نیز علاوه بر کتابخانه اصلی متریال دیزاین یعنی appcompat-v7 به کتابخانه design هم نیاز دارد:
dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'com.android.support:appcompat-v7:27.0.2' implementation 'com.android.support:design:27.0.2' }
برای اینکه قابلیت های اسنک بار به درستی اجرا شود (مانند قابلیت کشیدن به سمت راست برای از بین بردن یا swipe-to-dismiss) لازم است view ای که Snackbar در آن قرار گرفته از جنس CoordinatorLayout باشد. پس لایه اکتیویتی را به CoordinatorLayout تبدیل کرده و یک id نیز به آن اختصاص می دهم:
<?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:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/crd_layout" tools:context="ir.android_studio.snackbar.MainActivity"> </android.support.design.widget.CoordinatorLayout>
فعلا با layout کاری ندارم و به تکمیل کدهای جاوای اکتیویتی می پردازم:
package ir.android_studio.snackbar; import android.support.design.widget.CoordinatorLayout; import android.support.design.widget.Snackbar; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; public class MainActivity extends AppCompatActivity { CoordinatorLayout crdLayout; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); crdLayout = findViewById(R.id.crd_layout); Snackbar snkbr = Snackbar.make(crdLayout, "Sample Snackbar Message", Snackbar.LENGTH_LONG); snkbr.show(); } }
ابتدا CoordinatorLayout را با نام دلخواه crdLayout تعریف کردم. سپس یک نمونه از Snackbar با نام snkbr ساختم. همانطور که مشاهده می کنید با استفاده از تابع make که ۳ پارامتر ورودی می گیرد، اسنک بار را تکمیل می کنیم. ورودی اول همان view پدر یعنی CoordinatorLayout است. ورودی بعد، متن پیغام و سومی مدت زمان نمایش پیغام است که سه مقدار LENGTH_LONG (نمایش طولانی مدت)، LENGTH_SHORT (نمایش کوتاه مدت) و LENGTH_INDEFINITE را می پذیرد. استفاده از مقدار LENGTH_INDEFINITE باعث می شود تا زمانی که کاربر اقدام به بستن Snackbar نکند (مانند کشیدن به سمت راست یا تایید اکشن موجود در اسنک بار) پیغام روی صفحه باقی بماند. در نهایت توسط متد show() اسنک بار نمایش داده می شود.
پروژه را اجرا می کنم:
به محض اجرای پروژه، اسنک بار نیز ظاهر شده و پس از چند ثانیه از صفحه حذف می شود. برای راحتتر شدن کار، اسنک بار را درون یک دکمه قرار می دهم تا با هر بار لمس دکمه، اجرا شود. به جای Button عادی از یک Floating Action Button استفاده می کنم تا یکی از اهمیت های استفاده از CoordinatorLayout را نیز در این مبحث درک کنید. FAB مبحث گذشته را به پروژه اضافه می کنم:
<?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:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/crd_layout" tools:context="ir.android_studio.snackbar.MainActivity"> <android.support.design.widget.FloatingActionButton android:id="@+id/fab" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom|start" android:layout_margin="16dp" android:src="@android:drawable/ic_dialog_email" app:backgroundTint="#2c489c" android:clickable="true" android:focusable="true" app:fabSize="normal" app:rippleColor="#b12f2f"/> </android.support.design.widget.CoordinatorLayout>
package ir.android_studio.snackbar; import android.support.design.widget.CoordinatorLayout; import android.support.design.widget.FloatingActionButton; import android.support.design.widget.Snackbar; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; public class MainActivity extends AppCompatActivity { CoordinatorLayout crdLayout; FloatingActionButton mFab; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); crdLayout = findViewById(R.id.crd_layout); mFab = findViewById(R.id.fab); mFab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Snackbar snkbr = Snackbar.make(crdLayout, "Sample Snackbar Message", Snackbar.LENGTH_LONG); snkbr.show(); } }); } }
در واقع همان پروژه FAB است با این تفاوت که بجای Toast از Snackbar استفاده شده. پروژه را اجرا می کنم:
با لمس دکمه FAB، اسنک بار نمایش داده می شود. به تصویر دوم دقت کنید. با ظاهر شدن اسنک بار، FAB نیز به همان اندازه به بالا رفته و تداخل ایجاد نشده است در صورتی که اگر بجای CoordinatorLayout از سایر layout ها مانند RelativeLayout استفاده می کردیم، FAB در جای خود باقی می ماند و اسنک بار قسمتی از FAB را می پوشاند.
با استفاده از متد setDuration می توان مدت زمان نمایش اسنک بار را سفارشی کرد:
mFab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Snackbar snkbr = Snackbar.make(crdLayout, "Sample Snackbar Message", Snackbar.LENGTH_LONG); snkbr.setDuration(9000); snkbr.show(); } });
در کد بالا، اسنک بار به مدت ۹ ثانیه اجرا می شود.
اما در ابتدای مبحث به یکی از مهمترین برتری های Snackbar نسبت به Toast اشاره شد که تعریف اکشن است:
متد setAction دو ورودی نیاز دارد. ورودی اول عنوان اکشن و دومی یک OnClickListener که اکشن مدنظر درون آن تعریف می گردد. به اینصورت:
mFab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Snackbar snkbr = Snackbar.make(crdLayout, "Sample Snackbar Message", Snackbar.LENGTH_LONG); snkbr.setDuration(3000); snkbr.setAction("OK", new View.OnClickListener() { @Override public void onClick(View view) { } }); snkbr.show(); } });
ساده ترین اکشن، استفاده از dismiss() است. این متد قبل از به پایان رسیدن زمان نمایش اسنک بار و هنگام لمس “OK” توسط کاربر، اسنک بار را می بندد. پس snkbr.dismiss() را به setAction اضافه کرده و پروژه را اجرا می کنم:
snkbr.setAction("OK", new View.OnClickListener() { @Override public void onClick(View view) { snkbr.dismiss(); } });
گزینه ای با نام OK به سمت راست اضافه شده که با لمس آن، اسنک بار بسته می شود.
هر اکشن دیگری نیز می توان درنظر گرفتن. مثلا این اکشن نقش Undo را داشته باشد. یعنی در اپلیکیشن مدیریت ایمیل، بعد از نمایش پیغام “ایمیل ها حذف شد”، امکان لغو حذف وجود داشته باشد که با لمس گزینه Undo، ایمیل های حذف شده مجدد به اینباکس برگشته و پیغام جدیدی مبنی بر بازیابی ایمیل ها نمایش داده شود.
از setActionTextColor هم برای تغییر رنگ گزینه اکشن استفاده می شود:
mFab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { final Snackbar snkbr = Snackbar.make(crdLayout, "Sample Snackbar Message", Snackbar.LENGTH_LONG); snkbr.setDuration(5000); snkbr.setAction("OK", new View.OnClickListener() { @Override public void onClick(View view) { snkbr.dismiss(); } }); snkbr.setActionTextColor(Color.RED); snkbr.show(); } });
اگر بخواهیم به جای استفاده از رنگهای پیش فرض اندروید، از رنگهای تعریف شده در colors.xml استفاده کنیم به اینصورت قابل انجام است:
snkbr.setActionTextColor(getResources().getColor(R.color.colorAccent));
در اینجا رنگ با نام colorAccent به setActionTextColor پاس داده می شود.
در نهایت رنگ متن پیغام و پس زمینه Snackbar را نیز به اینصورت تغییر می دهم:
View snkView = snkbr.getView(); snkView.setBackgroundColor(Color.GRAY); TextView txtView = snkView.findViewById(android.support.design.R.id.snackbar_text); txtView.setTextColor(Color.GREEN);
در ابتدا یک نمونه از View با نام دلخواه snkView ساخته و snkbr.getView را درون آن قرار می دهم. به اینصورت view مربوط به snkbr به snkView متصل می شود. حالا برای تعریف رنگ پس زمینه از setBackgroundColor و رنگ متن از setTextColor استفاده شده که لازم است از TextView یک نمونه ساخته و به آی دی snackbar_text پیوند دهیم. snackbar_text در خود اندروید تعریف شده و چون مربوط به کتابخانه design است به صورت android.support.design.R.id.snackbar_text قابل دسترسی است.
MainActivity.java:
package ir.android_studio.snackbar; import android.graphics.Color; import android.support.design.widget.CoordinatorLayout; import android.support.design.widget.FloatingActionButton; import android.support.design.widget.Snackbar; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.TextView; public class MainActivity extends AppCompatActivity { CoordinatorLayout crdLayout; FloatingActionButton mFab; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); crdLayout = findViewById(R.id.crd_layout); mFab = findViewById(R.id.fab); mFab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { final Snackbar snkbr = Snackbar.make(crdLayout, "Sample Snackbar Message", Snackbar.LENGTH_LONG); snkbr.setDuration(5000); snkbr.setAction("OK", new View.OnClickListener() { @Override public void onClick(View view) { snkbr.dismiss(); } }); // snkbr.setActionTextColor(Color.RED); snkbr.setActionTextColor(getResources().getColor(R.color.colorPrimaryDark)); View snkView = snkbr.getView(); snkView.setBackgroundColor(Color.GRAY); TextView txtView = snkView.findViewById(android.support.design.R.id.snackbar_text); txtView.setTextColor(Color.GREEN); snkbr.show(); } }); } }
https://developer.android.com/reference/android/support/design/widget/Snackbar.html
https://material.io/guidelines/components/snackbars-toasts.html
توجه : سورس پروژه درون پوشه Exercises قرار داده شده است
تعداد صفحات : ۱۷
حجم : ۱٫۲ مگابایت
قیمت : رایگان
دانلود رایگان با حجم ۱٫۲ مگابایت لینک کمکی
عالی بود
دمتون گرم باشه
لطفا سمت سرورهم اموزش بدید
سلام عالی بود
ولی یه سوال من میخوام به جای استفاده از Toast از اسنک بار استفاده کنم کی قشنگ تره ولی به مشکل خوردم زمانی که کیبرد باز هست اسنک زیر کیبرد مخفی میشه چطور میتونم این مشکل رو درست کنم مثلا زمانی که کیبرد بازه اسنک بار بیاد بالی کیبرد قرار بگیره
سلام. گوگل کنید
How to show Android SnackBar above keyboard
ببینید چه راه حل هایی وجود داره
عالی. تشکر بابت این محتوا مختصر و مفید.
مثل همیشه عالی
بی نهایت ممنون