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 @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 @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