gpt4 book ai didi

android - 使用 FragmentPagerAdapter 时如何获取现有 fragment

转载 作者:IT老高 更新时间:2023-10-28 13:05:26 25 4
gpt4 key购买 nike

我的 fragment 通过 Activity 相互通信时遇到问题,它使用 FragmentPagerAdapter 作为实现选项卡和所有细节管理的辅助类将 ViewPager 与关联的 TabHost 连接起来。我已经实现了 FragmentPagerAdapter,就像 Android 示例项目 Support4Demos 提供的一样。

主要问题是当我既没有 ID 也没有标签时,如何从 FragmentManager 获取特定 fragment ? FragmentPagerAdapter 正在创建 fragment 并自动生成 Id 和标签。

最佳答案

问题总结

注意:在这个答案中,我将引用 FragmentPagerAdapter及其源代码。但通用解决方案也应适用于 FragmentStatePagerAdapter .

如果您正在阅读本文,您可能已经知道 FragmentPagerAdapter/FragmentStatePagerAdapter旨在创建 Fragments为您的ViewPager ,但是在 Activity 重新创建时(无论是设备旋转还是系统杀死您的应用程序以重新获得内存)这些 Fragments不会再次创建,而是它们的 instances retrieved from the FragmentManager .现在说你的Activity需要引用这些 Fragments对它们进行工作。您没有 idtag为这些创建 Fragments因为FragmentPagerAdapter set them internally .所以问题是如何在没有这些信息的情况下获得对它们的引用......

当前解决方案的问题:依赖内部代码

我在这个问题和类似问题上看到的许多解决方案都依赖于对现有 Fragment 的引用。调用 FragmentManager.findFragmentByTag()并模仿internally created tag: "android:switcher:" + viewId + ":" + id .这样做的问题是您依赖于内部源代码,众所周知,不能保证永远保持不变。 Google 的 Android 工程师可以轻松决定更改 tag结构会破坏您的代码,使您无法找到对现有 Fragments 的引用.

不依赖内部的替代解决方案tag

这里有一个简单的例子来说明如何获得对 Fragments 的引用。由 FragmentPagerAdapter 返回不依赖于内部 tags设置在 Fragments .关键是覆盖 instantiateItem() 并将引用保存在其中而不是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 (i.e. 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();
}
}
}

如果您更喜欢使用 tags而不是类成员变量/对 Fragments 的引用你也可以抢tagsFragmentPagerAdapter 设置以相同的方式:注意:这不适用于 FragmentStatePagerAdapter因为它没有设置 tags在创建其 Fragments 时.

@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;
}

请注意,此方法不依赖于模仿内部 tagFragmentPagerAdapter 设置而是使用适当的 API 来检索它们。这样即使 tag SupportLibrary future 版本的变化你还是安全的。


不要忘记这取决于您的 Activity 的设计, Fragments您正在尝试的工作可能存在也可能不存在,因此您必须通过执行 null 来解决此问题在使用您的引用资料之前进行检查。

另外,如果您正在使用 FragmentStatePagerAdapter ,那么您不想保留对 Fragments 的硬引用因为你可能有很多,硬引用会不必要地将它们保存在内存中。而是保存 Fragment WeakReference 中的引用资料变量而不是标准变量。像这样:

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...
}

关于android - 使用 FragmentPagerAdapter 时如何获取现有 fragment ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14035090/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com