بروز رسانی فرگمنت در تب لیوت
سلام
من 2 تا فرگمنت دارم؛ یکی برای وارد کردن اطلاعات ، یکی هم برای نمایش اطلاعات وارد شده
داخل اکتیویتی ها از متد onResume استفاده میکردم و جواب میداد،چون یکبار مجدد اکتیویتی ساخته میشه
ولی داخل فرگمنت وقتی به اکتیویتی کناری که وظیفه نمایش سطرهای وارد شده در دیتابیس رو داره ، میرم، سطر جدید رو نمایش نمیشه و حتما باید برنامه رو باز و بسته کرد
لطفا کمک کنید
دوست عزیز کار شما یکم پیچیدست. اینجوری که من فهمیدم شما یک فرگمنت Home داری که روش یک فرگمنت که مقادیری رو توی دیتابیس اد میکنه داره، وقتی مقادیر اد میشه، فرگمنت رویی بسته میشه و Home نمایش داده میشه. اگر درسته که باید از روش زیر استفاده کنی تا بتونی Home رو آپدیت کنی.
روش اول و شاید اصولی ترین روش: شما باید لیست تمام فرگمنت های attach شده رو بگیری، ببینی اگر Home توشون هست یک instance ازش بسازی و متد refresh رو توش صدا بزنی. بعد فرگمنت add رو ببندی. اینجوری پشت صحنه عملیات به روز رسانی انجام میشه.
روش دوم که اصلا پیشنهاد نمیکنم : متد refresh رو static کنی و از توی فرگمنت add صداش کنی. حتما باید توی try catch بذاری که فاجعه رخ نده. کار میکنه ولی اصلا راه خوبی نیست.
روش سوم : یک کنترلر براش بنویسی. یعنی یک کلاس باشه، که لیست ویو رو بگیره، زمانی که عملیات اد انجام میشه یک لیستنر توش کال بشه و خودش لیست ویو رو آپدیت کنه. (اینم راه خیلی خوبیه ولی نوشتنش به همین سادگی که گفتم نیست و خیلی چیزا باید توش رعایت بشه)
روش چهارم: استفاده از متد onResume (که فکر نکنم توی فرگمنت های اصلا جواب بده، تست کنید نتیجه رو اینجا بگید)
روش پنجم: پاس دادن لیست ویو و آپدیت کردنش توی فرگمنت add (اصلا و ابدا به هیچ وجه پیشنهاد نمیشه، فقط گفتم که بدونید همچین راه هایی هم وجود داره ولی نباید انجام داد!)
روش ششم: پاک کردن backstack و ساختن مجدد فرگمنت Home (این یکی از ساده ترین راه هاست که نه میشه گفت بده، نه میشه گفت خیلی راه خوبیه)
اگر نتونستید پیاده سازیش کنید، توی این چند روز بهم پی ام بدید وقت کردم براتون درستش میکنم و آموزش میذارم.
موفق باشید
واتیکان عزیز متاسفانه من تایمم واقعا محدوده و توی 7 روز هفته فقط یک نصفه روزم خالیه.
من روش اصولی رو به شما میگم، نمونه کد هم براتون قرار میدم، ولی اینکه شما چقدر این کد رو اصولی، تمیز و داینامیک بنویسید توضیحش در یک تاپیک نمیگنجه و خودتون باید با تلاش راه حلی براش پیدا کنید.
برای انجام کاری که شما میخواید انجام بدید، روش به این صورته:
فرگمنت دوم باید به فرگمنت اول دستور بده که یکسری عملیات رو انجام بده. به هیچ وجه نباید عملیات رو توی فرگمنت دوم انجام بدید یا از متغیر یا ویو های استاتیک استفاده کنید.(دلیلش خیلی طولانیه و یکم که بیشتر کار کنید کاملا متوجه مشکلاتش میشید).
برای این کار در فرگمنت اول یک متد public درست میکنیم. ارسال listener به فرگمنت دوم کار درستی نیست، چون شما مجبوری از یک لیستنر استاتیک استفاده کنی و بالا گفتم که این کار اصولی نیست.
متد زیر رو توی فرگمنت اول بنویسید:
public void setColor(){
btn.setBackgroundColor(Color.parseColor("#ff0000"));
}
این متدی که من برای تست نوشتم، رنگ زمینه یک button رو تغییر میده، شما میتونید متد خودتون رو بنویسید، هیچ فرقی نداره.
با کلیک روی یک دکمه فرگمنت دوم رو add کنید:
getFragmentManager().beginTransaction()
.add(R.id.container, new PlusTwoFragment(), "SECOND")
.addToBackStack("SECOND")
.commit();
خوب حالا توی فرگمنت دوم کد زیر رو در onViewCreated یا onCreateView قرار بدید:
view.findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
List<Fragment> fragments = getFragmentManager().getFragments();
for(int i=0;i<fragments.size();i++){
if(fragments.get(i) != null && fragments.get(i).getTag().toString().equals("FIRST")){
((PlusOneFragment) fragments.get(i)).setColor();
}
}
getActivity().onBackPressed();
}
});
توضیحات کد بالا :
در خط اول تمام فرگمنت هایی که در حافظه میباشند رو توی یک لیست از فرگمنت ها قرار میدیم.
در خط دوم یک حلقه وجود داره که تمام فرگمنت هارو چک میکنه.
در خط سوم چک میکنیم که آیا فرگمنتی که پیدا کردیم فرگمنت اول هست یا خیر.
در داخل شرط به فرگمنت پیدا شده دستور میدیم که متد setColor رو اجرا کنه.
در آخر هم دکمه back گوشی رو صدا میزنیم تا به فرگمنت قبلی برگردیم.
حالا مشکل این کد کجاست؟ زمانی که شما نمیخوای فرگمنت جدید رو add کنی و میخوای replace کنی.
در این موقع متد شما کار میکنه، ولی خروجی اونی نیست که شما میخواید. ینی اول متد setColor اجرا میشه، ولی چون فرگمنت از اول ساخته میشه تغییرات شما دیده نمیشه. برای رفع این مشکل باید چه کاری کرد:
اینجا 2 شرایط وجود داره که راه حل جفتش رو میگم:
1: در صورتی که بخواید به فرگمنت دیگه ای برید و نخواید از دکمه back استفاده کنید، خیلی ساده به فرگمنت مقادیری پاس میدید و در onViewCreated در فرگمنت بعدی اونارو میگیرید و اگر extras مخالف null بود متدتون رو اجرا میکنید.
2: اگر میخواید با زدن دکمه back به فرگمنت دیگه ای برید باید توی اکتیویتی در قسمت onBackPressed تغییراتی بدید.
این تغییرات به این صورت هست که شما باید ببینید کدوم فرگمنت هستید و میخواید کجا برید. برای فهمیدن اینکه در حال حاضر در چه فرگمنتی هستید کافیه از شرط زیر در حلقه ای که بالا نوشتیم استفاده کنید:
Fragment fragment = fragments.get(i); if (fragment.getTag() != null && !fragment.isHidden() && fragment.isVisible())
بعد از اینکه فرگمنتی که در حال حاضر داره روی صفحه نمایش داده میشه رو پیدا کردید، با استفاده از یک switch میتونید چک کنید تگ این فرگمنت مال کدوم یکی از فرگمنت های شماست.
خوب با استفاده از کد بالا فرگمنت جاری رو پیدا کردید، حالا فقط کافیه بگید اگر فرگمنت من دومی بود، عملیات replace رو انجام بده و مقادیری که میخواید رو بهش پاس بدید. در فرگمنتی که میخواید برید (توی مثال شما فرگمنت اول هست) مقادیر extras رو بخونید و اگر extras != null بود متد setColor رو اجرا کنید.
امیدوارم خیلی پیچیده و طولانی نبوده باشه، اگر بود بگید سر فرصت خلاصه و تمیز تر توضیح بدم.
--- این که من کدهارو توی فرگمنت ها نوشتم و خلاصه کردم روش درستش نیست. توی پروژه های بزرگ که شما 200 کلاس داری، باید همه این کارها رو توی helper ها و handler های خودت بنویسی. یعنی کلاس هایی باشن، که عملیات بالا رو مدیریت کنن، ولی شما فعلا همینجوری پیاده سازیش کن و کم کم سعی کن مرتبشون کنی.
موفق باشید
پاسخگویی و مشاهده پاسخ های این سوال تنها برای اعضای ویژه سایت امکان پذیر است .
چنانچه تمایل دارید به همه بخش ها دسترسی داشته باشید میتوانید از این بخش لایسنس این آموزش را خریداری نمایید .