我正在编写一个包含父Activity
和多个孩子Fragments
的应用。我试图让Fragment与父Activity进行通信。我知道有几种方法可以做到这一点,包括创建一个接口并在父Activity中实现它。但是,我对这种方法感兴趣:
ParentActivity activity = (ParentActivity) getActivity();
activity.someMethod();
这种方法占用的代码更少,而且复杂度更低。但是,在生产代码中这样做是否安全?或者界面更安全?
答案 0 :(得分:10)
你可以使用它 -
private ParentActivity callback;
@Override
public void onAttach(Activity activity)
{
//callback = (ParentActivity ) activity;
// make sure there is no cast exception
callback = (ParentActivty.class.isAssignableFrom(activity
.getClass())) ? (ParentActivity) activity : null;
super.onAttach(activity);
}
@Override
public void onDetach()
{
callback = null;
super.onDetach();
}
现在当你进行任何方法调用时,请像这样调用它 -
if(callback!=null)
{
callback.someMethod();
}
这种方法很安全。
答案 1 :(得分:5)
这是安全的(即你不会得到ClassCastException
),只要你确保只 ParentActivity
创建/添加你的片段。
这些类现在有效coupled,一般 ,这不是一件好事。
答案 2 :(得分:1)
通过强制转换为特定的Activity类(ParentActivity),您将无法使用不同的活动重用该片段。只要您只使用具有该活动的片段,就可以安全地进行投射。
使用接口允许片段与多个活动一起使用 - 您只需要在使用该片段的活动中实现该接口。
另一种选择是使用事件总线 - 例如GreenRobot's EventBus或Square's Otto
答案 3 :(得分:1)
直接from the Android documentation:
要允许Fragment与其Activity进行通信,您可以在Fragment类中定义接口并在Activity中实现它。 Fragment在其onAttach()生命周期方法中捕获接口实现,然后可以调用Interface方法以与Activity通信。
以下是片段到活动通信的示例:
// HeadlinesFragment.java
public class HeadlinesFragment extends ListFragment {
OnHeadlineSelectedListener mCallback;
public void setOnHeadlineSelectedListener(Activity activity) {
mCallback = activity;
}
// Container Activity must implement this interface
public interface OnHeadlineSelectedListener {
public void onArticleSelected(int position);
}
// ...
}
// MainActivity.java
public static class MainActivity extends Activity
implements HeadlinesFragment.OnHeadlineSelectedListener{
// ...
@Override
public void onAttachFragment(Fragment fragment) {
if (fragment instanceof HeadlinesFragment) {
HeadlinesFragment headlinesFragment = (HeadlinesFragment) fragment;
headlinesFragment.setOnHeadlineSelectedListener(this);
}
}
}
答案 4 :(得分:0)
我猜ParentActivity
来自Activity
。
getActivity()
将为您提供指向父活动的指针。所以,演员阵容没有问题。
做事并不是“Android方式”,但无论如何,谷歌都没有做很多“Android方式”的事情,这个演员阵容肯定会在未来的Android版本中继续运行。
答案 5 :(得分:0)
正如你自己说的,这不是一个好方法,谷歌自己的文档建议使用界面,但如果你选择使用这种方法尝试类似:
Activity mActivity;
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
this.mActivity = activity;
}
以避免类型NullPointerException
错误
if(this.mActivity != null){
this.mActivity.someMethod();
}
答案 6 :(得分:0)
如果你知道片段不会在另一个活动中,那么这是安全的。您也可以使用instanceof
进行检查,以确保它是正确的类型。
有一些可能性,其中getActivity()可能返回null(当片段未附加时),因此检查活动是否为空甚至更好是一个好习惯:myFragment.isAdded()
。否则,在调用activity.someMethod()
时会出现NullPointerException。
所以安全的代码是:
if (isAdded() && getActivity() instanceof ParentActivity){
ParentActivity activity = (ParentActivity) getActivity();
activity.someMethod();
}
当然还有其他一些方法,比如将侦听器传递给片段,或者使用像Guava或Otto这样的共享事件总线,这些方法也有其优点和缺点。最简单的方法是上面描述的方法,如果你仔细使用它(检查null,更正类),它将按预期工作。