将复杂对象列表从活动传递到片段

时间:2014-08-27 11:55:56

标签: android android-fragments parcelable

我有一个带有SearchFragment和SearchResultFragment的MainActivity。

当用户按下搜索按钮时,我使用SearchParameters作为参数从SearchFragment回调到MainActivity。

在MainActivity I上显示LoadFragment并加载结果 当我收到结果时,我想将结果对象列表传递给SearchResultFragment。

最好的方法是什么?

我知道你通常会这样做,如果它只是一个结果:

public static SearchResultFragment newInstance(SearchResult result) {
    SearchResultFragment f = new SearchResultFragment();
    Bundle args = new Bundle();
    args.putInt("result", result);  // Make result parceable
    f.setArguments(args);
    return f;
} 

但是如何使用对象列表执行此操作?

我能想到的另一个解决方案是在片段的onAttach方法中获取对MainActivity的引用,然后在MainActivity上调用方法getResults()。

最好的方法是什么?

2 个答案:

答案 0 :(得分:6)

在大多数情况下,您可以避免传递复杂对象,但如果不能,则只需使用getter和setter。尝试这样的事情:

public static SearchResultFragment newInstance(SearchResult result) {
    SearchResultFragment f = new SearchResultFragment();
    f.setResult(result);        
    return f;
}

但是尝试避免这种情况,使用Bundle传递数据是一个更好的解决方案。尽可能使用Parcelable

答案 1 :(得分:4)

注意:我的回答是假设您尝试将数据聚合传递给片段一次。如果您尝试使用新信息(新结果)定期更新现有片段,那么最好在Fragment中使用专用方法将结果保存为参数并更新UI。

这两种方法都可以接受,特别是取决于您希望为搜索结果提供的范围,但我赞成将结果作为"静态"参数(意思是不是从Activity动态获取的)主要是由于以下原因:

  • Fragment旨在作为可重复使用的UI片段,这意味着Android框架允许您将相同的Fragment集成到另一个Activity中;在这种情况下,集成(更灵活)比附加的Activity必须实现给定的getter更容易,Fragment实际上可以由另一个实体构建(例如"结果) fetcher)并附加到Activity而没有它知道结果(简化潜在的重构)
  • 保留
  • Fragment个参数,这意味着相同的Fragment初始化代码(从参数中获取结果)也将在活动重启后处理Fragment自动重新实现(例如屏幕旋转) ) 例如 ;否则你还需要自己处理结果实体的保存和恢复

另一方面,将结果放在Bundle作为Fragment参数会稍微慢一点,因为在收到新结果后,您创建了一个额外的结构(Bundle),然后您parcel(序列化)和unparcel(反序列化)。 Activity重启后会更快,因为在这种情况下你不必包裹它(它已经完成)。我只是为了完整性而提到它,但是,除非你的结果非常大(这是一个有效的用例,但可能更适合分页加载呢?),你不会注意到,反正不应该在意。

将多个结果传递给Fragment(假设单个结果为int):

final Bundle args = new Bundle();
args.putIntArray(SearchResultFragment.ARG_NAME_RESULTS, results);  // results being an int[]
fragment.setArguments(args);

如果Bundle#putIntegerArrayList(String, ArrayList<Integer>)的类型为results,请使用ArrayList<Integer>