فرگمنت ها (Fragment) در اندروید
در این مبحث ابتدا به معرفی Fragment در اندروید پرداخته، سپس فرگمنتهای استاتیک و داینامیک را در قالب دو پروژه شرح میهم.
فرگمنت (Fragment) چیست
به نام خدا. Fragment (فرگمنت) را می توان به عنوان یک زیر مجموعه و یا یک بخش از اکتیویتی (sub-activity) در نظر گرفت که در نهایت قسمتی از رابط کاربری را تشکیل داده و به واسطه آن یک رابط کاربری چند قسمتی ایجاد می شود. فرگمنت در اندروید مشابه آنچه قبلا برای اکتیویتی ها آموختیم، چرخه حیات و رفتار خاص خود را دارد، رویدادهای ورودی را دریافت می کند و از دو قسمت xml (لایه واسط کاربری) و کد عملیاتی (java) تشکیل شده است. هر اکتیویتی می تواند چندین فرگمنت را در خود جای دهد و هر فرگمنت می تواند در چندین اکتیویتی استفاده شود. بنابراین فرگمنت به تنهایی قابلیت اجرا ندارد و به اکتیویتی والد و چرخه حیات آن وابسته است. فرگمنت از API 11 (اندروید Honeycomb) اضافه شد.
چرخه حیات فرگمنت (Fragment Lifecycle)
فرگمنت هم مانند اکتیویتی چرخه حیات خاص خود را دارد که تا حد زیادی مشابه چرخه حیات اکتیویتی است. خوب است ابتدا مروری بر این چرخه حیات داشته باشیم.
()onAttach : این متد هنگامی که فرگمنت به اکتیویتی اضافه شده خوانده می شود.
()onCreate : این متد برای مقداردهی در هنگام ساخت فرگمنت فراخوانی می شود.
()onCreateView : این متد زمانی فراخوانده می شود که فرگمنت ایجاد شده و آماده ساخت واسط کاربری (UI) است. در اکتیویتی این وظیفه بر عهده onCreate() بود.
()onActivityCreated : این متد در زمانی فراخوانده می شود که اکتیویتی میزبان فرگمنت اجرا شده است.
()onStart : این متد زمانی فراخوانده می شود که رابط کاربری فرگمنت آماده نمایش است.
()onResume : در این زمان فرگمنت فعال است.
()onPause و ()onStop : این متد در زمان پایان فعالیت فرگمنت اجرا می شود و اگر لازم است چیزی ذخیره شود در این مرحله باید انجام داد.
()onDestroyView : این متد زمانی فراخوانده می شود که UI فرگمنت از اکتیویتی حذف می شود.
()onDestroy : در زمان انتهای حیات فرگمنت این متد اجرا می شود.
()onDetach : زمانی فراخوانده می شود که فرگمنت به طور کامل از اکتیویتی میزبان خود جدا شده است.
از مفاهیم فاصله گرفته و با ذکر مثالهایی، آموزش را ادامه می دهم.
پروژه شماره یک (فرگمنت های استاتیک)
شاید ساده ترین مثال، همان اپلیکیشن کتاب باشد که اگر قبلا در مورد فرگمنت در وب جستجو کرده باشید به احتمال زیاد با آن برخورد کرده اید.
تصویر بالا یک تلفن هوشمند و یک تبلت را نشان می دهد. قصد دارم یک کتابچه اندرویدی توسعه بدهم. حالت ساده و ابتدایی این است که چینش اجزاء رابط کاربری در همه اندازه ها و حالت های مختلف صفحه نمایش، یکسان باشد. اما از نظر UX (تجربه کاربری) این امر پسندیده نبوده و باید حالتهای متفاوتی را برای اندازه های مختلف صفحه نمایش در نظر بگیریم تا تمامی کاربران تجربه خوبی هنگام تعامل با برنامه ما داشته باشند.
نکته : تجربه کاربری (UX) مفهومی است که در کنار مفهوم رابط کاربری (UI) مدتیست مورد توجه توسعه دهندگان وب و اپلیکیشن قرار گرفته. به طور خلاصه نحوه چینش عناصر، رنگهای بکار رفته و هرآنچه که باعث می شود تا کاربر ارتباط بهتری با محصول ما برقرار کند، در استفاده از بخش های مختلف آن دچار سردرگمی نشده و در نهایت تعامل رضایت بخشی را تجربه کرده باشد، همگی در حوزه تجربه کاربری قرار می گیرد. توصیه می کنم چند دقیقه ای وقت گذاشته و در این خصوص جستجو و مطالعه کنید.
اپلیکیشن کتاب ما شامل یک لیست موضوعی است که کاربر با انتخاب هریک از گزینه های موجود در لیست، به متن مربوط به آن هدایت می شود. در صفحات عمودی (Portrait) و همچنین صفحات کوچک، حالت مطلوب این است که در صفحه اصلی فقط لیست موضوعات نمایش داده شود و کاربر با انتخاب هر گزینه، برای مطالعه متن به صفحه جدید منتقل شود که به صورت کامل متن را نمایش داده و خبری از لیست موضوعات نیست. اما این حالت برای تبلت و در حالت افقی (Landscape) شاید منطقی به نظر نرسد و پذیرفتنی نیست که یک صفحه عریض بخواهد فقط چند کلمه را در هر سطر نمایش دهد. اینجا گزینه مطلوب این است که لیست و متن، هر دو را در کنار هم برای کاربر نمایش دهیم. هر موضوعی که کاربر انتخاب کرد، متن آن در کنار لیست نشان داده شود.
برای تحقق این هدف، از فرگمنت استفاده می کنیم. با بکارگیری فرگمنت، نیازی به تعریف چندباره لیست و قسمت مربوط به نمایش متن در اکتیویتی های مختلف نداریم و تنها کافیست یکبار آنها را در دو فرگمنت مجزا ایجاد کرده و سپس به تعداد لازم و در اکتیویتی های مختلف، فرگمنتها را فراخوانی کنیم.
یک پروژه با نام FragmentOne و API 16 می سازم. در زمان تهیه این آموزش بر اساس آمار گوگل حدود ۹۶ درصد دیوایس های اندرویدی فعال، شامل نسخه ۱۶ و بالاتر اندروید می شوند و من ترجیح میدهم پروژه خود را روی این ورژن پیاده سازی کنم.
در این مثال من وارد جزئیات از جمله لیست و متن موضوعات نمی شوم و به آشنایی با نحوه پیاده سازی فرگمنت ها بسنده می کنم.
فرگمنت ها به دو صورت ایستا (Static) و پویا (Dynamic) به اکتیویتی اضافه می شوند که در این پروژه من فرگمنتها را به صورت ایستا استفاده می کنم.
روی فولدر app پروژه راست کلیک کرده و در مسیر New > Fragment یک فرگمنت خالی (Blank) انتخاب می کنم:
در مرحله بعد نام فرگمنت را تعیین می کنم. من برای این فرگمنت نام frg1 را انتخاب کردم:
با انتخاب گزینه Create layout XML ، لایه رابط کاربری این فرگمنت به صورت خودکار ساخته شده و نیاز به ساخت دستی آن نیست. اندروید استودیو نام Layout را بر اساس نام فرگمنت تعیین می کند که نیازی به تغییر آن نمی بینم. در پایان دو گزینه به صورت پیش فرض انتخاب شده که من فعلا به متدهای اضافی نیازی ندارم و تیک هر دو را برمیدارم. با زدن گزینه Finish، فرگمنت ایجاد می شود.
کد frg1.java:
package ir.android_studio.fragmentone; import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; public class frg1 extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment return inflater.inflate(R.layout.fragment_frg1, container, false); } }
(برای خلوت شدن محیط کار من متد سازنده را به صورت دستی حذف کردم)
کد fragment_frg1.mxl:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="ir.android_studio.fragmentone.frg1"> <!-- TODO: Update blank fragment layout --> <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:text="@string/hello_blank_fragment" /> </FrameLayout>
به ایمپورت های فرگمنت دقت کنید. دو کلاس android.support.v4.app.Fragment و android.view.LayoutInflater در لیست قرار دارند. قبلا گفتیم فرگمنت در API 11 به اندروید اضافه شده و برای استفاده از آن در نسخه های پایینتر لازم است به جای کلاس android.app.Fragment ، از کلاس android.support.v4.app.Fragment استفاده کنیم تا به واسطه کتابخانه Support امکان استفاده از آن میسر شود. البته در حال حاضر توسعه اپلیکیشن برای نسخه های ۱۱ به پایین توجیهی ندارد. من هم هنگام ساخت پروژه MinSDK را برابر ۱۶ قرار دادم. با این حال اندروید استودیو به صورت پیش فرض این کلاس را اضافه کرده که تفاوتی نمی کند و نیازی به تغییر نیست. در ادامه ملاحظه می کنید کلاس frg1 از Fragment ارث بری کرده است.
برای اتصال لایه xml به فرگمنت و نمایش آن، لازم است متد onCreateView را Override کنیم (مشابه اکتیویتی با این تفاوت که در آنجا متد onCreate استفاده می شد). در نهایت با شئ ای که از LayoutInflater ساخته شده لایه R.layout.fragment_frg1 به فرگمنت متصل شده است.
UI این فرگمنت شامل یک FrameLayout (از FrameLayout برای چهارچوب بندی در اندروید استفاده می شود) است که تنها یک TextView داخل آن قرار گرفته. برای این پروژه هم فعلا به چیز بیشتری نیاز ندارم. فقط برای تشخیص دو فرگمنت از یکدیگر، برای هرکدام متن و رنگ پس زمینه متمایز تعریف می کنم. مشابه قبل یک فرگمنت جدید با نام frg2 ایجاد کرده و Layout ها را مطابق زیر تغییر می دهم:
fragment_frg1.xml:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="ir.android_studio.fragmentone.frg1" android:background="#bf2e2e"> <!-- TODO: Update blank fragment layout --> <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:text="Fragment A" android:gravity="center"/> </FrameLayout>
fragment_frg2.xml:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="ir.android_studio.fragmentone.frg2" android:background="#1e6ea7"> <!-- TODO: Update blank fragment layout --> <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:text="Fragment B" android:gravity="center"/> </FrameLayout>
هدف ما این بود تا در صفحات عادی و پیش فرض (که آنها را به عنوان استثنائات به صورت جداگانه تعریف نکردیم) فقط یک فرگمنت و در صفحات با سایز صفحه نمایش بزرگ (تبلت) و در حالت افقی، هر دو فرگمنت در کنار هم نمایش داده شوند. به سراغ activity_main.xml می روم. با استفاده از
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="ir.android_studio.fragmentone.MainActivity"> <fragment android:layout_width="match_parent" android:layout_height="match_parent" /> </RelativeLayout>
فرگمنت به اکتیویتی اضافه شد. عرض و ارتفاع را match_parent تنظیم کردم تا فرگمنت تمام اکتیویتی را به خود اختصاص دهد. (دقت کنید ممکن است به صورت خودکار به انتهای fragment اضافه نشده باشد). در قدم بعد می بایست کلاس frg1 را به این
مقدار این خاصیت را برابر نام کلاسی قرار می دهم که می خواهم نمایش داده شود. اندروید استودیو لیست فرگمنت ها را نمایش داده و نیازی به وارد کردن دستی نیست. با این حال اگر لازم شد نام را خودتان وارد کنید، ترکیب PackageName.FragmentClass است. به هر فرگمنت می بایست یک id نیز اختصاص داد که fr1 را انتخاب می کنم:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="ir.android_studio.fragmentone.MainActivity"> <fragment android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/fr1" android:name="ir.android_studio.fragmentone.frg1" /> </RelativeLayout>
اگر Layout را در حالت Design قرار دهید ارور زیر را مشاهده خواهید کرد:
مضمون پیغام این است که اگر مایلم در حالت Preview و در محیط توسعه هم فرگمنت انتخاب شده نمایش داده شود، با کلیک روی Use @layout/fragment_frg1 خاصیت مربوط به آن به
tools:layout="@layout/fragment_frg1"
حالا در محیط توسعه هم فرگمنت نمایش داده می شود:
اضافه کردن
پس از کشیدن
چون در این آموزش صرفا نحوه اضافه کردن فرگمنتها را بررسی می کنیم، از انتقال به Fragment B صرف نظر می کنم و به سراغ مرحله دوم می روم، یعنی ساخت رابط کاربری مناسب تبلت ها در حالت افقی. در اندروید سایز صفحه نمایش در ۴ دسته Small، Normal، Large و X-Large قرار می گیرد. قصد ندارم در این آموزش به مبحث سایز بندی بپردازم و صرفا جهت آشنایی با فرگمنت ها به صورت اجمالی ساخت Layout جدید را توضیح می دهم. صفحه نمایش تبلت در رده سایز Large قرار می گیرد. از طرفی قصد دارم لایه جدید بر روی صفحه ای که در حالت افقی (Landscape) قرار گرفته اعمال شود. بنابراین در کنار پوشه layout پروژه، یک پوشه جدید با نام layout-large-land می سازم و یک کپی از activity_main.xml اصلی داخل آن قرار می دهم.
برای ساخت پوشه جدید، روی res راست کلیک کرده و Android resource directory را انتخاب می کنم. حالا با انتخاب layout به عنوان Resource type و تکمیل نام دایرکتوری، پوشه جدید را می سازم:
علاوه بر نوشتن دستی نام فولدر، با انتخاب گزینه های Size و Orientation و انتقال آنها به قسمت Chosen qualifiers و در نهایت انتخاب گزینه مدنظر، نام دایرکتوری به صورت خودکار تکمیل می شود (ضمن اینکه در خارج از محیط اندروید استودیو و در محل ذخیره پروژه هم به راحتی می توان دایرکتوری موردنیاز را به پروژه اضافه کرد).
حالا یک کپی از activity_main.xml ساخته و به دایرکتوری layout-large-land منتقل می کنم. هنگامی که ساختار نمایش پروژه روی Android تنظیم شده، دایرکتوری که جدید ساختیم نمایش داده نمی شود و لازم است حالت نمایش پروژه را موقتا از Android به Project تغییر داده و فایل کپی شده را روی دایرکتوری مدنظر Paste کنیم (و یا باز هم در محل ذخیره پروژه در سیستم عامل خود، عمل کپی فایل به دایرکتوری را انجام دهیم).
البته روش ساده تری هم هست. وقتی من activity_main.xml را کپی کرده و یک دایرکتوری خالی هم وجود دارد، اندروید استودیو هدف من را تشخیص می دهد و کافیست در همان حالت نمایش Android، روی layout راست کلیک و Paste کنیم. پنجره ای باز می شود که مسیر انتقال را layout-large-land معرفی می کند که با تایید آن، انتقال به درستی انجام می شود:
نکته : الزامی به کپی کردن layout قبلی و انتقال به دایرکتوری جدید نیست و در واقع این عمل همان ساخت layout جدید است. در مواردی که لایه ما کامپوننت های متعددی داشته و قصد اعمال تغییرات جزئی داشته باشیم، احتمالا کپی راه حل ساده تری است اما در مواردی مثل پروژه فعلی که یک اکتیویتی ساده داریم و علاوه بر آن، لایه پیش فرض را از جنس RelativeLayout ساخته بودیم که لازم است در حالت Large Landscape لایه را از نوع LinearLayout بسازیم، ساخت یک لایه جدید و همنام با لایه پیش فرض منطقی خواهد بود:
Layout > New > Resource File
اگر می خواهید لایه جدید را به این شیوه بسازید و قبلا آنرا توسط کپی از لایه پیش فرض ساخته اید، کافیست آنرا حذف کرده و مجدد از این طریق اقدام کنید.
لایه جدید ایجاد شد و در قسمت Preview به صورت افقی نمایش داده شده است:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> </LinearLayout>
حالا دو activity_main.xml داریم که دومی مقابل آن large-land قید شده. هنگامی که برنامه روی دیوایسی با سایز صفحه نمایش Large اجرا شود و دیوایس در حالت افقی قرار گرفته باشد، به جای activity_main.xml پیش فرض، activity_main.xml موجود در دایرکتوری layout-large-land برای کاربر رندر می شود. پس در این لایه دو
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="match_parent"> <fragment android:name="ir.android_studio.fragmentone.frg1" android:id="@+id/fr1" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1"/> <fragment android:name="ir.android_studio.fragmentone.frg2" android:id="@+id/fr2" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="2" /> </LinearLayout>
خاصیت orientation را به horizontal تغییر دادم تا دو فرگمنت به صورت افقی در کنار هم قرار بگیرند. با وزن دهی (layout_weight) قبلا در فصل پنجم آشنا شدیم.
حالا پروژه آماده ی اجراست. من یک دیوایس Tablet روی جنی موشن ساخته ام و پروژه را روی آن اجرا می کنم. دیوایس در ابتدا روی حالت عمودی قرار دارد:
همانطور که انتظار داشتم فقط یک فرگمنت نمایش داده می شود (Fragment A). در مرحله بعد با کلیک روی گزینه تنظیمات دیوایس (سه نقطه) و یا Ctrl + F11 دیوایس در حالت افقی قرار می گیرد:
با چرخش دیوایس، Layout موجود در دایرکتوری large-land به درستی جایگزین layout اصلی پروژه شد.
پروژه شماره دو (فرگمنت های داینامیک)
در مثال قبل با فرگمنت های استاتیک آشنا شدیم. تفاوت فرگمنت پویا با استاتیک در این است که در فرگمنت پویا در زمان اجرا می توان یک فرگمنت را جایگزین فرگمنت قبلی کرد. یعنی می توان در یک اکتیویتی چند محتوای متفاوت را بنا به نیازی که کاربر دارد نمایش داد بدون اینکه لازم باشد از یک اکتیویتی به اکتیویتی دیگر منتقل شود. یا به عنوان مثال به جای اینکه به وسیله Intent کاربر به برنامه پیش فرض دوربین دیوایس منتقل شده، عکس گرفته و مجدد به برنامه برگردد و روی تصویر ویرایش انجام دهد، تمامی مراحل درون برنامه انجام شود (مشابه نرم افزارهای بارکدخوان و…).
در این مثال قصد دارم فرگمنت های پویا را با یک مثال ساده معرفی کنم.
از پروژه قبل خارج شده (File > Close Project) و یک پروژه جدید با نام FragmentTwo می سازم. پروژه من شامل یک اکتیویتی و دو فرگمنت است. درون اکتیویتی دو Button و یک FrameLayout وجود دارد که با لمس هریک از دکمه ها، یکی از دو فرگمنت در FrameLayout نمایش داده شده و جایگزین فرگمنت قبل می شود.
ابتدا دو فرگمنت با نامهای FrgOne و FrgTwo عینا مشابه پروژه قبل اضافه می کنم. در مرحله بعد لایه activity_main.xml را همانگونه که در پاراگراف بالا عنوان شد می سازم. اکتیویتی را به نوع LinearLayout و چینش عمودی تغییر داده و به هریک از عناصر یک id اختصاص داده ام.
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="ir.android_studio.fragmenttwo.MainActivity"> <Button android:id="@+id/btn_a" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Select Fragment A" /> <Button android:id="@+id/btn_b" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Select Fragment B" /> <FrameLayout android:id="@+id/frg_holder" android:layout_width="match_parent" android:layout_height="match_parent"> </FrameLayout> </LinearLayout>
سپس Button ها را داخل اکتیویتی تعریف کرده و دو متد مربوط به دکمه ها را نیز اضافه می کنم:
package ir.android_studio.fragmenttwo; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; public class MainActivity extends AppCompatActivity { Button btnOne, btnTwo; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btnOne = (Button) findViewById(R.id.btn_a); btnTwo = (Button) findViewById(R.id.btn_b); btnOne.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { } }); btnTwo.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { } }); } }
نکته : برای اینکه فرگمنت اجرا شود، باید اکتیویتی والد آن حتما از FragmentActivity یا AppCompatActivity ارث بری شده باشد.
ابتدا متد یکی از دکمه ها را کامل کرده و سپس به توضیح جزئیات می پردازم.
btnOne.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { FrgOne frg1 = new FrgOne(); FragmentManager fm = getSupportFragmentManager(); FragmentTransaction ft = fm.beginTransaction(); ft.replace(R.id.frg_holder, frg1); ft.commit(); } });
در خط اول ابتدا یک نمونه از فرگمنت FrgOne با نام frg1 ساختم. در قدم بعد برای مدیریت فرگمنت ها به نمونه ای از کلاس FragmentManager نیاز دارم:
دو گزینه در اختیار داریم که اولی مربوط به کتابخانه Support می شود. همین را انتخاب می کنم. برای گرفتن آن دو گزینه getSupportFragmentManager() یا getFragmentManager() قرار می گیرد که مسلما باید getSupportFragmentManager() را انتخاب کنم. برای تبادل پیامهای فرگمنت در اکتیویتی (add، remove و replace) باید از FragmentTransaction استفاده کنیم که نام ft را درنظر گرفتم و در مقابل با متد beginTransaction() فرگمنت آماده جایگزینی می شود. در خط بعد، از متد replace استفاده کرده ام که دو ورودی می گیرد. اولی، id مربوط به FrameLayout که قرار است فرگمنت در آن جایگذاری شود و دوم، نام فرگمنت موردنظر. در نهایت لازم است با دستور commit() انجام این پروسه را آغاز کنیم.
برای دکمه دوم هم به همینصورت کد را تکمیل می کنم با این تفاوت که فرگمنت دوم باید جایگزین شود.
کد نهاییی MainActivity.java:
package ir.android_studio.fragmenttwo; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentTransaction; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; public class MainActivity extends AppCompatActivity { Button btnOne, btnTwo; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btnOne = (Button) findViewById(R.id.btn_a); btnTwo = (Button) findViewById(R.id.btn_b); btnOne.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { FrgOne frg1 = new FrgOne(); FragmentManager fm = getSupportFragmentManager(); FragmentTransaction ft = fm.beginTransaction(); ft.replace(R.id.frg_holder, frg1); ft.commit(); } }); btnTwo.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { FrgTwo frg2 = new FrgTwo(); FragmentManager fm = getSupportFragmentManager(); FragmentTransaction ft = fm.beginTransaction(); ft.replace(R.id.frg_holder, frg2); ft.commit(); } }); } }
پروژه را اجرا می کنم:
در ابتدا ناحیه مربوط به FrameLayout خالی است به این معنی که هیچ فرگمنتی در آن جایگذاری نشده. انتظار دارم با کلیک روی دکمه ها، فرگمنت های مرتبط نمایش داده شوند:
برنامه به درستی کار می کند.
تعداد صفحات : ۳۰
حجم : ۱٫۶ مگابایت
قیمت : رایگان
دانلود رایگان با حجم ۱٫۶ مگابایت لینک کمکی
سلام واقعا مفید بود دم شما گرم
سلام خدا قوت بسیار مطالب آموزشی مفیدی ارایه می کنید خدا یارتان
سلام
وقتی میخام اجرا کنم خطا زیر را میده.
Execution failed for task ‘:app:checkDebugAarMetadata’.
> Could not resolve all files for configuration ‘:app:debugRuntimeClasspath’.
> Could not find androidx.legacy:legacy-support-v4:1.0.0.
Searched in the following locations:
– https://dl.google.com/dl/android/maven2/androidx/legacy/legacy-support-v4/1.0.0/legacy-support-v4-1.0.0.pom
– https://jcenter.bintray.com/androidx/legacy/legacy-support-v4/1.0.0/legacy-support-v4-1.0.0.pom
Required by:
project :app
Possible solution:
– Declare repository providing the artifact, see the documentation at https://docs.gradle.org/current/userguide/declaring_repositories.html
تاکید شده قبل از ارسال دیدگاه، صفحه پرسش های رایج رو مطالعه بفرمایید
اموزش هاتون عالیه واقعا خسته نباشید
سلام میخواستم بدونم ایا شما برای کلیک روی فرگمنت لیست و رفتن به یک فرگمنت دیگر میدونید باید چیکار کنم؟
منظورتون از فرگمنت لیست رو متوجه نمیشم
سلام خسته نباشید
من داخل xml فرگمنتم از دکمه استفاده کردم
وقتی می خوام از دکمه داخل اکتیویتی فرگمنت استفاده کنم intent من کانتکست رو نمیشناسه و نمی تونم از this استفاده کنم من باید چیکار کنم
عذرخواه بابت تاخیر. لینک زیر رو ملاحظه بفرمائید
https://stackoverflow.com/a/20835980
با سلام و تشکر بابات توضیحات دقیق و کاملتون
میشه آموزش callback هارو هم انجام بدین؟ توی سایت سرچ زدم چیزی ندیدم چون به این مبحث فرگمنت ها هم مرتبط هست
مثلاً از اکتیویتی اطلاعات ارسال شه برای فرگمنت اول و دوم … و تکرار چرخه برگشتش
سلام
اموزشتون عالی بود یه سوال میخوام از اکتیویتی به فرگمنت دیتایی ارسال کنم و توی فرگمنت دوباره یک سری اطلاعات دیگه از کاربر بگیریم و محاسباتی انجام بدم و سپس نتیجه رو به اکتیویتی برگردنم لطفا در این مورد راهنمایی کنید
ممنون
https://android-studio.ir/android-shared-preferences
سلام استاد
من طبق آموزش وقتی که دارم فرگمنت رو درست میکنم این ارور رو بعد ساخت و موقع سینک کردن میده
ERROR: Unable to resolve dependency for ‘:app@debug/compileClasspath’: Could not resolve com.android.support:support-v4:28.0.0.
و هر چی هم سرچ کردم به جایی نرسیدم.
بزرگوار اگه صفحه پرسشهای رایج رو مطالعه میکردید نیازی به سرچ هم نداشتید
https://android-studio.ir/problems-and-questions
سلام خوبید ؟
ببخشید میشه لطف کنید اموزش بدید که چگونه میتوان از ایمج ویو اسلایدر در فرگمت استفاده کرد؟
سلام
getSupportFragmentManager();
تو اندروید استودیو شناسایی نمیشه فک کنم منسوخ شده جایگزینش چیه؟
خیر منسوخ نشده. دقت کنید کتابخانه مربوطه بالای صفحه import شده باشه. با مثال متن آموزشی مقایسه کنید
سلام
من یک app ساختم که روی گوشی که با آن تست گرفتم انداز ها خوبه ولی وقتی روی گوشی بزرگتری تست گرفتم اندازه ها هم اندازه گوشی نبود و کوچک بود
خیلی جاها گشتم ولی راه خوبی پیدا نکردم ممنون میشم اگر راهنماییم کنید که چه طوری اندازه صفحه مطابق اندازه گوشه شه
باتشکر
مطالب مربوط به رابط کاربری رو مطالعه کنید
سلام
من وقتی پروژه میسازم فایل gradle ساخته میشه
ولی وقتی فایل source شما رو اجرا میکنم build نمیشه
باید چکار کنم؟
خب ببینید چه اروری میگیرید.
سلام من یه viewPagerTabActivity ساختم و داخل یکی از فرگمنت هاش recyclerView گذاشتم و با کلیک روی هر یک از ایتم ها میخوام یه اکتیویتی نمایش داده شود
حالا چطور ارتباط بین اینا رو درست کنم؟
سلام
خیلی ممنون از اموزش های خوبتون
یک سوال داشتم متوجه هستم که در یک اکتوتی میشه چند فرگمنت همزمان داشت که کارها جدا انجام بدن و از یک فرگمنت میتوان چند جا استفاده کرد. با این توصیف سوال من این خیلی ممنون میشم اگه وقت بگذارید و پاسخ بدین:
۱- جز اکتوتی اصلی برنامه، کاری هست که فقط اکتوتی بتونه انجام بده ولی فرگمنت نتونه؟ یعنی مجبور به تعریف اکتوتی باشیم نه فرگمنت؟
۲- اگر یک صفحه بشه به صورت یکسان هم در اکتوتی هم در فرگمنت پیاده سازی کرد از نظر بارکاری و هزینه اولویت با کدوم؟
۳- ایا بهتره تا حد ممکن از فرگمنت استفاده کرد یا اکتوتی؟
ممنون
به طور کل بهتره جایی که میشه فرگمنت استفاده کرد، از اضافه کردن اکتیویتی پرهیز کنیم. مطالب زیادی در این خصوص در وب هست. لطفا مطالعه بفرمایید:
https://goo.gl/GKuUBR
سپاس از زحمات شما
توضیحاتتون عالیه
سلام
میخواستم یک تشکر صمیمانه داشته باشم از همه عزیزانی که برای این سایت زحمت میکشن.
سایتتون خیلی خیلی خیلی خیلی خیلی خیلی فوق العاده است. جدی میگم. بهترین سایت آموزشی فارسی که تابحال دیدم.
من خودم برنامه نویس اندروید هستم و از آموزش های شما هم خیلی استفاده کردم.
با آرزوی شادی، سلامتی، ثروت و سعادت در دنیا و آخرت
ممنون از آموزش عالیتون. فقط مشکلی که من دارم اینه که در فرگمنت پویا، من در xml فرگمنتم یک textview دارم اما setText آن که داخل onCreateView نوشتم کار نمیکنه. یعنی خطایی نمیده ولی متن textView هم تغییری نمیکنه. این کد رو در onCreateView نوشتم:
LayoutInflater lf = getActivity().getLayoutInflater();
View rootView =lf.inflate(R.layout.fragment_category,container,false);
TextView txtTest=(TextView)rootView.findViewById(R.id.txtTest) ;
txtTest.setText(“salam. worked!”);
https://stackoverflow.com/questions/24559124/android-set-text-of-textview-in-fragment-that-is-in-fragmentpageradapter
سلام خسته نباشید میخواستم بپرسم که چجوری باید از if استفاده کرد وقتی میخوام چک کنم ببینم توی کدوم case از فرگمنت هستم ؟
سلام
روز به خیر
خسته نباشید و ممنون
ببخشید من یه تازه کار هستم
میخواستم در هر فرگمنت یه تعداد کلید و تکست باکس تعریف کنم و با اونا کار کنم
در ساخت ظاهر فرگمنت اونجور که مد نظرم هست با استفاده از راهنمایی سایت شما موفق شدم اما نمیدونم کجا و چطور و با چه دستوراتی در جاوای مربوط به فرگمنا مقادیر تکست باکس ها رو بخونم و با کلید روی اونا اعمال مورد نظرمو انجام بدم
اصلا آیا این امکان پذیر هست که برای فرگمنت ویجت تعریف کرد و روی اونا عملیات خاصی رو انجام داد ؟؟
فرگمنت تفاوتی با یه اکتیویتی نداره و هرچیزی که مدنظرتون هست رو میتونید پیاده کنید. همونطور که داخل یه اکتیویتی ویجت تعریف میشه و تو کلاس جاواش عملیات رو تعریف کرد
ممنون از پاسختون
الان من میخوام تو فرگمنتم یه ادیت تکست و یه باتن تعریف کنم که یک مقدار رو بعنوان سانتیمتر بگیره و با فشار باتن اونو به اینچ تبدیل کنه
در فرگمنت دوم هم یه ادیت تکست و یه باتن تعریف کنم و میخوام سانتیگراد رو به فارنهایت تبدیل کنه
اما نمیدونم کد جاوای فرگمنت ها رو کجا بنویسم و چطور این کار رو بکنم
خواهش میکنم اگه وقتتون اجازه میده کمک کنید
ممنون
ببخشید اگه سوالام مبتدیه خیلی
ببینید فرگمنت هم مثل اکتیویتی از یه لایه و فایل جاوا تشکیل شده که داخل آموزش واضح توضیح دادم. ینی fragment_frg1.xml و frg1.java مربوط به فرگمنت اول هستند.
علیرغم اینکه مشکلم حل نشد ولی از اینکه با صبوری پاسخ دادین متشکر و قدردان هستم
ممنونم از اینکه حوصله به خرج دادین و پاسخ حقیر رو دادین
میتونید یک منبع خوب و کامل در مورد UI اندروید معرفی کنید؟
ممنون از آموزش های خوبتون
منبع خاصی مدنظرم نیست. سرچ کنید
سلام. خیلی مفید، کاربردی، کامل و عالی بود. تشکر از زحمات شما.
لطفا آموزش در خصوص ارتباط اندورید با وب سرویس Asp.net هم بزارید