Как получить элементы фрагментов, созданных ViewPager, в MainActivity?
У меня есть несколько фрагментов, которые организованы с помощью ViewPager
. Я добавляю addOnPageChangeListener
к ViewPager
методу onCreate
в MainActivity, который указывает положение выбранного фрагмента.
Несмотря на то, что я предотвращаю самоуничтожение фрагментов, указывая a setOffscreenPageLimit
, я все еще не понял, как получить доступ к фрагментам из MainActivity, поскольку простое использование findViewById
возвращает исключения нулевого объекта.
Что я хочу сделать:
Я хотел бы получить доступ к элементам фрагментов, например layouts и scrollviews, в OnPageListener
из ViewPager
:
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageSelected(int i) {
if(i == 0) {
// Do something with the first fragment.
} else if(i == 1) {
// Do something with the second fragment.
}
}
}
В ViewPager
используетсяFragmentPagerAdapter
:
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return Fragment1.newInstance(position);
case 1:
return Fragment2.newInstance(position);
case 2:
return Fragment3.newInstance(position);
case 3:
return Fragment4.newInstance(position);
default:
throw new IllegalArgumentException();
}
}
@Override
public int getCount() {
return 4;
}
}
Который добавляется следующим образом:
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
mViewPager.setAdapter(mSectionsPagerAdapter);
~
Или мне следует изменить свой подход?
Если доступ к фрагментам не может быть достигнут с помощью этого дизайна, какой может быть эффективный альтернативный маршрут?
Я пытался реализовать ViewPager.onPageChangeListener
в пользовательском ViewPager
режиме, но это не показалось мне хорошим вариантом.
Я мог бы работать с элементами в соответствующих им фрагментах, но это утомительный процесс, который сложно поддерживать, поэтому я ищу способ обрабатывать их одновременно.
Я знаю, что подобные вопросы задавались раньше, но я не нашел в них решения.
Переведено автоматически
Ответ 1
К сожалению, единственный "безопасный" способ сделать это - проверить исходный код FragmentPagerAdapter
и посмотреть, с чем tag
добавлен фрагмент, потому что findFragmentByTag
это единственный безопасный способ получить фрагмент из FragmentManager.
Конечно, нам нужно надеяться, что эта деталь реализации не меняется в зависимости от версий библиотеки поддержки, но на самом деле она не менялась годами :)
В любом случае, так говорит FragmentPagerAdapter:
// Do we already have this fragment?
String name = makeFragmentName(container.getId(), itemId);
Fragment fragment = mFragmentManager.findFragmentByTag(name);
Так что же такое name
?
private static String makeFragmentName(int viewId, long id) {
return "android:switcher:" + viewId + ":" + id;
}
Что такое viewId
и что такое id
?
ViewID - это container.getId()
, где container
находится сам ViewPager
файл.
id
это: final long itemId = getItemId(position);
который по умолчанию является return position;
.
Итак, вы можете найти фрагмент следующим образом:
Fragment fragment = fragmentManager.findFragmentByTag("android:switcher:" + viewPager.getId() + ":" + fragmentPosition);
// if fragment is null, it was not created yet by ViewPager
ПРИМЕЧАНИЕ:
Стоит отметить, что вам НЕ следует полагаться на то, что getItem(int position) {
вернет тот же экземпляр фрагмента, который вы передали в, потому что это приведет вас к этой проблеме. (Этот вопрос отвечает правильно, getItem()
метод всегда должен возвращать новый экземпляр фрагмента.)