将对象从活动传递到片段


76

我有一个Activity使用Fragment。我只是想将一个对象从此传递ActivityFragment

我该怎么办?到目前为止,我看过的所有教程都是从资源中检索数据的。

编辑:

让我们更精确一点:

我的活动ListView左侧有一个。当您单击它时,其想法是Fragment在右侧加载一个。

当我输入此内容时Activity,将Category通过给出一个对象Intent。该对象包含其他对象的列表Questions(其中包含字符串的列表)。这些Questions对象显示在ListView上。当我点击从一个项目ListView,我想显示的列表StringFragment(入ListView)。

为此,我setContentView()Activity布局中调用。在此布局中,定义了Fragment要调用的正确类。当我调用this时setContentView()onCreateView()我的会Fragment被调用,但此时getArguments()返回null。

我如何设法在致电之前将其填满onCreateView()?(告诉我,如果我不够清楚)

谢谢

Answers:


132

在中创建一个静态方法Fragment,然后使用获取它getArguments()

例:

public class CommentsFragment extends Fragment {
  private static final String DESCRIBABLE_KEY = "describable_key";
  private Describable mDescribable;

  public static CommentsFragment newInstance(Describable describable) {
    CommentsFragment fragment = new CommentsFragment();
    Bundle bundle = new Bundle();
    bundle.putSerializable(DESCRIBABLE_KEY, describable);
    fragment.setArguments(bundle);

    return fragment;
  }

  @Override
  public View onCreateView(LayoutInflater inflater,
      ViewGroup container, Bundle savedInstanceState) {

    mDescribable = (Describable) getArguments().getSerializable(
        DESCRIBABLE_KEY);

    // The rest of your code
}

之后,您可以通过以下操作来调用它Activity

FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
Fragment fragment = CommentsFragment.newInstance(mDescribable);
ft.replace(R.id.comments_fragment, fragment);
ft.commit();

8
我要传递不能序列化的对象是什么?
Bagusflyer 2014年

1
putParcelable是最好的实践方式
panchicore

9
我想知道为什么不简单地fragment.mDescribable = describable;在newInstance中设置?它有效,但是我在这里缺少什么吗?
拉胡尔·塔库尔

2
@RahulThakur您在m这里缺少前缀的要点。由于Java社区强烈鼓励数据封装的概念,因此应注意,私有字段无需在外部访问。之所以将其作为单例方法的参数进行传递,是因为该字段在该上下文中是强制性的,因此减少了您忘记分配其值的潜在风险。
mr5 '16

16
最佳答案,但是您忘了说Object要实现Serializable的工作(在这种情况下,对象是Describable)。
加布里埃尔·斯塔福卡

12

您应该在片段中创建一个方法,该方法接受要传递给它的对象的类型。在这种情况下,我将其命名为“ setObject”(creative huh?:))然后该方法可以对该对象执行所需的任何操作。

MyFragment fragment;

@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);

        if (getSupportFragmentManager().findFragmentById(android.R.id.content) == null) {
            fragment = new MyFragment();
            getSupportFragmentManager().beginTransaction().add(android.R.id.content, detailsFragment)
                    .commit();
        } else {
           fragment = (MyFragment) getSupportFragmentManager().findFragmentById(
                    android.R.id.content);
        }


        fragment.setObject(yourObject); //create a method like this in your class "MyFragment"
}

请注意,我正在使用支持库,根据您使用的内容,对getSupportFragmentManager()的调用可能只是对您来说就是getFragmentManager()


2
在可能超出您的托管视图的片段上使用此方法时要小心(retainInstance为true)。
珍妮·特尼森

7
这行不通。当您的应用在后台死机,并且用户将其带回前台时,setObject不一定会被调用。
Martin Konecny 2014年

5
在这种情况下,@ MartinKonecny将再次调用onCreate方法(因为将重新创建活动),因此还将调用setObject。如果不是这种情况,请解释您的评论。谢谢。
fklappan

在查看页面调度程序片段的情况下这不起作用。因为对象没有保留在过渡上。
特斯

12

在您的活动课中:

public class BasicActivity extends Activity {

private ComplexObject co;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main_page);

    co=new ComplexObject();
    getIntent().putExtra("complexObject", co);

    FragmentManager fragmentManager = getFragmentManager();
    Fragment1 f1 = new Fragment1();
    fragmentManager.beginTransaction()
            .replace(R.id.frameLayout, f1).commit();

}

注意:您的对象应实现Serializable接口

然后在您的片段中:

public class Fragment1 extends Fragment {

ComplexObject co;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    Intent i = getActivity().getIntent();

    co = (ComplexObject) i.getSerializableExtra("complexObject");

    View view = inflater.inflate(R.layout.test_page, container, false);
    TextView textView = (TextView) view.findViewById(R.id.DENEME);
    textView.setText(co.getName());

    return view;
}
}

4

通过bundle传递参数仅限于某些数据类型。但是您可以通过以下方式将任何数据传输到片段:

在您的片段中创建一个像这样的公共方法

public void passData(Context context, List<LexItem> list, int pos) {
    mContext = context;
    mLexItemList = list;
    mIndex = pos;
}

在实例化片段后,在您的活动中调用passData()和所有需要的数据类型

        WebViewFragment myFragment = new WebViewFragment();
        myFragment.passData(getApplicationContext(), mLexItemList, index);
        FragmentManager fm = getSupportFragmentManager();
        FragmentTransaction ft = fm.beginTransaction();
        ft.add(R.id.my_fragment_container, myFragment);
        ft.addToBackStack(null);
        ft.commit();

备注:我的片段扩展了“ android.support.v4.app.Fragment”,因此我必须使用“ getSupportFragmentManager()”。当然,此原理也适用于扩展“ Fragment”的片段类,但是随后您必须使用“ getFragmentManager()”。


4

从以下示例获取参考。

1.在片段中:为要在片段中找到其对象的类创建一个引用变量。只需为参考变量创建一个setter方法,并在从活动中替换片段之前调用setter。

 MyEmployee myEmp;
 public void setEmployee(MyEmployee myEmp)
 {
     this.myEmp = myEmp;
 }

2.活动中

   //we need to pass object myEmp to fragment myFragment

    MyEmployee myEmp = new MyEmployee();

    MyFragment myFragment = new MyFragment();

    myFragment.setEmployee(myEmp);

    FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
    ft.replace(R.id.main_layout, myFragment);
    ft.commit();

1

要将对象传递给片段,请执行以下操作:

首先将对象存储在Bundle中,不要忘记将可序列化的工具放在类中。

            CategoryRowFragment fragment = new CategoryRowFragment();

            // pass arguments to fragment
            Bundle bundle = new Bundle();

            // event list we want to populate
            bundle.putSerializable("eventsList", eventsList);

            // the description of the row
            bundle.putSerializable("categoryRow", categoryRow);

            fragment.setArguments(bundle);

然后在片段中检索捆绑

       // events that will be populated in this row
        mEventsList = (ArrayList<Event>)getArguments().getSerializable("eventsList");

        // description of events to be populated in this row
        mCategoryRow = (CategoryRow)getArguments().getSerializable("categoryRow");


0

如果数据应在整个应用程序生命周期中生存并在多个片段或活动之间共享,则Model可以考虑使用一个类,这样可以减少序列化开销。

检查此设计示例


0

这个为我工作:

活动中:

User user;
public User getUser(){ return this.user;}

在Fragment的onCreateView方法中:

User user = ((MainActivity)getActivity()).getUser(); 

MainActivity用您的活动名称替换。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.