利用Fragment创建动态UI 之 Fragment之间的通信

为了可以复用一个fragment,所以在定义fragment的时候,要把它定义为一个完全独立和模块化,它有它自己的layout和行为。当你定义好了这些可复用的fragment,可以把他们和activity相关联,在应用的逻辑基础上把这些fragment相互关联,从而组成一个完整的UI。

很多时候,我们需要fragment直接进行通信,比方说,根据用户的动作交换内容。所有的fragment直接的通信,都是利用与之关联的activity.2个fragment永远不可能直接通信。

定义接口

要允许fragment和它所在的activity通信,你可以在Fragment类里面定义一个接口,然后在activity里面实现这个接口。Fragment会在它的生命周期函数:onAttach()期间捕获这个接口的实现。然后就可以调用这个接口的方法和activity通信了。

下面是一个通信的例子:

 1 public class HeadlinesFragment extends ListFragment {
 2     OnHeadlineSelectedListener mCallback;
 3 
 4     // Container Activity must implement this interface
 5     public interface OnHeadlineSelectedListener {
 6         public void onArticleSelected(int position);
 7     }
 8 
 9     @Override
10     public void onAttach(Activity activity) {
11         super.onAttach(activity);
12         
13         // This makes sure that the container activity has implemented
14         // the callback interface. If not, it throws an exception
15         try {
16             mCallback = (OnHeadlineSelectedListener) activity;
17         } catch (ClassCastException e) {
18             throw new ClassCastException(activity.toString()
19                     + " must implement OnHeadlineSelectedListener");
20         }
21     }
22     
23     ...
24 }
View Code

然后,这个fragment就可以利用OnHeadlineSelectedListener这个接口的实例mCallback,来调用onArticleSelected()(或者是其他接口里面的方法)来给activity发送信息。

比方说,下面的例子就是,当用户点击一个list里面的一项的时候,fragment里面接口函数被调用,利用这个接口里面的函数,给父activity发送消息。

1 @Override
2     public void onListItemClick(ListView l, View v, int position, long id) {
3         // Send the event to the host activity
4         mCallback.onArticleSelected(position);
5     }
View Code

实现接口

为了处理从fragment来的回调函数传来的消息,那么要处理这个回调消息的activity,也就是这个fragment所在的主体activity,必须实现在fragment里面定义的接口。

比方说,下面就是activity对上面那个接口的实现:

1 public static class MainActivity extends Activity
2         implements HeadlinesFragment.OnHeadlineSelectedListener{
3     ...
4     
5     public void onArticleSelected(int position) {
6         // The user selected the headline of an article from the HeadlinesFragment
7         // Do something here to display that article
8     }
9 }
View Code

向Fragment发送消息

主体的activity可以通过使用findFragmentById()来获取Fragment的实例,然后发送消息到这个fragment,可以直接调用fragment的公有方法。

想象一下,显示在最上面的activity可能还包括有另外一个fragment,用来显示从上面的回调函数里里面返回的信息。那这种情况下,activity可以把从上面的回调函数里面接口的信息,传递给要显示这个信息的fragment.

 1 public static class MainActivity extends Activity
 2         implements HeadlinesFragment.OnHeadlineSelectedListener{
 3     ...
 4 
 5     public void onArticleSelected(int position) {
 6         // The user selected the headline of an article from the HeadlinesFragment
 7         // Do something here to display that article
 8 
 9         ArticleFragment articleFrag = (ArticleFragment)
10                 getSupportFragmentManager().findFragmentById(R.id.article_fragment);
11 
12         if (articleFrag != null) {
13             // If article frag is available, we're in two-pane layout...
14 
15             // Call a method in the ArticleFragment to update its content
16             articleFrag.updateArticleView(position);
17         } else {
18             // Otherwise, we're in the one-pane layout and must swap frags...
19 
20             // Create fragment and give it an argument for the selected article
21             ArticleFragment newFragment = new ArticleFragment();
22             Bundle args = new Bundle();
23             args.putInt(ArticleFragment.ARG_POSITION, position);
24             newFragment.setArguments(args);
25         
26             FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
27 
28             // Replace whatever is in the fragment_container view with this fragment,
29             // and add the transaction to the back stack so the user can navigate back
30             transaction.replace(R.id.fragment_container, newFragment);
31             transaction.addToBackStack(null);
32 
33             // Commit the transaction
34             transaction.commit();
35         }
36     }
37 }
View Code
天生我才必有用,千金散去还复来!
原文地址:https://www.cnblogs.com/Jack-Lu/p/3169177.html