استارت‌آپ و کارآفرینی

استفاده از Fragment ها در Android ( مقدمه )

اگرچه که fragment ها حدود سه سال هستند که جزئی از Android API هستند ولی من هنوز توسعه دهندگانی را می‌بینم که در تلاش برای درک ارزش و هدف استفاده از fragmentها هستند.

یک توضیح رایج درمورد استفاده از fragmentها که خودم هم معمولا از ان استفاده میکنم:

Fragmentها رابط کاربری و منطق پشت آن را دسته بندی یا گروه بندی می‌کند ( منظور منظم کردن هر بخش به صورت جداست).

با اینکه این توضیح دقیقی است ولی در جواب کسی که می‌گوید بدون استفاده از آنها نیز اپلیکیشن من کار می‌کند، می‌گویم استفاده از آنها مانند ساختن یک ساعت دقیق سویسی است درحالی که شما فقط می‌خواهید بدانید ساعت چند است!

دراینجا دلایلی برای مفید بودن استفاده از fragmentها رو برایتان می گویم:

سر و کار داشتن با دستگاه‌هایی با ابعاد ظاهری متفاوت

کلاس Activity اغلب به عنون کلاس اصلی رابط کاربری در اندروید شناخته می‌شود. درست است که انجام رندر UI برنامه بر عهده این کلاس است اما بسیاری از مسئولیت های دیگر را مانند lifecycle management و platform interaction و … را برعهده دارد.

قرار دادن تمام این بارها بر دوش کلاس Activity باعث بوجود آمدن مشکلاتی در برخورد با دستگاه‌های مختلف ( از نظر ابعاد ) می‌شود. درنهایت یکی از دو مورد زیر رخ خواهد داد :

  • یک Activity که شامل کدهای زیاد برای هندل کردن موارد خاص برای دستگاه‌هایی با ابعاد متفاوت است.
  • چندین Activity که هر کدام برای یک سایز خاص بوجود آمده با UI های تکراری یا مشترک برای تمام Activity‌ها.

Fragmentها با در نظر گرفتن جرئیات رابط کاربری این مشکل را حل می‌کنند و این بار را از روی دوش Activity برمی‌دارند. به این ترتیب که fragmentهای جداگانه‌ای برای هر ابعاد مختلف ساخته میشود که جزئیات مربوطه در رابط کاربری در هر سایز رو مشخص میکنند و Activity از زیر بار این مسئولیت آزاد شده و رابط کاربری برای سایز فعلی دستگاه رو به fragment واگذار می‌کند.

پاس دادن داده بین فرم‌های اپلیکیشن

همان طور که می‌دونید هر فرم از اپلیکیشن متعلق به یک Activity است. این باعث بوجود آمدن چالش‌هایی در انتقال و پاس دادن داده‌ها بین فرم‌ها می‌شود، زیرا Android Intent mechanism اجازه پاس دادن نوع داده‌ای مرجع ( object ) را بطور مستقیم بین Activityها نمی‌دهد. در عوض شی باید سریالایز (serialize) شده باشد یا بهش دسترسی عمومی داشته باشیم.

با ایجاد هر فرم به صورت یک fragment جداگانه از این سردرد پاس دادن داده‌ها و شی‌ها بطور کلی خلاص می‌یابیم. fragment ها همیشه در داخل یه Activity مشخص وجو دارند و Activity به آنها و محتوایات آنها دسترسی دارد. با ذخیره اطلاعات مورد نظر در هر Activity هر fragment که برای هر فرم ایجاد شده به تمام داده‌های آن Activity به راحتی دسترسی دارد یعنی دیگر نیاز به پاس دادن داده‌ها و شی‌ها به یک Activity دیگر ندارید.

ساختار بخشیدن به رابط کاربری

دو تا از رایج ترین ابزار برای ساختار بخشیدن به فرم‌ها استفاده از تب و لیست کشویی می باشد. تب‌های هنگامی که تعداد کمی فرم داشته باشیم و لیست‌های کشویی که فرم‌ها زیاد و مختلف هستند پر کاربرد و عالی هستند، که بعنوان مثال در شکل زیر استفاده از لیست کشویی در برنامه ایمیل نشاد داده شده است.

EmailInboxWithMenu

fragmentها استفاده از این ابزار را بسیار آسان کرده است. در هر دو شما به راحتی با قرار دادن یک ActionBar به حالت ناوبری (navigation) مناسب ، رابط کاربری مناسب و سپس استفاده از FragmentTransaction برای سوئیچ کردن بین fragmentهایی که در حال حاضر نمایش داده می‌شود ، استفاده کنید.

  • برای تب‌ها از NAVIGATION_MODE_TABS و ActionBar.TabListener استفاده کنید
  • و برای لیست‌ها کشویی از NAVIGATION_MODE_LIST و ActionBar.OnNavigationListener استفاده کنید.

برخی ویژگی‌های fragment ها بطور خلاصه

  • هر fragment دارای لایوت ، رفتار ( behavior code ) و چرخه عمر (lifecycle callbacks ) خودش است.
  • شما می‌توانید یک fragment را در یک Activity حذف یا اضافه کنید در حالی که Activity در حال اجرا است.
  • شما می‌توانید از چند fragment برای ساختن یک Activity استفاده کنید تا یک رابط کاربری چند تکه با functionality بالا داشته باشید.
  • یک fragment می‌تواند در چند Activity استفاده شود.
  • چرخه عمر هر fragment وابسه به Activity میزبان است.
  • هنگامی که یک Activity متوقف می‌شود تمام fragment های قابل دسترس در آن Activity نیز متوقف می‌شوند.
  • رفتار fragment می‌تواند به هیچ یک از اجزا رابط کاربری وابسته نباشد.
  • fragment ها از API 11 به بعد قابل دسترس هستند.

برای جزئیات بیشتر میتوانید به سایت رسمی مراجعه کنید.

13 نظرات
  1. mobina می گوید

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

    1. صمصام بابادی می گوید

      خواهش
      خوشحالم که با این مقاله تونستم بهتون کمک کنم

  2. مهدی تقی زاده می گوید

    به نام خدا

    بابا خدا پدرت رو بیامرزه . شونصدتا سایت دیدم نفهمیدم این fragment به چه دردی می خوره . همشون هم از رو هم کپی کردن . به هرحال دستت درد نکنه . البته ما تو اندروید فنچیم هنوز . مونده تا قدر کارهای شما رو بدونیم .

    1. صمصام بابادی می گوید

      درود بر شما
      شما لطف دارید

  3. پویا می گوید

    سلام و خسته نباشید و تشکر از مطلب مفید و البته تخصصی تون!
    سوالی داشتم؛ تو یه اکتیویتی از سه فرگمنت استفاده می کنم و بینشون در حرکتم. موقع Transaction از انیمیشن استفاده میکنم، ولی فرگمنت ها حین جابجایی مقداری لک دارن! روش ست کردن انیمیشنمم استاندارده، یعنی چیزی که همه جا درج شده؛ fragmentTransaction.setCustomAnimations
    به نظرتون آیا ممکنه انیمیشن ها کلا برای جابجایی بین فرگمنت ها معقول نباشن، یا نه، ایراد کار رو تو درز حافظه، کد سنگین و این چیزا بگردم؟! یعنی گشتما، انگار همه چی منطقیه! و البته رمق نکردم منتقلشون کنم به اکتیویتی های جدا و تست کنم!! خیلی طولانی شد، شرمنده، و ممنون میشم راهنمایی کنید.

  4. صمصام بابادی می گوید

    سلام دوست عزیز
    ممنون از لطفتون
    من زیاد از انیمیشن ها برای جابجایی استفاده نکردم ، حقیقتا یکبار استفاده کردم و با لک مواجه شدم و تا اونجایی که فهمیدم لک دار بودن ارتباط مستقیمی با مدل و قدرت دستگاه داره!
    تا اونجایی هم که من میدونم fragmentTransaction.setCustomAnimations معقول ترین راه ست کردن انیمیشن ، البته یک تستی انجام دادم که یک اکتیویتی خالی و دو فرگمنت داشتم ، انیمشین بدون لک انجام میشد.

    1. پویا می گوید

      اوکی! به هر حال ممنون از وقتی که برای جواب دادن گذاشتید! موفق باشید.

  5. مرتضی می گوید

    سلام مهندس
    مدیون میشدم اگر نظر نمیذاشتم
    مفهوم رو به خوبی رسوندید

    خیلی ممنون

  6. سعید می گوید

    سلام،

    متاسفانه فرصت ندارم مقاله تون رو کامل بخونم، اما میخواستم یه نکته ای رو عرض کنم که اگر ننوشتید و صلاح دونستید به مقاله تون اضافه کنید.

    اینکه کل صفحات برنامه رو فرگمنت در نظر بگیریم و همه ی اینها رو وابسته به یک اکتیویتی کنیم کاری بس ناپسند است.

    اصولاً علت بوجود آمدن مفهوم فرگمنت، ارتباط عناصر و اطلاعات مشترکی بود که بین چند صفحه از برنامه جریان داشت.
    در نتیجه استفاده از فرگمنت وابسته به این هست که طراح برنامه در وهله اول به ساختار صفحات مسلط باشد، سپس بتواند تشخیص دهد که چگونه برای هر بخش(صفحات مرتبط با هم) یک اکتیویتی و برای هر صفحه یک فرگمنت در نظر بگیرد.

    همچنین بخاطر سایت و مقالات شما بزرگواران بسیار تشکر مینمایم.

  7. کویر سبز می گوید

    سلام ممنون از بابت مقاله که گذاشتید ولی ای کاش ی مثال عملی می زدید من همچنان با این بحث فرگمنت مشکل دارم

  8. مهدي می گوید

    با سلام و سپاس از مطلب قابل فهمی که قرار دادید

  9. علیرضا می گوید

    سلام
    خیلی ممنون داداش برا توضیحات…
    من میخواستم بد.نم چجوری تو یک فرگمنت ، تب بسازم؟؟؟
    یعنی تو یه فرگمت که خودش تو یه اکتیویتیه من میخوام تب بار بسازم؟؟؟

  10. احمدرضا مودی می گوید

    کاشکی همه بتونن مث شما برایه یک موضوع منطق درست بیارن.واقعا عالی بود.راستشو بگم ذهنم نسبت به فرگمنت ها باز شد.ممنون

ارسال یک پاسخ

آدرس ایمیل شما منتشر نخواهد شد.