1page.title=Communicating with Other Fragments
2page.tags=fragments
3helpoutsWidget=true
4
5trainingnavtop=true
6
7@jd:body
8
9<div id="tb-wrapper">
10  <div id="tb">
11    <h2>This lesson teaches you to</h2>
12<ol>
13  <li><a href="#DefineInterface">Define an Interface</a></li>
14  <li><a href="#Implement">Implement the Interface</a></li>
15  <li><a href="#Deliver">Deliver a Message to a Fragment</a></li>
16</ol>
17
18    <h2>You should also read</h2>
19    <ul>
20      <li><a href="{@docRoot}guide/components/fragments.html">Fragments</a></li>
21    </ul>
22
23<h2>Try it out</h2>
24
25<div class="download-box">
26 <a href="http://developer.android.com/shareables/training/FragmentBasics.zip"
27class="button">Download the sample</a>
28 <p class="filename">FragmentBasics.zip</p>
29</div>
30
31  </div>
32</div>
33
34<p>In order to reuse the Fragment UI components, you should build each as a completely
35self-contained, modular component that defines its own layout and behavior.  Once you
36have defined these reusable Fragments, you can associate them with an Activity and
37connect them with the application logic to realize the overall composite UI.</p>
38
39<p>Often you will want one Fragment to communicate with another, for example to change
40the content based on a user event.  All Fragment-to-Fragment communication is done
41through the associated Activity.  Two Fragments should never communicate directly.</p>
42
43
44<h2 id="DefineInterface">Define an Interface</h2>
45
46<p>To allow a Fragment to communicate up to its Activity, you can define an interface
47in the Fragment class and implement it within the Activity.  The Fragment captures
48the interface implementation during its onAttach() lifecycle method and can then call
49the Interface methods in order to communicate with the Activity.</p>
50
51<p>Here is an example of Fragment to Activity communication:</p>
52
53<pre>
54public class HeadlinesFragment extends ListFragment {
55    OnHeadlineSelectedListener mCallback;
56
57    // Container Activity must implement this interface
58    public interface OnHeadlineSelectedListener {
59        public void onArticleSelected(int position);
60    }
61
62    &#64;Override
63    public void onAttach(Activity activity) {
64        super.onAttach(activity);
65
66        // This makes sure that the container activity has implemented
67        // the callback interface. If not, it throws an exception
68        try {
69            mCallback = (OnHeadlineSelectedListener) activity;
70        } catch (ClassCastException e) {
71            throw new ClassCastException(activity.toString()
72                    + " must implement OnHeadlineSelectedListener");
73        }
74    }
75
76    ...
77}
78</pre>
79
80<p>Now the fragment can deliver messages to the activity by calling the {@code
81onArticleSelected()} method (or other methods in the interface) using the {@code mCallback}
82instance of the {@code OnHeadlineSelectedListener} interface.</p>
83
84<p>For example, the following method in the fragment is called when the user clicks on a list
85item. The fragment uses the callback interface to deliver the event to the parent activity.</p>
86
87<pre>
88    &#64;Override
89    public void onListItemClick(ListView l, View v, int position, long id) {
90        // Send the event to the host activity
91        mCallback.onArticleSelected(position);
92    }
93</pre>
94
95
96
97<h2 id="Implement">Implement the Interface</h2>
98
99<p>In order to receive event callbacks from the fragment, the activity that hosts it must
100implement the interface defined in the fragment class.</p>
101
102<p>For example, the following activity implements the interface from the above example.</p>
103
104<pre>
105public static class MainActivity extends Activity
106        implements HeadlinesFragment.OnHeadlineSelectedListener{
107    ...
108
109    public void onArticleSelected(int position) {
110        // The user selected the headline of an article from the HeadlinesFragment
111        // Do something here to display that article
112    }
113}
114</pre>
115
116
117
118<h2 id="Deliver">Deliver a Message to a Fragment</h2>
119
120<p>The host activity can deliver messages to a fragment by capturing the {@link
121android.support.v4.app.Fragment} instance
122with {@link android.support.v4.app.FragmentManager#findFragmentById findFragmentById()}, then
123directly call the fragment's public methods.</p>
124
125<p>For instance, imagine that the activity shown above may contain another fragment that's used to
126display the item specified by the data returned in the above callback method. In this case,
127the activity can pass the information received in the callback method to the other fragment that
128will display the item:</p>
129
130<pre>
131public static class MainActivity extends Activity
132        implements HeadlinesFragment.OnHeadlineSelectedListener{
133    ...
134
135    public void onArticleSelected(int position) {
136        // The user selected the headline of an article from the HeadlinesFragment
137        // Do something here to display that article
138
139        ArticleFragment articleFrag = (ArticleFragment)
140                getSupportFragmentManager().findFragmentById(R.id.article_fragment);
141
142        if (articleFrag != null) {
143            // If article frag is available, we're in two-pane layout...
144
145            // Call a method in the ArticleFragment to update its content
146            articleFrag.updateArticleView(position);
147        } else {
148            // Otherwise, we're in the one-pane layout and must swap frags...
149
150            // Create fragment and give it an argument for the selected article
151            ArticleFragment newFragment = new ArticleFragment();
152            Bundle args = new Bundle();
153            args.putInt(ArticleFragment.ARG_POSITION, position);
154            newFragment.setArguments(args);
155
156            FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
157
158            // Replace whatever is in the fragment_container view with this fragment,
159            // and add the transaction to the back stack so the user can navigate back
160            transaction.replace(R.id.fragment_container, newFragment);
161            transaction.addToBackStack(null);
162
163            // Commit the transaction
164            transaction.commit();
165        }
166    }
167}
168</pre>
169
170
171
172
173
174
175
176
177
178