| page.title=Communicating with Other Fragments |
| parent.title=Building a Dynamic UI with Fragments |
| parent.link=index.html |
| |
| trainingnavtop=true |
| previous.title=Building a Flexible UI |
| previous.link=fragment-ui.html |
| |
| @jd:body |
| |
| <div id="tb-wrapper"> |
| <div id="tb"> |
| <h2>This lesson teaches you to</h2> |
| <ol> |
| <li><a href="#DefineInterface">Define an Interface</a></li> |
| <li><a href="#Implement">Implement the Interface</a></li> |
| <li><a href="#Deliver">Deliver a Message to a Fragment</a></li> |
| </ol> |
| |
| <h2>You should also read</h2> |
| <ul> |
| <li><a href="{@docRoot}guide/components/fragments.html">Fragments</a></li> |
| </ul> |
| |
| <h2>Try it out</h2> |
| |
| <div class="download-box"> |
| <a href="http://developer.android.com/shareables/training/FragmentBasics.zip" |
| class="button">Download the sample</a> |
| <p class="filename">FragmentBasics.zip</p> |
| </div> |
| |
| </div> |
| </div> |
| |
| <p>In order to reuse the Fragment UI components, you should build each as a completely |
| self-contained, modular component that defines its own layout and behavior. Once you |
| have defined these reusable Fragments, you can associate them with an Activity and |
| connect them with the application logic to realize the overall composite UI.</p> |
| |
| <p>Often you will want one Fragment to communicate with another, for example to change |
| the content based on a user event. All Fragment-to-Fragment communication is done |
| through the associated Activity. Two Fragments should never communicate directly.</p> |
| |
| |
| <h2 id="DefineInterface">Define an Interface</h2> |
| |
| <p>To allow a Fragment to communicate up to its Activity, you can define an interface |
| in the Fragment class and implement it within the Activity. The Fragment captures |
| the interface implementation during its onAttach() lifecycle method and can then call |
| the Interface methods in order to communicate with the Activity.</p> |
| |
| <p>Here is an example of Fragment to Activity communication:</p> |
| |
| <pre> |
| public class HeadlinesFragment extends ListFragment { |
| OnHeadlineSelectedListener mCallback; |
| |
| // Container Activity must implement this interface |
| public interface OnHeadlineSelectedListener { |
| public void onArticleSelected(int position); |
| } |
| |
| @Override |
| public void onAttach(Activity activity) { |
| super.onAttach(activity); |
| |
| // This makes sure that the container activity has implemented |
| // the callback interface. If not, it throws an exception |
| try { |
| mCallback = (OnHeadlineSelectedListener) activity; |
| } catch (ClassCastException e) { |
| throw new ClassCastException(activity.toString() |
| + " must implement OnHeadlineSelectedListener"); |
| } |
| } |
| |
| ... |
| } |
| </pre> |
| |
| <p>Now the fragment can deliver messages to the activity by calling the {@code |
| onArticleSelected()} method (or other methods in the interface) using the {@code mCallback} |
| instance of the {@code OnHeadlineSelectedListener} interface.</p> |
| |
| <p>For example, the following method in the fragment is called when the user clicks on a list |
| item. The fragment uses the callback interface to deliver the event to the parent activity.</p> |
| |
| <pre> |
| @Override |
| public void onListItemClick(ListView l, View v, int position, long id) { |
| // Send the event to the host activity |
| mCallback.onArticleSelected(position); |
| } |
| </pre> |
| |
| |
| |
| <h2 id="Implement">Implement the Interface</h2> |
| |
| <p>In order to receive event callbacks from the fragment, the activity that hosts it must |
| implement the interface defined in the fragment class.</p> |
| |
| <p>For example, the following activity implements the interface from the above example.</p> |
| |
| <pre> |
| 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 |
| } |
| } |
| </pre> |
| |
| |
| |
| <h2 id="Deliver">Deliver a Message to a Fragment</h2> |
| |
| <p>The host activity can deliver messages to a fragment by capturing the {@link |
| android.support.v4.app.Fragment} instance |
| with {@link android.support.v4.app.FragmentManager#findFragmentById findFragmentById()}, then |
| directly call the fragment's public methods.</p> |
| |
| <p>For instance, imagine that the activity shown above may contain another fragment that's used to |
| display the item specified by the data returned in the above callback method. In this case, |
| the activity can pass the information received in the callback method to the other fragment that |
| will display the item:</p> |
| |
| <pre> |
| 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(); |
| } |
| } |
| } |
| </pre> |
| |
| |
| |
| |
| |
| |
| |
| |
| |