2014-2-14
本篇文章翻译自Android官方的培训教程,我也是初学者,觉得官方的Training才是最好的学习材料,所以边学边翻译,有翻译不好的地方,请大家指正。
如果我们在开发过程中为了重用Fragment这个UI组件,那么我们应该把Fragment设计成是“自包含”、“模块化”组件,这种组件定义自己的布局和行为。一旦我们成功定义了这样的可重用的Fragment,我们就可以将他们与Activity进行关联,然后与整个Application进行整体的UI组装。
我们经常需要一个Fragment与另一个Fragment进行通信,比如点击一个Fragment,另外一个Fragment进行响应。所有的Fragment与Fragment之间的通信,都是由与他们绑定之间的Activity来完成,2个Fragment之间是不能进行直接通信的。
下面具体介绍Fragment直接的通信的步骤。
第一步:定义接口
为了首先实现Fragment与它所绑定的Activity直接进行通信,我们需要在Fragment的类中定义一个接口,并且在它所绑定的Activity的类中实现这个接口。Fragment通过在onAttach()这个生命周期回调函数中去捕获接口的实现,然后调用这个接口中的方法与Activity进行通信。
下面是一个例子:
public class HeadlinesFragment extends ListFragment {
OnHeadlineSelectedListener mCallback; // 容器Activity必须实现这个接口
public interface OnHeadlineSelectedListener {
public void onArticleSelected(int position);
} @Override
public void onAttach(Activity activity) {
super.onAttach(activity); // 这个确保容器Activity已经实现了这个回调接口,如果没有实现,会抛出异常
try {
mCallback = (OnHeadlineSelectedListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnHeadlineSelectedListener");
}
} ...
}
现在Fragment可以通过接口OnHeadlineSelectedListener
的实例mCallback
instance调用接口中的onArticleSelected()
方法(或者接口中定义的其他的方法)发送messages到Activity。
例如,当用户点击一个list中的item,下面的Fragment中的方法会被调用。Fragment通过回调接口来发送事件到上层的Activity。
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
// Send the event to the host activity
mCallback.onArticleSelected(position);
}
第二步:实现接口 为了接收来自Fragment的回调事件,包含这个Fragment的Activity必须实现Fragment中所定义的接口。
例如,下面的代码就是上面接口的实现。
public static class MainActivity extends Activity
implements HeadlinesFragment.OnHeadlineSelectedListener{
... public void onArticleSelected(int position) {
// The user selected the headline of an article from the HeadlinesFragment
// Do something here to display that article
}
}
第三步:发送消息到Fragment
Activity通过调用findFragmentById()这个方法找到Fragment实例,然后直接调用这个实例的public方法。
比如,假设上述的activity可能包含另一个Fragment,这个Fragment用来显示前一个Fragment中具体item所对应的数据。在这个例子中,activity会将受到的数据,传送给这个Fragment,然后这个Fragment跟去该数据去显示相应的内容。
public static class MainActivity extends Activity
implements HeadlinesFragment.OnHeadlineSelectedListener{
... public void onArticleSelected(int position) {
// The user selected the headline of an article from the HeadlinesFragment
// Do something here to display that article ArticleFragment articleFrag = (ArticleFragment)
getSupportFragmentManager().findFragmentById(R.id.article_fragment); if (articleFrag != null) {
// If article frag is available, we're in two-pane layout... // Call a method in the ArticleFragment to update its content
articleFrag.updateArticleView(position);
} else {
// Otherwise, we're in the one-pane layout and must swap frags... // Create fragment and give it an argument for the selected article
ArticleFragment newFragment = new ArticleFragment();
Bundle args = new Bundle();
args.putInt(ArticleFragment.ARG_POSITION, position);
newFragment.setArguments(args); FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); // Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack so the user can navigate back
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null); // Commit the transaction
transaction.commit();
}
}
}