ViewPager və fraqmentlər - parçanın vəziyyətini saxlamanın düzgün yolu nədir?

Bu parçacıqlar istifadəçi interfeysi mantığını bəzi modullara ayırmaq üçün çox gözəl görünür. Lakin ViewPager ilə ViewPager onun həyat dövrü hələ mənim üçün dumanlı qalır. Buna görə də, Guru düşüncələri çox vacibdir!

Change

Aşağıdakı lal seçimə baxın: -)

Ölçək

Əsas fəaliyyətin parçaları olan ViewPager . Bu fraqmentlər digər (subtitr) tədbirlər üçün bir qədər fərqli məntiq tətbiq edə bilər, buna görə də bu fraqmentlər hərəkət içərisində geri çağrış interfeysi ilə doldurulur. Və ilk başladığınız zaman hər şey yaxşı işləyir, amma ...

Problem

Fəaliyyət aktivləşdirildikdə (məsələn, istiqaməti dəyişdirərkən), həmçinin ViewPager parçaları. Kod (aşağıda tapa bilərsiniz) deyir ki, bir hərəkətin ViewPager zaman, yeni bir ViewPager fraqment adapterini fraqmentlər (bəlkə də bu problemdir) kimi yaratmağa ViewPager , amma FragmentManager artıq bir yerdə bu fraqmentləri saxlanılır (harada?) və onlar üçün qalan mexanizmi çalışır. Beləliklə, istirahət mexanizmi "köhnə" parçanıAttach, onCreateView və s. Mənim geri çağırış interfeysi ilə Fəaliyyət metodunu istifadə edərək məlumatları başlamağa çağırın. Amma bu üsul, yeni yaradılmış fraqmenti göstərir ki, yaradılmışdır.

Problem

Yəqin ki, yanlış şablonlardan istifadə edirəm, amma Android 3 Pro kitabında belə bir şey yoxdur. Budur, mənə bir və ya iki xit verin və bunu necə düzgün etdiyini göstərin. Çox sağ olun!

kodu

Əsas fəaliyyət

 public class DashboardActivity extends BasePagerActivity implements OnMessageListActionListener { private MessagesFragment mMessagesFragment; @Override protected void onCreate(Bundle savedInstanceState) { Logger.d("Dash onCreate"); super.onCreate(savedInstanceState); setContentView(R.layout.viewpager_container); new DefaultToolbar(this); // create fragments to use mMessagesFragment = new MessagesFragment(); mStreamsFragment = new StreamsFragment(); // set titles and fragments for view pager Map<String, Fragment> screens = new LinkedHashMap<String, Fragment>(); screens.put(getApplicationContext().getString(R.string.dashboard_title_dumb), new DumbFragment()); screens.put(getApplicationContext().getString(R.string.dashboard_title_messages), mMessagesFragment); // instantiate view pager via adapter mPager = (ViewPager) findViewById(R.id.viewpager_pager); mPagerAdapter = new BasePagerAdapter(screens, getSupportFragmentManager()); mPager.setAdapter(mPagerAdapter); // set title indicator TitlePageIndicator indicator = (TitlePageIndicator) findViewById(R.id.viewpager_titles); indicator.setViewPager(mPager, 1); }  @Override public void onMessageInitialisation() { Logger.d("Dash onMessageInitialisation"); if (mMessagesFragment != null) mMessagesFragment.loadLastMessages(); } @Override public void onMessageSelected(Message selectedMessage) { Intent intent = new Intent(this, StreamActivity.class); intent.putExtra(Message.class.getName(), selectedMessage); startActivity(intent); } 

BasePagerActivity köməkçi

 public class BasePagerActivity extends FragmentActivity { BasePagerAdapter mPagerAdapter; ViewPager mPager; } 

Adapter

 public class BasePagerAdapter extends FragmentPagerAdapter implements TitleProvider { private Map<String, Fragment> mScreens; public BasePagerAdapter(Map<String, Fragment> screenMap, FragmentManager fm) { super(fm); this.mScreens = screenMap; } @Override public Fragment getItem(int position) { return mScreens.values().toArray(new Fragment[mScreens.size()])[position]; } @Override public int getCount() { return mScreens.size(); } @Override public String getTitle(int position) { return mScreens.keySet().toArray(new String[mScreens.size()])[position]; } // hack. we don't want to destroy our fragments and re-initiate them after @Override public void destroyItem(View container, int position, Object object) { // TODO Auto-generated method stub } } 

Fragment

 public class MessagesFragment extends ListFragment { private boolean mIsLastMessages; private List<Message> mMessagesList; private MessageArrayAdapter mAdapter; private LoadMessagesTask mLoadMessagesTask; private OnMessageListActionListener mListener; // define callback interface public interface OnMessageListActionListener { public void onMessageInitialisation(); public void onMessageSelected(Message selectedMessage); } @Override public void onAttach(Activity activity) { super.onAttach(activity); // setting callback mListener = (OnMessageListActionListener) activity; mIsLastMessages = activity instanceof DashboardActivity; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { inflater.inflate(R.layout.fragment_listview, container); mProgressView = inflater.inflate(R.layout.listrow_progress, null); mEmptyView = inflater.inflate(R.layout.fragment_nodata, null); return super.onCreateView(inflater, container, savedInstanceState); } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); // instantiate loading task mLoadMessagesTask = new LoadMessagesTask(); // instantiate list of messages mMessagesList = new ArrayList<Message>(); mAdapter = new MessageArrayAdapter(getActivity(), mMessagesList); setListAdapter(mAdapter); } @Override public void onResume() { mListener.onMessageInitialisation(); super.onResume(); } public void onListItemClick(ListView l, View v, int position, long id) { Message selectedMessage = (Message) getListAdapter().getItem(position); mListener.onMessageSelected(selectedMessage); super.onListItemClick(l, v, position, id); }  } 

Həll

Səssiz bir həll, Fragment istifadə edərək, SaveInstanceState (host fəaliyyəti) içərisində olan parçaları saxlamaq və getFragment vasitəsilə onCreate içərisində almaq. Amma hər şeyin yanlış işləməsi lazım olduğuna dair bir qəribə hissi var ... Aşağıdakı kodu gör:

  @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); getSupportFragmentManager() .putFragment(outState, MessagesFragment.class.getName(), mMessagesFragment); } protected void onCreate(Bundle savedInstanceState) { Logger.d("Dash onCreate"); super.onCreate(savedInstanceState); ... // create fragments to use if (savedInstanceState != null) { mMessagesFragment = (MessagesFragment) getSupportFragmentManager().getFragment( savedInstanceState, MessagesFragment.class.getName()); StreamsFragment.class.getName()); } if (mMessagesFragment == null) mMessagesFragment = new MessagesFragment(); ... } 
462
31 окт. Aleksey Malevaniy 31 oktyabr tarixinə təyin edilib 2011-10-31 12:18 '11 'da 12:18' də 2011-10-31 12:18
@ 10 cavab

FragmentPagerAdapter bir parça əlavə edərkən parçanın yerləşdiriləcəyi xüsusi mövqeyə əsasən xüsusi bir etiket istifadə edir. FragmentPagerAdapter.getItem(int position) yalnız bu mövqedə forma olmadığı üçün çağırılır. Dönüşündən sonra Android bu xüsusi mövqeyə görə artıq yaradıb / saxladığını görür və buna görə yeni bir FragmentManager.findFragmentByTag() yaratmaq əvəzinə FragmentManager.findFragmentByTag() istifadə edərək sadəcə ona qoşulmağa çalışır. Bütün bunlar FragmentPagerAdapter istifadə edərək buraxılır və buna görə də getItem(int) metodunun içərisində bir parçası başlatma kodu var.

FragmentPagerAdapter istifadə etməmiş olsaq da, Activity.onCreate(Bundle) hər dəfə yeni bir parça yaratmaq məsləhət görülmür. Gördüyünüz kimi FragmentManager-a bir parça əlavə olunduqda, rotasiya sonrası sizin üçün yenidən yaradılacaq və yenidən əlavə etmək lazım deyil. Bu fraqmentlərlə işləyərkən səhvən ümumi bir səbəbdir.

Fragmanlarla işləyərkən adi yanaşma aşağıdakılardır:

 protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ... CustomFragment fragment; if (savedInstanceState != null) { fragment = (CustomFragment) getSupportFragmentManager().findFragmentByTag("customtag"); } else { fragment = new CustomFragment(); getSupportFragmentManager().beginTransaction().add(R.id.container, fragment, "customtag").commit(); } ... } 

FragmentPagerAdapter istifadə edərkən FragmentPagerAdapter biz parçalanma idarəetmə adapter ilə imtina və yuxarıda addımlar yerinə yetirmək lazım deyil. Varsayılan olaraq, bu, FragmentStatePagerAdapter istifadə etmədiyiniz müddətdə onları məhv etməyəcəkdir. Bu ViewPager.setOffscreenPageLimit (int) tərəfindən idarə olunur. Buna görə, adapter xaricindəki fraqmentlər üçün metodların birbaşa dəqiqləşdirilməsi təmin edilə bilməz, çünki onlar hətta sağ ola bilməzlər.

Uzun bir tarixi qısaltmaq üçün, putFragment dən istifadə etmək üçün qərarınızı daha sonra əldə edə bilmək üçün belə dəli deyil və hər halda fragmanları istifadə etmək adi şəkildə fərqlənmir (yuxarıda bax). Bağlantını başqa bir yerə almaq çətindir, çünki fragman adapter tərəfindən əlavə olunur və şəxsən deyil. Yalnız əmin olun offscreenPageLimit həmişə düzgün parçaları yükləmək üçün kifayət qədər yüksəkdir, çünki onun varlığına güvənirəm. Bu ViewPager'in tənbəl yüklənməsini atır, ancaq tətbiqiniz üçün istədiyiniz nədir.

Başqa bir yanaşma FragmentPageAdapter.instantiateItem(View, int) yenidən təyin etmək və onu geri qaytarmadan əvvəl super-zəngdən geri gələn hissəyə istinad etməyi nəzərdə tutur (zaten varsa, fragmanı axtarmaq üçün məntiqə malikdir).

Daha tam şəkil üçün qaynaq FragmentPagerAdapter (qısa) və ViewPager (uzun) baxın.

429
10 марта '12 в 16:00 2012-03-10 16:00 Cavab antonit tərəfindən 10 mart 2012- ci il saat 4: 00-da verilir. 2012-03-10 16:00

antonyt gözəl cavab verən və daha sonra üzərində işləyə biləcəyiniz FragmentPageAdapter.instantiateItem(View, int) istinadlar yaratmaq üçün yaradılan Fragments saxlanmasını xatırladan bir həll təklifi təqdim etmək istəyirəm. Bu da FragmentStatePagerAdapter ilə işləməlidir; ətraflı məlumat üçün qeydləri baxın.


Fragments tərəfindən qaytarılan Fragments a keçidlərin necə alındığına dair bir sadə misaldır. Bu, Fragments a təyin edilmiş daxili tags əsaslanır. Açar instantiateItem()getItem() əlaqələri getItem() .

 public class SomeActivity extends Activity { private FragmentA m1stFragment; private FragmentB m2ndFragment; // other code in your Activity... private class CustomPagerAdapter extends FragmentPagerAdapter { // other code in your custom FragmentPagerAdapter... public CustomPagerAdapter(FragmentManager fm) { super(fm); } @Override public Fragment getItem(int position) { // Do NOT try to save references to the Fragments in getItem(), // because getItem() is not always called. If the Fragment // was already created then it will be retrieved from the FragmentManger // and not here (ie getItem() won't be called again). switch (position) { case 0: return new FragmentA(); case 1: return new FragmentB(); default: // This should never happen. Always account for each position above return null; } } // Here we can finally safely save a reference to the created // Fragment, no matter where it came from (either getItem() or // FragmentManger). Simply save the returned Fragment from // super.instantiateItem() into an appropriate reference depending // on the ViewPager position. @Override public Object instantiateItem(ViewGroup container, int position) { Fragment createdFragment = (Fragment) super.instantiateItem(container, position); // save the appropriate reference depending on position switch (position) { case 0: m1stFragment = (FragmentA) createdFragment; break; case 1: m2ndFragment = (FragmentB) createdFragment; break; } return createdFragment; } } public void someMethod() { // do work on the referenced Fragments, but first check if they // even exist yet, otherwise you'll get an NPE. if (m1stFragment != null) { // m1stFragment.doWork(); } if (m2ndFragment != null) { // m2ndFragment.doSomeWorkToo(); } } } 

ya da Fragments sinif dəyişənləri / istinadları yerinə tags işləməyi üstün Fragments , ayrıca FragmentPagerAdapter tərəfindən təyin olunan tags də eyni şəkildə FragmentPagerAdapter . QEYD: FragmentStatePagerAdapter üçün tətbiq edilmir, çünki Fragments yaratmaq tags təyin etmir.

 @Override public Object instantiateItem(ViewGroup container, int position) { Fragment createdFragment = (Fragment) super.instantiateItem(container, position); // get the tags set by FragmentPagerAdapter switch (position) { case 0: String firstTag = createdFragment.getTag(); break; case 1: String secondTag = createdFragment.getTag(); break; } // ... save the tags somewhere so you can reference them later return createdFragment; } 
border=0

Bu metodun FragmentPagerAdapter tərəfindən təyin edilmiş daxili tag təqlidinə əməl etmədiyini və bunları almaq üçün müvafiq API-lərdən istifadə etdiyini unutmayın. Beləliklə, tag SupportLibrary in gələcək versiyalarında dəyişirsə belə, hələ də təhlükəsiz olursunuz.


Unutmayın ki, fəaliyyətinizin dizaynına əsasən, işləməyə çalışdığınız Fragments ola bilər və ya olmaya bilər, buna görə də bağlantılarınızı istifadə etməzdən öncə null yoxlamaqla nəzərə alınmalıdır.

Əlavə olaraq, bir FragmentStatePagerAdapter ilə FragmentStatePagerAdapter , onlardan bir çoxuna sahib ola biləcəyi üçün, Fragments sərt bağlantılar qoymaq istəmirsinizsə və sabit linklər onları lazımsız olaraq yadda saxlayacaq. Bunun əvəzinə, WeakReference standart olanlar əvəzinə WeakReference dəyişənlərində saxlaya bilərsiniz. Burada:

 WeakReference<Fragment> m1stFragment = new WeakReference<Fragment>(createdFragment); // ...and access them like so Fragment firstFragment = m1stFragment.get(); if (firstFragment != null) { // reference hasn't been cleared yet; do work... } 
34
26 марта '15 в 23:22 2015-03-26 23:22 Cavab Tony Chan tərəfindən martın 26-da saat 23: 22-də verilir. 2015-03-26 23:22

Sualınız üçün başqa bir nisbətən sadə bir həll tapdım.

FragmentPagerAdapter mənbə kodundan görə bilərsiniz ki FragmentPagerAdapter tərəfindən idarə olunan parçalar FragmentPagerAdapter ilə saxlanılır:

 String tag="android:switcher:" + viewId + ":" + index; 

viewId container.getId() , container sizin ViewPager . index parçanın mövqeyidir. Buna görə, obyektin identifikatorunu xarici vəziyyətdə saxlaya bilərsiniz:

 @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putInt("viewpagerid" , mViewPager.getId() ); } @Override protected void onCreate(Bundle savedInstanceState) { setContentView(R.layout.activity_main); if (savedInstanceState != null) viewpagerid=savedInstanceState.getInt("viewpagerid", -1 ); MyFragmentPagerAdapter titleAdapter = new MyFragmentPagerAdapter (getSupportFragmentManager() , this); mViewPager = (ViewPager) findViewById(R.id.pager); if (viewpagerid != -1 ){ mViewPager.setId(viewpagerid); }else{ viewpagerid=mViewPager.getId(); } mViewPager.setAdapter(titleAdapter); 

Bu snippet ilə ünsiyyət qurmaq istəyirsinizsə, FragmentManager dən, məsələn:

 getSupportFragmentManager().findFragmentByTag("android:switcher:" + viewpagerid + ":0") 
16
03 марта '13 в 7:17 2013-03-03 07:17 cavab user2110066 mart 03 '13 da 07:17 ' də verilir 2013-03-03 07:17

Bəlkə də bir az fərqli bir vəziyyətdə alternativ bir həll təklif etməyi təklif edirəm, çünki cavabların çoxu məni bu mövzuya gətirib çıxardı.

Mənim işim dinamik olaraq pages yaratmaq / əlavə et və onları ViewPager-ə daşıyıram, ancaq OnCreate-i yenidən çağırır, çünki mən açıldıqda (onConfigurationChange) yeni bir səhifə alıram. Ancaq dönüşümdən əvvəl yaradılan bütün səhifələrə bir keçid saxlamaq istərdim.

Problem - yaradılan hər bir fragman üçün unikal identifikatorlara malik deyiləm, belə ki istinad üçün yeganə yol rotasiya / konfiqurasiya dəyişikliyindən sonra bərpa ediləcək dizidəki istinadları xilas etdi.

Çözüm - Əsas məqsədi Fəaliyyətin (fraqmentləri göstərən) həmçinin mövcud fraqmentlərə istinadlar bir sıra idarə etməsi idi, çünki bu fəaliyyət OnSaveInstanceState-də Bundles istifadə edə bilər

 public class MainActivity extends FragmentActivity 

Beləliklə, bu əməliyyatın bir hissəsi olaraq, açıq səhifələrin izlənməsi üçün xüsusi iştirakçı elan edirəm.

 private List<Fragment> retainedPages = new ArrayList<Fragment>(); 

Bu yeniləmə hər dəfə SaveInstanceState çağırılır və onCreate-ə bərpa olunur

 @Override protected void onSaveInstanceState(Bundle outState) { retainedPages = _adapter.exportList(); outState.putSerializable("retainedPages", (Serializable) retainedPages); super.onSaveInstanceState(outState); } 

... belə qənaət etsək, bərpa edilə bilər ...

 @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if (savedInstanceState != null) { retainedPages = (List<Fragment>) savedInstanceState.getSerializable("retainedPages"); } _mViewPager = (CustomViewPager) findViewById(R.id.viewPager); _adapter = new ViewPagerAdapter(getApplicationContext(), getSupportFragmentManager()); if (retainedPages.size() > 0) { _adapter.importList(retainedPages); } _mViewPager.setAdapter(_adapter); _mViewPager.setCurrentItem(_adapter.getCount()-1); } 

Bunlar əsas fəaliyyətdə zəruri dəyişikliklər idi, buna görə də FragmentPagerAdapter-də işləmək üçün üzvlərə və üsullara ehtiyacım vardı

 public class ViewPagerAdapter extends FragmentPagerAdapter 

eyni tikinti (yuxarıda göstərildiyi kimi MainActivity)

 private List<Fragment> _pages = new ArrayList<Fragment>(); 

və bu sinxronizasiya (yuxarıda göstərildiyi kimiSaveInstanceState) xüsusilə üsullarla dəstəklənir

 public List<Fragment> exportList() { return _pages; } public void importList(List<Fragment> savedPages) { _pages = savedPages; } 

Nəhayət, parçaların sinifində

 public class CustomFragment extends Fragment 

Bütün bunlar işlədildikdə iki dəyişiklik var idi: birincisi

 public class CustomFragment extends Fragment implements Serializable 

sonra parçaları məhv edilməməsi üçün Yaratma'ya əlavə edin

 setRetainInstance(true); 

Mən hələ də parçaları və Android həyat dövrü ətrafında sarma prosesində olduğum üçün, bu metoddakı azalma / səmərəsizlik ola biləcək bir şərt ola bilər. Amma mənim üçün işləyir və ümid edirəm ki, mənim kimi digər insanlar üçün faydalı olacaqdır.

15
04 дек. Cavab Frank Yin tərəfindən verilir 04 Dek 2012-12-04 07:12 '12 saat 07:12 'da 2012-12-04 07:12

Mənim PageAdapter çox kobud, amma işləyir: saxlanan məlumatlardan dinamik şəkildə yaradılan fraqmentlər super.onSaveInstanceState() PageAdapter əvvəl bütün fragmanı PageAdapter dən silmək və fəaliyyət yaratdıqda onları yenidən yaratmaq:

 @Override protected void onSaveInstanceState(Bundle outState) { outState.putInt("viewpagerpos", mViewPager.getCurrentItem() ); mSectionsPagerAdapter.removeAllfragments(); super.onSaveInstanceState(outState); } 

onDestroy() onları silə onDestroy() , əks halda bu istisna olacaqsınız:

java.> Bu hərəkətin üzərindənSaveInstanceState-dən sonra çıxış edə bilmir

Səhifə adapterindəki kod:

 public void removeAllfragments() { if ( mFragmentList != null ) { for ( Fragment fragment : mFragmentList ) { mFm.beginTransaction().remove(fragment).commit(); } mFragmentList.clear(); notifyDataSetChanged(); } } 

Yalnız cari səhifəni onCreate()onCreate() sonra onCreate() bərpa edirəm.

 if (savedInstanceState != null) mViewPager.setCurrentItem( savedInstanceState.getInt("viewpagerpos", 0 ) ); 
8
17 апр. cavab Sir John 17 apr tərəfindən verilir . 2013-04-17 12:51 '13 at 12:51 2013-04-17 12:51

Bu BasePagerAdapter nədir? ViewPager tərəfindən dəstəklənməyən (ilk) və ya onların vəziyyətinə (sonuncu) və yenidən saxlanılmaq ViewPager ehtiyac ViewPager ya yenidən ViewPager əsasən standart çağrı cihazı adapterlərindən - FragmentPagerAdapter və ya FragmentStatePagerAdapter ViewPager zəruri hallarda yaradılmalıdır.

ViewPager istifadə nümunəsi kodu burada tapa bilərsiniz.

Çağırış görünüşündəki fraqmentlərin fəaliyyət halları ilə idarə olunması bir az daha mürəkkəbdir, çünki strukturdakı FragmentManager dövlətin saxlanılması və çağırıcının hazırladığı hər hansı bir aktiv fragmanı bərpa etməyi təmin edir. Bütün bunlar həqiqətən adapterin başlanğıc zamanı hər hansı bərpa olunan parçaya qoşulmasını təmin etməlidir. Bunu necə həyata keçirmək üçün FragmentPagerAdapterFragmentStatePagerAdapter kodunu bilərsiniz.

4
04 нояб. Cavab hackbod verilir 04 Noyabr. 2011-11-04 10:07 '11 at 10:07 'da 2011-11-04 10:07

Kimsə FragmentStatePagerAdapter ilə problemləri varsa, onlar parçaların vəziyyətini bərpa etmirlər ... Yəni .... FragmentStatePagerAdapter tərəfindən dövlətin onları əvəzinə yaradılır ...

ViewPager.setAdapeter(fragmentStatePagerAdapter) əvvəl ViewPager.setAdapeter(fragmentStatePagerAdapter)

ViewPager.setOffscreenPageLimit() funksiyasını çağırırıqda ... ViewPager dərhal bağdaştırıcısına baxacaq və onun parçalarını əldə etməyə çalışır. Bu, ViewPager'in saxlanılan InstanceState-dən fragmanları bərpa etmək qabiliyyətinə malik olmasına (bundan əvvəl onlar yeni olduğundan SavedInstanceState-dən reinitialized olan yeni fraqmentlər yaratmaq) malik ola bilər.

2
05 февр. Cavab verilir dell116 05 fevral. 2017-02-05 04:22 '17 də 4:22 2017-02-05 04:22 'də

Mən bu sadə və zərif həlli ilə tanış oldum. O, fraqmentləri yaratmaq üçün fəaliyyətin məsuliyyət daşıyır və adapter sadəcə onlara xidmət edir.

Bu adapter kodu (burada mFragments Fəaliyyət tərəfindən dəstəklənən fraqmentlərin siyahısı olduğu istisna olmaqla) burada qəribə bir şey yoxdur.

 class MyFragmentPagerAdapter extends FragmentStatePagerAdapter { public MyFragmentPagerAdapter(FragmentManager fm) { super(fm); } @Override public Fragment getItem(int position) { return mFragments.get(position); } @Override public int getCount() { return mFragments.size(); } @Override public int getItemPosition(Object object) { return POSITION_NONE; } @Override public CharSequence getPageTitle(int position) { TabFragment fragment = (TabFragment)mFragments.get(position); return fragment.getTitle(); } } 

Bu mövzu içərisindəki bütün problem "köhnə" fraqmentlərə keçid olur, buna görə də bu kodu Create-də Aktivliyində istifadə edirəm.

  if (savedInstanceState!=null) { if (getSupportFragmentManager().getFragments()!=null) { for (Fragment fragment : getSupportFragmentManager().getFragments()) { mFragments.add(fragment); } } } 

Əlbəttə ki, əgər lazım olsa, bu kodu daha da özelleştirebilirsiniz, məsələn, fragmanların müəyyən bir sinif nümunələri olduğuna əmin olmaq.

0
19 июля '16 в 18:53 2016-07-19 18:53 Cavab Merlevede 19 iyul '16, 18:53 2016-07-19 18:53 'də verilir

Orientasiya dəyişdikdən sonra fraqmentləri əldə etmək üçün, .getTag () istifadə etməlisiniz.

  getSupportFragmentManager().findFragmentByTag("android:switcher:" + viewPagerId + ":" + positionOfItemInViewPager) 

Bir az daha çox emal etmək üçün, mənim pageAdapter üçün öz ArrayList yazıb viewPagerId və FragmentClass istifadə edərək, hər hansı bir mövqedə bölməni almaq üçün:

 public class MyPageAdapter extends FragmentPagerAdapter implements Serializable { private final String logTAG = MyPageAdapter.class.getName() + "."; private ArrayList<MyPageBuilder> fragmentPages; public MyPageAdapter(FragmentManager fm, ArrayList<MyPageBuilder> fragments) { super(fm); fragmentPages = fragments; } @Override public Fragment getItem(int position) { return this.fragmentPages.get(position).getFragment(); } @Override public CharSequence getPageTitle(int position) { return this.fragmentPages.get(position).getPageTitle(); } @Override public int getCount() { return this.fragmentPages.size(); } public int getItemPosition(Object object) { //benötigt, damit bei notifyDataSetChanged alle Fragemnts refrehsed werden Log.d(logTAG, object.getClass().getName()); return POSITION_NONE; } public Fragment getFragment(int position) { return getItem(position); } public String getTag(int position, int viewPagerId) { //getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.shares_detail_activity_viewpager + ":" + myViewPager.getCurrentItem()) return "android:switcher:" + viewPagerId + ":" + position; } public MyPageBuilder getPageBuilder(String pageTitle, int icon, int selectedIcon, Fragment frag) { return new MyPageBuilder(pageTitle, icon, selectedIcon, frag); } public static class MyPageBuilder { private Fragment fragment; public Fragment getFragment() { return fragment; } public void setFragment(Fragment fragment) { this.fragment = fragment; } private String pageTitle; public String getPageTitle() { return pageTitle; } public void setPageTitle(String pageTitle) { this.pageTitle = pageTitle; } private int icon; public int getIconUnselected() { return icon; } public void setIconUnselected(int iconUnselected) { this.icon = iconUnselected; } private int iconSelected; public int getIconSelected() { return iconSelected; } public void setIconSelected(int iconSelected) { this.iconSelected = iconSelected; } public MyPageBuilder(String pageTitle, int icon, int selectedIcon, Fragment frag) { this.pageTitle = pageTitle; this.icon = icon; this.iconSelected = selectedIcon; this.fragment = frag; } } public static class MyPageArrayList extends ArrayList<MyPageBuilder> { private final String logTAG = MyPageArrayList.class.getName() + "."; public MyPageBuilder get(Class cls) { // Fragment über FragmentClass holen for (MyPageBuilder item : this) { if (item.fragment.getClass().getName().equalsIgnoreCase(cls.getName())) { return super.get(indexOf(item)); } } return null; } public String getTag(int viewPagerId, Class cls) { // Tag des Fragment unabhängig vom State zB nach bei Orientation change for (MyPageBuilder item : this) { if (item.fragment.getClass().getName().equalsIgnoreCase(cls.getName())) { return "android:switcher:" + viewPagerId + ":" + indexOf(item); } } return null; } }