如何在 MainActivity 中获取 ViewPager 创建的片段元素? [英] How to get elements of fragments created by ViewPager in MainActivity?
问题描述
我有几个用 ViewPager
组织的片段.我在 MainActivity 的 onCreate
方法中向 ViewPager
添加了一个 addOnPageChangeListener
,它给出了所选片段的位置.
即使我通过声明一个 setOffscreenPageLimit
来防止片段自我破坏,我仍然没有弄清楚如何从 MainActivity 访问片段,因为简单地使用 findViewById
返回null 对象异常.
我想做什么:
我想访问片段的元素,例如布局和滚动视图,在 ViewPager
的 OnPageListener
中:
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {@覆盖公共无效 onPageSelected(int i) {如果(我== 0){//对第一个片段做一些事情.} else if(i == 1) {//对第二个片段做一些事情.}}}
ViewPager
使用一个 FragmentPagerAdapter
:
public class SectionsPagerAdapter extends FragmentPagerAdapter {公共 SectionsPagerAdapter(FragmentManager fm) {超级(调频);}@覆盖公共片段 getItem(int position) {开关(位置){案例0:返回 Fragment1.newInstance(position);情况1:返回 Fragment2.newInstance(position);案例2:返回 Fragment3.newInstance(position);案例3:返回 Fragment4.newInstance(position);默认:抛出新的 IllegalArgumentException();}}@覆盖公共 int getCount() {返回 4;}}
是这样添加的:
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());mViewPager.setAdapter(mSectionsPagerAdapter);
~
或者我应该改变我的方法吗?
如果这种设计无法实现访问片段,那么有效的替代途径是什么?
我尝试在自定义 ViewPager
中实现 ViewPager.onPageChangeListener
,但它似乎不是一个好的选择.
我可以处理它们各自片段中的元素,但这是一个繁琐且难以维护的过程,因此我寻找一种同时处理它们的方法.
我知道以前有人问过类似的问题,但我没有找到解决方案.
不幸的是,唯一的安全"方法是检查FragmentPagerAdapter
的源代码,并查看添加的片段是什么 tag
- 因为 findFragmentByTag
是从 FragmentManager 获取片段的唯一安全方法.
当然,我们需要希望这个实现细节在支持库版本之间不会改变,但它实际上已经多年没有改变:)
<小时>无论如何,所以 FragmentPagerAdapter 说:
<块引用>//我们已经有这个片段了吗?String name = makeFragmentName(container.getId(), itemId);片段片段 = mFragmentManager.findFragmentByTag(name);
那么什么是name
?
private static String makeFragmentName(int viewId, long id) {返回 "android:switcher:" + viewId + ":" + id;}
什么是viewId
,什么是id
?
ViewId 是 container.getId()
,其中 container
是 ViewPager
本身.
id
是:final long itemId = getItemId(position);
默认是 return position;
.
因此您可以按如下方式找到 Fragment:
Fragment fragment = fragmentManager.findFragmentByTag("android:switcher:" + viewPager.getId() + ":" + fragmentPosition);//如果片段为空,则它尚未被 ViewPager 创建
<小时>
注意:
值得注意的是,您不应该依赖 getItem(int position) {
返回 与您传入的相同片段实例,因为这会导致您这个问题.(这个问题做对了,getItem()
方法必须总是返回一个新的 Fragment 实例.)
I have several fragments which are organized with a ViewPager
. I add an addOnPageChangeListener
to the ViewPager
in MainActivity's onCreate
method which gives the position of the selected fragment.
Even though I prevent the fragments from destroying themselves with stating a setOffscreenPageLimit
, I still haven't figured out how to access fragments from MainActivity, as simply using findViewById
returns null object exceptions.
What I want to do:
I would like to access elements of fragments, e.g. layouts and scrollviews, in the OnPageListener
of the 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.
}
}
}
The ViewPager
uses a 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;
}
}
Which is added like this:
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
mViewPager.setAdapter(mSectionsPagerAdapter);
~
Or should I change my approach?
If accessing fragments cannot be achieved with this design, what could be an effective alternative route?
I've tried to implement ViewPager.onPageChangeListener
in the custom ViewPager
, but it didn't seem to be a good option.
I could deal with the elements in their respective fragments, but this is a tedious process and hard to maintain, which I the reason I look for a way to handle them simultaneously.
I know similar questions have been asked before, but I didn't find a solution in them.
Unfortunately the only "safe" way to do it is to check the source code of FragmentPagerAdapter
, and see what tag
is the fragment is added with - because findFragmentByTag
is the only safe way to get a Fragment from a FragmentManager.
Of course, we need to hope that this implementation detail doesn't change between support library versions, but it actually hasn't changed in years :)
Anyways, so FragmentPagerAdapter says:
// Do we already have this fragment? String name = makeFragmentName(container.getId(), itemId); Fragment fragment = mFragmentManager.findFragmentByTag(name);
So what is name
?
private static String makeFragmentName(int viewId, long id) { return "android:switcher:" + viewId + ":" + id; }
What is viewId
and what is id
?
ViewId is container.getId()
, where container
is the ViewPager
itself.
id
is: final long itemId = getItemId(position);
which by default is return position;
.
So you can find the Fragment as follows:
Fragment fragment = fragmentManager.findFragmentByTag("android:switcher:" + viewPager.getId() + ":" + fragmentPosition);
// if fragment is null, it was not created yet by ViewPager
NOTE:
It is worth noting that you should NOT rely on getItem(int position) {
to return the same fragment instance as you passed in, because that will lead you to this problem. (This question does it correctly, the getItem()
method must always return a new Fragment instance.)
这篇关于如何在 MainActivity 中获取 ViewPager 创建的片段元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!