从 Fragment 启动一个 Activity

3

我在网站上搜索了类似于我的问题,但是没有一个能够回答我的问题。

看一下这张图片:

enter image description here

所以很明显我想通过从CrimeListFragment发送一个带有extraintent来启动CrimeActivity

我读的关于android编程的书籍作者说:

从片段开始一个活动几乎与从另一个活动开始一个活动一样。  你调用 Fragment.startActivity(Intent) 方法,该方法在幕后调用相应的 Activity 方法

CrimeListFragment.java:

public void onListItemClick(ListView l, View v, int position, long id) {
   // Get the Crime from the adapter
   Crime c = ((CrimeAdapter)getListAdapter()).getItem(position);

   // Start CrimeActivity
   Intent i = new Intent(getActivity(), CrimeActivity.class);
   i.putExtra(CrimeFragment.EXTRA_CRIME_ID, c.getId());
   startActivity(i);
}

现在的第二部分是检索 intent 及其 extra,关于这一点作者说:

一个片段可以通过两种方式访问其活动中的数据:一种简单、直接的方式和一种复杂、灵活的方式。首先,您将尝试使用快捷方式。然后,您将实现涉及片段参数的复杂而灵活的解决方案。

我的问题是关于第一种方式,也就是快捷方式。

在快捷方式中,CrimeFragment 将简单地使用 getActivity() 方法直接访问 CrimeActivity 的 intent。返回到 CrimeFragment 并添加 extra 的键。然后,在 onCreate(Bundle) 中,从 CrimeActivity 的 intent 中检索 extra,并使用它来获取 Crime。

CrimeFragment.java :

public class CrimeFragment extends Fragment {
  public static final String EXTRA_CRIME_ID =
    "com.bignerdranch.android.criminalintent.crime_id";
  private Crime mCrime;
  ...
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mCrime = new Crime();
    UUID crimeId = (UUID)getActivity().getIntent()
      .getSerializableExtra(EXTRA_CRIME_ID);

    mCrime = CrimeLab.get(getActivity()).getCrime(crimeId);
}

直接检索的缺点

使片段访问属于托管活动的意图可确保代码简单易懂。 但是,这会导致你失去了片段的封装性。CrimeFragment不再是可重用的构建块, 因为它预期总是由一个其Intent定义了名为 EXTRA_CRIME_ID 的额外信息的活动托管。

这可能是CrimeFragment的合理期望,但这意味着作为当前编写方式, CrimeFragment 无法与任何活动一起使用。

我的问题和问题在于最后一句话,为什么这个Fragment(CrimeFragment)不能只与任何Activity一起使用?


使用Fragment中的getActivity()方法启动新的Activity。 - jitain sharma
2个回答

3
作者解释了这个问题。 在CrimeFragmentonCreate()方法中,它通过getActivity()获取其托管的活动(hosting activity),然后尝试从启动该ActivityIntent中获取UUID。
这意味着包含CrimeFragment的任何活动都必须遵守此规则,即其意图(intent)应该有一个由名称EXTRA_CRIME_ID定义的额外内容(extra)。如果该活动不符合要求,您将在CrimeFragmentonCreate()中看到一个异常被抛出。
尝试在自己创建的新活动中使用此片段来查看会发生什么。

但是正如您所看到的,我们在CrimeFragment中定义了EXTRA_CRIME_ID,而不是在其包含的Activity中。 - hamid_c
1
EXTRA_CRIME_ID这个字符串本身是在片段中定义的,但实际上你正在尝试从具有该名称的ActivityIntent中获取额外信息。真正的问题在于:如果包含CrimeFragmentActivity没有带有该额外信息的Intent,则会导致崩溃。如果您将EXTRA_CRIME_ID替换为“JOHN SMITH”,则仍然需要ActivityIntent具有相同的额外信息。 - takecare
所以你的意思是实际上有两个传递的“intent”,第一个是从CrimeListFragmentCrimActivity,第二个是从CrimeActivityCrimeFragment??? - hamid_c
1
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - takecare

0

在onActivityCreated()中进行检索

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    if (savedInstanceState != null) {
        ....
    }
    else {
        UUID crimeId = (UUID)getActivity().getIntent().getSerializableExtra(EXTRA_CRIME_ID);
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接