در اندروید این امکان وجود دارد که یک برنامه در موقعیتهای گوناگون از layout های مختلفی استفاده کند.
- انواع مختلف device (تبلت، گوشی همراه، ساعت هوشمند و … )
- سایزهای متنوع صفحه نمایش
- جهتهای گوناگون (( landscape , portrait
- مناطق و کشورهای مختلف (تنوع زبان و … )
برنامهی شما منابع خود را از چند طریق میتواند پیدا کند:
- تراکم صفحه – screen density (hdpi ، mdpi ، xhdpi و …)
- سایز صفحه (small ، normal ، large ، xlarge )
- جهت ( landscape ، portrait )
نیازی که مطرح شد در حالتی است که layout های موقعیتی شما شبیه هم هستند و از این جهت شما نمیخواهید یک کد مشابه xml یا java را تکرار کنید.
از طرف دیگر بعضی اوقات میخواهید در یک موقعیت نسبت به دیگری رفتار غیرمشابهی داشته باشید. مثلا در حالت portrait با کلیک روی یک دکمه یک activity جدید باز شود ولی در حالت landscape با کلیک روی دکمه یک view جدید نشان داده شود.
Fragment چیست؟
Fragment را می توان به عنوان یک زیر مجموعه و یا یک بخش از اکتیویتی در نظر گرفت که در نهایت قسمتی از رابط کاربری را تشکیل داده و به واسطه آن یک رابط کاربری چند قسمتی ایجاد می شود. به کمک فرگمنت شما میتوانید device و سایزهای مختلف را مدیریت کنید.
برای درست کردن یک fragment در اندروید استودیو روی app راست کلیک کنید و مسیر زیر را طی کنید:
New -> Fragment -> Fragment (blank)
در آخر یک layout از جنس xml و یک Activity جاوایی درست کنید.
چرخه حیات فرگمنت (Fragment life cycle)
Activity ها برای خود یک چرخه حیات دارند، Fragment ها نیز چرخه حیاتی مخصوص به خود دارند که البته مستقل از چرخه حیات Activity نیست و با آن مشترکاتی دارد.
در تصویر زیر چرخه حیات Fragment را مشاهده میکنید:
چرخه حیات فرگمنت شامل وضعیت های زیر است:
onAttach(): این متد هنگامی که فرگمنت به اکتیویتی اضافه شده خوانده می شود.
onCreate(): این متد برای مقداردهی در هنگام ساخت فرگمنت فراخوانی می شود.
onCreateView(): این متد زمانی فراخوانده می شود که فرگمنت ایجاد شده و آماده ساخت واسط کاربری (UI) است. در اکتیویتی این وظیفه بر عهده onCreate() بود.
onActivityCreate(): این متد در زمانی فراخوانده می شود که اکتیویتی میزبان فرگمنت اجرا شده است.
onStart(): این متد زمانی فراخوانده می شود که رابط کاربری فرگمنت آماده نمایش است.
onResume(): در این زمان فرگمنت فعال است.
onStop(): این متد در زمان پایان فعالیت فرگمنت اجرا می شود و اگر لازم است چیزی ذخیره شود در این مرحله باید انجام داد.
onDestroyView(): این متد زمانی فراخوانده می شود که UI فرگمنت از اکتیویتی حذف می شود.
onDestroy(): در زمان انتهای حیات فرگمنت این متد اجرا می شود.
onDetach(): زمانی فراخوانده می شود که فرگمنت به طور کامل از اکتیویتی میزبان خود جدا شده است.
مقایسه چرخه عمر Activity و Fragment
تفاوت Activity و Fragment
Fragment از نظر پیاده سازی کد، شباهت زیادی به activity دارد با این تفاوت که خیلی از متدهای activity را نمیشود در fragment صدا کرد، با این حال از طریق getActivity میتوان در fragment به activity دسترسی داشت.
Button b = (Button) findViewById(R.id.but); Button b = (Button) getActivity().findViewById(R.id.but);
از getView هم میتوان برای دسترسی به layout استفاده کرد.
xml و لایهی UI نمیتوانند event ها را بگیرند و از این جهت این event ها به از طریق کد java مدیریت میشوند.
انتقال دیتا به fragment از طریق intent و bundle انجام میشود.
برای کلیک کردی روی view در Fragment مانند کد زیر عمل میکنیم:
// Activity: <Button android:id="@+id/b1" android:onClick nonClickB1" ... /> // Fragment: <Button android:id="@+id/b1" ... /> // in Fragment's Java file Button b = (Button) getActivity().findViewById(r.id.b1); b.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View view){ // whatever code would have been in onClickBl } });
گرفتن پارامتر در activity از طریق intent به صورت زیر است:
public class Name extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.name); // extract parameters passed to activity from intent Intent intent = getIntent(); int name1 = intentsgetIntExtra("id1, default); String name2 = intent.getStringExtra("id2", "default"); // use parameters to set up the initial state ... } ... }
گرفتن مقادیر intent در fragment به صورت زیر است؛ همانطور که در تصویر مشاهده میکنید از getActivity برای گرفتن intent استفاده شده است.
public class Name extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.name, container, false); } @Override public void onActivityCreated(Bundle savedState) { super.onActivityCreated(savedState); // extract parameters passed to activity from intent Intent intent = getActivity().getIntent(); int name1 = intentsgetIntExtra("id1, default); String name2 = intent.getStringExtra("id2", "default"); // use parameters to set up the initial state ... } }
ارتباط Fragment ها با یکدیگر
همانطور که قبلا گفته شد یک Activity میتواند چند Fragment داشته باشد و اصولا این Fragmentها نیاز دارند که با یکدیگر در ارتباط باشند. از این رو از متد getFragmentManager استفاده میشود. همچنین از طریق findFragmentById میتوان به هر فرگمنتی که id دارد دسترسی پیدا کرد.
Activity act = getActivity(); if (act.getResources().getConfiguration().orientation == Configuration.ORIENTATION LANDSCAPE) { // update other fragment within this same activity FragmentCLass fragment = (FragmentCLass) act.getFragmentManager().findFragmentById(R.id.id); fragment.methodName(parameters); }
زیرکلاس های Fragment
- DialogFragment: یک فرگمنت میتواند به صورت دیالوگ روی Activity باز شود.
- ListFragment: یک فرگمنت میتواند لیستی از آیتمها را به عنوان محتوای اصلی نشان دهد.
- PereferenceFragment: به کاربر این اختیار را میدهد که تنظیمات برنامه را تغییر دهد.