Android 为片段提供初始数据的正确方法?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10798489/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 05:00:50  来源:igfitidea点击:

Proper way to give initial data to fragments?

androidandroid-fragments

提问by Warpzit

So I've learned that I need an empty constructor in order for my fragments not to crash on reinitialization. My problem is that I use lists of data for my fragments when they are initialized (at least some of them). So what would be a good way to start new fragments with a list of data. Should I in the OnCreate() make a getData method which gets the data from some other source or what would be a proper approach?

所以我了解到我需要一个空的构造函数,以便我的片段不会在重新初始化时崩溃。我的问题是我在片段初始化时使用数据列表(至少其中一些)。那么用数据列表开始新片段的好方法是什么?我应该在 OnCreate() 中创建一个从其他来源获取数据的 getData 方法,或者什么是正确的方法?

Feeding the bundle with data really wouldn't be a very good approach as I have a lot of data.

因为我有很多数据,所以用数据来提供数据包真的不是一个很好的方法。

So let's take a case (I understand it tons better that way).

所以让我们举个例子(我这样理解得更好)。

When a user clicks on a button the fragment is started. What I used to do was creating a new fragment this way:

当用户单击按钮时,片段将启动。我以前做的是通过这种方式创建一个新片段:

    FragmentManager fragmentManager = getSupportFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

    fragmentTransaction.replace(R.id.center_container, new DetailFragment(item));
    fragmentTransaction.addToBackStack(DETAIL_TAG);

    fragmentTransaction.commit();

Then in my fragment:

然后在我的片段中:

public DetailFragment(EventItem item) {
    mItem = item;
    mPlaces = Database.getContainerPlaces(getActivity()).getValidItems();
}

I can't give all the data to a bundle, so that wouldn't work. So what should I do?

我不能把所有的数据都放在一个包里,所以这是行不通的。所以我该怎么做?

A: Should I initialize the fragment with the empty constructor and then from my activity use setters to set the data directly in the fragment? However, won't I be missing data if the user presses home, android close the fragment and the user later returns?

A:我应该使用空构造函数初始化片段,然后从我的活动中使用 setter 直接在片段中设置数据吗?但是,如果用户按下 home 键,android 关闭片段并且用户稍后返回,我会不会丢失数据?

B: Should I initialize the fragment with factory pattern and call setRetainInstance(true), give the fragment a key for identifying the data and then letting the fragment fetch the data needed in onCreateView from some third source?

B:我应该用工厂模式初始化片段并调用 setRetainInstance(true),给片段一个用于识别数据的键,然后让片段从第三方来源获取 onCreateView 中所需的数据?

C: Should I just make an empty constructor and then in onCreate() fetch the data needed for the fragment?

C:我应该创建一个空的构造函数,然后在 onCreate() 中获取片段所需的数据吗?

It should be noted that the app is locked in portrait so the issue is primarily with maintaining the objects when Android closes and the user restarts.

应该注意的是,该应用程序是纵向锁定的,因此问题主要是在 Android 关闭和用户重新启动时维护对象。

回答by CommonsWare

So what would be a good way to start new fragments with a list of data.

那么用数据列表开始新片段的好方法是什么?

Use the factory pattern and the "arguments" Bundle, such as:

使用工厂模式和“参数” Bundle,例如:

package com.commonsware.empublite;

import android.os.Bundle;

public class SimpleContentFragment extends AbstractContentFragment {
  private static final String KEY_FILE="file";

  protected static SimpleContentFragment newInstance(String file) {
    SimpleContentFragment f=new SimpleContentFragment();

    Bundle args=new Bundle();

    args.putString(KEY_FILE, file);
    f.setArguments(args);

    return(f);
  }

  @Override
  String getPage() {
    return(getArguments().getString(KEY_FILE));
  }
}

If you are retaining your fragment instance, you should be able to get away with just using ordinary setters to put stuff in data members. The "arguments" Bundleis retained as part of configuration changes, so for non-retained instances, this is the way to ensure your setup data is retained if the user rotates the screen, etc.

如果您要保留片段实例,您应该能够只使用普通的 setter 将内容放入数据成员中。“参数”Bundle作为配置更改的一部分保留,因此对于非保留实例,这是确保在用户旋转屏幕等时保留设置数据的方法。