ViewPager'dagi bir nechta fragmentlar orasidagi aloqa obyektlari

Men biznes ob'ektini bir nechta maydonlarni asta-sekin to'ldirish uchun foydalaniladigan ViewPager da 5 ta fragment mavjud bo'lib, har bir qadamda ushbu maydonlarning bir qismi o'rnatiladi. Fragmanlar o'rtasidagi aloqalar haqida juda ko'p maqolalarni o'qidim, ammo boshqalar afzal ko'rganimdan o'zimni qulay his qilmayman, shuning uchun bu haqda qanday fikrda ekanligimni bilib olgandan so'ng, nihoyat, barcha qismlarga osongina kira oladigan yagona modelli ob'ektni ishlatishni o'ylay boshlayman o'z sohalarida va ularni aniq qadamlar bilan to'ldiradi.

Android uchun yangi bo'lganim kabi mutaxassislardan tajribali mutaxassislardan eshitish vositasi sifatida ishlatish o'rniga, singletonni ishlatish haqida eshitishni xohlayman (u juda murakkab va texnik jihatdan qiyin ko'rinadi). Har qanday maslahat foydali bo'ladi.

15
Bir xudo obyekti singletonini ishlatish o'rniga, boshqa fraqmentlar uchun LocalBroadcastManager.getInstance (...). SendBroadcast() yordamida biror narsa o'zgarganligini bilib, BroadcastReceivers LocalBroadcastManager -ga bosing
qo'shib qo'ydi muallif Shark, manba
Ha, uning qimmatligi va faoliyatidagi umumiy interfeysni, fragmentlarni, viewpager va blah blah-dasturlarini amalga oshirish juda murakkab. Sizning fikringizni qadamlarning ustuvorligini o'zgartiring yoki bosqichlar o'rtasida qo'shimcha qadamlar qo'shishingiz kerak.
qo'shib qo'ydi muallif saber, manba
@ValentinoS. OnPageChangeListener ichida interfeyslarni boshqarish haqida ba'zi resurslar yoki misollar bera olasizmi?
qo'shib qo'ydi muallif saber, manba
@AnuragSingh Viewpagerning birinchi qismida yarating va serverga ish ma'lumotlarini yuborganingizdan so'ng, obyektni to'ldirguncha, viewpagerda biznes modeli ob'ektiga kirishning barcha qismlari, hech qanday adapter FragmentStatePagerActivity xizmatini uzatmaydi.
qo'shib qo'ydi muallif saber, manba
@ValentinoS. Men SharedPreferences kodi String , Boolean va hokazo kabi oddiy ma'lumot turi uchun qiymatni saqlash uchun ishlatiladi deb o'ylayman!
qo'shib qo'ydi muallif saber, manba
Men ham xuddi shu stsenariyga ega bo'ldim va uni hal qilish uchun singleton modelini qo'lladim va uni juda qimmat vazifa bo'lgan qismlar orasidagi ma'lumotlarni uzatishdan ko'ra yaxshi deb topdim
qo'shib qo'ydi muallif arjun, manba
Sizning aniq muammoningizni bilmayman, lekin fragmentlar orasidagi interfeyslarni ishlatishni ko'rib chiqdingizmi (va ularni OnPageChangeListener ichida ishlatish kerakmi)?
qo'shib qo'ydi muallif Valentino S., manba
Men biror narsani yozmoqchiman, ehtimol sizning talablaringizga mos kelmaydi. Tez orada tekshirib ko'ring
qo'shib qo'ydi muallif Valentino S., manba
SharedPreferences dan foydalanmoqchimisiz? Yoki juda murakkabmi?
qo'shib qo'ydi muallif Valentino S., manba
Ehtimol sizga yordam bermaydi, lekin siz birgalikdagi imtiyozlarda JSON Ob'ektni saqlashingiz mumkin
qo'shib qo'ydi muallif Valentino S., manba
Biznes obyektini qachon yaratasiz? Biznes obyekti uchun qiymatlarni qaerdan olasiz? Viewpager adapterini FragmentStatePagerAdapter kengaytiradimi?
qo'shib qo'ydi muallif Anurag Singh, manba

7 javoblar

Men global bir juftlik tavsiya qilmayman. Ikkita asosiy sabab bor:

  1. Tushunchaga ko'ra, bitta qo'shimchani ilovangizni asosiy biznes ob'ektining bir nusxasiga cheklaydi. Agar siz (yoki dizayner yoki xo'jayiningiz xo'jayiningiz xo'jayiningiz) bu ViewPagers bir vaqtning o'zida bir nechta bo'lishga qaror qilsangiz, sizning me'morchiligingizni o'zgartirasiz.
  2. "Android fikrlash usuli" - foydalanuvchingiz ilovangizni orqa fonga qo'yishi va boshqa ilovalarni ilovaga qaytib kelishidan foydalanishlari mumkin. Tizim sizning ilovangizni fonda o'ldirishga qaror qilsa, sizning shaxsiy xotira obyektingiz yo'q qilinadi va foydalanuvchi sizning barcha taraqqiyotingizni yo'qotadi. Haqiqiy vaziyatni saqlab qolish uchun to'g'ri Android usuli - bu holatni onSaveInstanceState() da saqlab, uni onCreate() ga qayta tiklab, uni Activity yoki Fragmentda saqlashdir.

ViewPager ichidagi barcha parchalar getActivity() ga qo'ng'iroq orqali ota-ona faoliyatiga murojaat qilishlari mumkin. Yoki ViewPager Fragment ichida bo'lsa, u holda barcha Fragmanlar getParentFragment() ga qo'ng'iroq orqali ota-bobga kirishlari mumkin. Keyinchalik, natijani tegishli sinfga (yoki undan ham yaxshiroq, interfeysga) ko'chirishingiz va ma'lumotlarni oldinga va orqaga o'tkazish uchun usul qo'ng'iroqlarini amalga oshirishingiz mumkin. Sizning biznes ma'lumotlarini ota-ona faoliyat/parchada kuzatib boring. Shunday qilib, siz global singletonga ehtiyoj sezmaysiz

Misol uchun,

public class MyParentFragment extends Fragment {

  private String mPageOneData;
  private int mPageTwoData;
  private List mPageThreeData;

  public void setPageOneData(String data) {
    mPageOneData = data;
  }

  ...
}

public class PageOneFragment extends Fragment {

  private void sendDataToParent(String data) {
    Fragment f = getParentFragment();
    if (f != null && f instanceof MyParentFragment) {
      MyParentFragment parent = (MyParentFragment) f;
      f.setPageOneData(data);
    }
  }

}
5
qo'shib qo'ydi

Singletonning yondashuvi oson bajarilishi mumkin va uni tushunishingiz kerak bo'lgan narsaga erishishning eng yaxshi usuli emas. Buning bir sababi shundaki, sizning modelingiz ob'ekti yoki uni sizning biznes obyektingiz deb atagan holda, xatolaringizni topish uchun qiyinlasha oladigan faoliyat kontekstidan tashqarida yashaydi. Masalan, Faoliyat sinfingizning bir nechta nusxasi tizim tomonidan yaratilgan bo'lsa va ikkovingiz ham sizning singletoningizga murojaat qilsalar. Ob'ektlaringizning yo'lini qanday yo'qotishingizga qarang.

Men nima qilishimni bilaman

  1. Make my model object to implement Parcelable you will hate it at the beginning but once you get use to it it will become your model's best friend
  2. Since your model is parcelable now you can easily pass it between fragments, activities, and even save it in shared preferences. One important thing to note here when you pass your parcelable between fragment or activity it is like pass by value, i.e. every time new instance is created.
  3. Set your fragment's argument or if it is already instantiated then get arguments and add your model. here is an example: if a fragment is not active yet:

    Bundle args = new Bundle(); args.putParcable("businessObject", yourBusinessObjectThatIsParcable); yourFragment.setArguments(args);

    Otherwise: yourFragment.getArguments().putParcelable("businessObject", yourBusinessObjectThatIsParcable);

  4. In your fragment perhaps in onCreateView method get your model object like this MyParcableObject mpo = (MyParcableObject)getArguments().getParcelable("businessObject") and use it set whatever data you want.

  5. When you finish editing your object on button click or in onPause method updated your fragment's arguments same way getArguments().putParcelable("businessObject", mpo);

  6. in your last page or last fragment you can pass your object to your activity, here is how to do it

Garchi u noqulay ko'rinadigan bo'lsa-da, lekin u sizni android ishlab chiquvchisi sifatida ishlatish kerak bo'lgan amaliyotdir. Sizning modelingiz parcelable amalga oshirilganda juda ko'p nazoratga ega bo'lasiz.

Sizga kerak bo'lgan narsani amalga oshirishning yana bir yo'li - delegatsiya naqshde , lekin asosan qo'ng'iroqlar uchun ishlatiladi. siz ham moslamalarni topshirishingiz mumkin.

4
qo'shib qo'ydi
  1. Siz o'zingizning ma'lumotlarni saqlab qo'yishingiz mumkin, agar sizning jarayoningiz fonga kirsa. Bundle va getExtras() dan foydalanib ma'lumotlaringizni onCreate() tadbirida qayta tiklashingiz mumkin.

  2. Ma'lumotlaringizni dastur sinfida saqlashingiz mumkin va agar jarayoningiz fonga kirsa, ma'lumotlar hali ham mavjud bo'ladi.

Birinchi variantni afzal ko'rmoqchiman, chunki siz turli mashqlarni va fragmentlardan olingan barcha ma'lumotlarni dastur sinfida tartibsizlik qilishni xohlamaysiz. Umid qilamanki :)

2
qo'shib qo'ydi

Siz EventBus ni chiqarmoqchimisiz?

Men sizning savolingiz juda keng bo'lsa, u eng yaxshi yondashuv ekanligiga amin emasman, ammo bu faqat 5 ta parcha bilan salqin bo'ladi.

Umid qilamanki yordam beradi

1
qo'shib qo'ydi

Har qanday imkoniyatni tanlashdan oldin, foydalanuvchi sizning ma'lumotlaringiz yo'qolmagani uchun boshqa ilova (lar) ga o'tishi yoki ochishi mumkinligini yodda tuting.

Siz onSaveInstanceState dan foydalanishingiz mumkin, ammo bu sizni qanday himoya qilishni qiyinlashtiradi (siz Androidda yangi deb aytganingiz kabi). Siz singleton bilan birga borishingiz mumkin

  • Database - Use when you want to store maintain multiple records but you have to create a database getter/setter or use any ORM like RushOrm etc.
  • SharefPreference(preferably) - If you want to use single values.

Ikkala holatda ham bitta singlet obyekti yaratiladi va uning qismlarini sizning xususiyatlaringizga kirasiz.

0
qo'shib qo'ydi

Menimcha, MainActivity'da ViewPager mavjud va FragmentOne ko'rinishdagi chaqiruvchi ichidagi qismlardan biri bo'ladi. Bu erda MainActivity ushbu adapterni yangilash uchun FragmentOne bilan bog'lanadi. Umid aniq.

MainActivity-da ushbu interfeysni qo'shing:

public interface Updateable {
    public void update();
}

Ushbu interfeysni yangilanib turadigan qismga kiritib, kodni update usulidagi adapterga bildirish uchun kodni yozing:

public class FragmentOne extends Fragment implements MainActivity.Updateable {
    ...
    @Override
    public void update() {
       //YOUR CODE TO UPDATE HERE, FOR EXAMPLE, HERE I'M UPDATING THE ADAPTER
        if ( adapter != null ) {
            adapter.notifyDataSetChanged();
        } else {
            Log.d("LOG_TAG", "null");
        }
    }
    ...
}

Fragman birinchi yuklanganda MainActivity-dan update usulini chaqiring. Buni quyidagi kabi PagerAdapter getItemPosition usulidan olib tashlashingiz mumkin:

@Override
public int getItemPosition(Object object) {    
    if ( object != null && object instanceof FragmentOne ) {
        FragmentOne f = (FragmentOne) object;

        f.update();
    }
    return super.getItemPosition(object);
}

Nihoyat, viewPager adapterining notifyDataSetChanged() ni chaqirishingiz kerak. Bu sizning viewpager adapterini getItemPosition usulini chaqirishga majbur qiladi.

mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
        int previousState;
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

        }

        @Override
        public void onPageSelected(int position) {

        }

        @Override
        public void onPageScrollStateChanged(int state) {

            if (previousState == ViewPager.SCROLL_STATE_SETTLING && state == ViewPager.SCROLL_STATE_IDLE) {

                if ( viewPagerAdapter.getItem(viewpager.getCurrentItem()) instanceof Pictures ) {
                    Log.d("LOG_TAG", "New Position=" + viewpager.getCurrentItem());

                    viewPagerAdapter.notifyDataSetChanged();
                }

            }
            previousState = state;
        }
    });
0
qo'shib qo'ydi
Ishingiz uchun tashakkur, lekin afsuski, bu mening talablarga javob bermaydi. Menda bitta faoliyat va bir parcha bor, faoliyat ichidagi parcha ko'rish pageri bor va ko'rib chiqish uchun har bir sahifada o'z qismlari bor. O'ylaymanki, men uni yanada aniq va oson saqlab turadigan singleton bilan borishim kerak.
qo'shib qo'ydi muallif saber, manba
Faoliyat va parchadan foydalangan yondashuv vaziyatingiz bilan birgalikda ishlatilishi mumkin (ko'rish peyzaji va Fragment ko'rinishida pager orqali). Biroq, agar u mos keladigan bo'lsa, unday emas
qo'shib qo'ydi muallif Valentino S., manba

Ob'ektlaringizni uyg'un holga keltirish va keyinchalik boshqa qismlarga paketni ishlatish. bundle.putParcelable (obj) parcelable juda samarali va tez.

u sizni rag'batlantirish kerak

http://www.developerphil.com/parcelable-vs-serializable/

0
qo'shib qo'ydi