Ссылка на фрагменты внутри ViewPager

У меня проблема с ссылкой на мои фрагменты внутри ViewPager. Я хотел бы сделать это, потому что из своей активности я хотел бы обновить фрагмент в указанной позиции (например, отображаемый в данный момент фрагмент).

В настоящее время у меня есть что-то вроде этого:

public static class MyPagerAdapter extends FragmentPagerAdapter { private static final String TAG = "MyPagerAdapter"; private static HashMap<Integer, EventListFragment> mPageReferenceMap = new HashMap<Integer, EventListFragment>(); public MyPagerAdapter(FragmentManager fm) { super(fm); } @Override public int getCount() { return NUM_ITEMS; } @Override public Fragment getItem(int position) { Log.i(TAG, "getItem: "+position); int dateOffset = position-1; EventListFragment mFragment = EventListFragment.newInstance(dateOffset); mPageReferenceMap.put(position, mFragment); return mFragment; } @Override public void destroyItem(ViewGroup container, int position, Object object) { Log.i(TAG, "destroyItem: "+position); mPageReferenceMap.remove(position); super.destroyItem(container, position, object); } public EventListFragment getFragment(int key) { Log.i(TAG, "Size of pager references: "+mPageReferenceMap.size()); return mPageReferenceMap.get(key); } } 

Проблема в том, что destroyItem() чаще, чем getItem() , поэтому я остаюсь с нулевыми ссылками. Если я не использую destroyItem() чтобы очистить ссылки на уничтоженные фрагменты … ну, я destroyItem() на фрагменты, которые не существуют.

Есть ли хороший способ ссылки на фрагменты, созданные с помощью EventListFragment mFragment = EventListFragment.newInstance(dateOffset); ? Или что мне делать, чтобы обновить фрагмент внутри ViewPager из моей активности (из меню опций, чтобы быть точным)?

Мне удалось это решить. Хитрость заключалась в том, чтобы сделать список ссылок внутри Activity, а не PagerAdapter. Это происходит так:

 List<WeakReference<EventListFragment>> fragList = new ArrayList<WeakReference<EventListFragment>>(); @Override public void onAttachFragment (Fragment fragment) { Log.i(TAG, "onAttachFragment: "+fragment); if(fragment.getClass()==EventListFragment.class){ fragList.add(new WeakReference<EventListFragment>((EventListFragment)fragment)); } } public EventListFragment getFragmentByPosition(int position) { EventListFragment ret = null; for(WeakReference<EventListFragment> ref : fragList) { EventListFragment f = ref.get(); if(f != null) { if(f.getPosition()==position){ ret = f; } } else { //delete from list fragList.remove(f); } } return ret; } 

Конечно, ваш фрагмент должен реализовать функцию getPosition() , но мне все равно нужно было что-то подобное, поэтому это не проблема.

Спасибо Алекс Локвуд за предложение с WeakReference !

Две вещи:

  1. Добавьте следующую строку в метод onCreate вашей деятельности (или где бы вы не инициализировали ViewPager):

     mPager.setOffscreenPageLimit(NUM_ITEMS-1); 

    Это позволит сохранить дополнительные экранные страницы в памяти (т. Е. Предотвратить их уничтожение), даже если они в настоящее время не отображаются на экране.

  2. Вы можете подумать о том, чтобы реализовать свой HashMap чтобы он удерживал WeakReference<Fragment> s вместо самих Fragment . Обратите внимание, что это потребует от вас изменить метод getFragment следующим образом:

     WeakReference<Fragment> weakRef = mPageReferenceMap.get(position); return (weakRef != null) ? weakRef.get() : null; 

    Это не имеет никакого отношения к вашей проблеме … это просто что-то, что я заметил, и подумал, что я приму вашему вниманию. Сохранение WeakReferences с вашим Fragment позволит вам использовать способность сборщика мусора определять доступность для вас, поэтому вам не нужно делать это самостоятельно.