【问题标题】:getSupportLoaderManager() use same ids in different fragments?getSupportLoaderManager() 在不同的片段中使用相同的 id?
【发布时间】:2012-10-24 09:41:14
【问题描述】:

我正在一个带有多个 ListFragment 的 FragmentActivity 中创建一个 viewPager。为了填充不同的列表视图,我得到了 LoaderManager 并在加载器中初始化。我希望每个片段都有一个唯一的 LoaderManager,但是片段没有 getSupportLoaderManager() 方法,所以我需要调用父片段活动:

getActivity().getSupportLoaderManager()

这种方法的问题是我在不同片段中的加载器 ID 相互冲突。当您在一个片段中已经有多个加载程序 id 时,它会变得有点麻烦。那么有没有办法为每个片段获取一个唯一的 LoaderManager,而不是调用父片段?我基本上希望能够在多个片段上使用相同的 id。

谢谢

【问题讨论】:

  • 为什么需要同一个ID?你不能给他们一个不同的ID吗?是的,片段和活动之间存在耦合,以不同的形式,这可能是最偷偷摸摸的一个。
  • 这就是我现在正在做的事情。但是我为每个片段使用了许多 id,它会变得非常混乱。因此,我经常使我的应用程序崩溃。我只想从每个片段的 0 开始。并不是真正的必需品,但它会使我的代码更清晰,更易于阅读

标签: android android-listfragment android-loadermanager android-cursor android-support-library


【解决方案1】:

是的,您可以使用:android.support.v4.app.Fragment.getLoaderManager() 为每个 Fragment 获得一个唯一的,这意味着您可以从零开始您的 id。

【讨论】:

  • 返回 LoaderManager 而不是 SupportLoaderManager
  • @States 它返回android.support.v4.app.LoaderManager,因此 support LoaderManager(它真的不存在)。来自android.app.Fragment 的普通片段返回android.app.FragmentManager不是支持实现)。所以用这个方法是省事的。
  • 查看@Snicolas 的答案。从 API22 开始,虽然加载器管理器可能不同(可以通过 enableDebugLogging 看到),但重叠时的 id 会导致各种问题。我无法找到重叠 id 的方法,我只是简单地转向使用非重叠 id(每个片段的 id 范围)。
  • 虽然一个应该使用android.support.v4.app.Fragment.getLoaderManager()作为片段内的列表视图,这将返回与getActivity().getSupportLoaderManager()相同的LoaderManager。见stackoverflow.com/questions/31088404/…
【解决方案2】:

评论太长了,但我会在你的问题的范围内继续我们的讨论。

您应该反其道而行之:接受 ID 是 Activity 本地的事实,而不是片段的本地 ID。

是的,片段和活动之间的耦合很差。大多数情况下,来自片段的回调将片段链接到一个活动(即使使用接口也不是那么干净),并且为了将参数从活动传递给片段:您必须使用静态工厂方法来构建片段并设置其参数通过 setArgs。

您的问题完全是关于这样的耦合问题:活动的每个片段中的加载程序 ID 不应与所有其他片段使用的 ID 重叠。这也是一个耦合约束,因为我们对位于活动级别的片段有一个约束。 你说得对,Android 可以通过在 Fragment 中引入本地加载器来解决 Fragment 级别的问题。

尽管如此,可能有一些优雅的方法可以解决这个问题并保留一个相对的解耦方案。例如,您可以创建一个 ID 工厂,为片段内的加载程序生成“好的”ID 并防止重叠(id++ 将是完美的):

public interface IdFactory {
   public int createId();
}

然后在每个片段中,当你需要一个加载器时:

this.newLoaderId = idFactory.createId();

工厂可以使用以下三种策略之一由所有片段共享:

  • 单身人士。每个片段将通过

    访问IdFactory

    IdFactory idFactory = DefaultIdFactory.getInstance();

  • 创建实现 IdFactory 的类的单个实例,使该类的实例成为应用程序类中的数据字段,并为其提供 getter。每个片段都可以使用

    访问它

    IdFactory idFactory = ((MyApplication)getActivity().getApplicationContext() ).getIdFactory();

  • 在活动级别创建您的工厂。活动可以实现 IdFactory 接口,或者它们可以提供一个内部类来实现它。然后每个片段将使用以下方法访问工厂:

    IdFactory idFactory = getActivity().getIdFactory(); //要么 IdFactory idFactory = (IdFactory)getActivity();

第三个选项更好,因为它会根据您的确切需求并遵循活动生命周期,允许您的工厂被垃圾收集。

还有其他选项,例如使用 RoboGuice 或 Dagger 或任何其他依赖注入框架,但标准较低。

【讨论】:

  • 非常感谢您的回答,非常清楚。我决定听从你的建议。我还是 java 新手,所以我有一个问题:为什么我不能只调用 getActivity().createId() 而不必将对象转换为 IdFactory 接口?接口转换的目的是什么?再次感谢
  • getActivity 将返回一个 Activity 并且此类没有 createIdFactory 方法。您需要您的 Activity 来实现 IdFactory 接口并将您的 Activity 从片段内投射到其中以便能够访问该方法,否则编译器将不允许您调用未在 Acitivty 类型本身中定义的方法。如果答案适合您的需要,请采纳。
  • 另一个答案(由 fr1550n 提供)是更好的方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-21
  • 1970-01-01
  • 2020-11-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多