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