2012年11月2日金曜日

Communicating with the Activity

Although a Fragment is implemented as an object that's independent from an Activity and can be used inside multiple activities, a given instance of a fragment is directly tied to the activity that contains it.

Specifically, the fragment can access the Activity instance with getActivity() and easily perform tasks such as find a view in the activity layout:

View listView = getActivity().findViewById(R.id.list);

Likewise, your activity can call methods in the fragment by acquiring a reference to the Fragment fromFragmentManager, using findFragmentById() or findFragmentByTag(). For example:

ExampleFragment fragment = (ExampleFragment) getFragmentManager().findFragmentById(R.id.example_fragment);

Creating event callbacks to the activity

In some cases, you might need a fragment to share events with the activity. A good way to do that is to define a callback interface inside the fragment and require that the host activity implement it. When the activity receives a callback through the interface, it can share the information with other fragments in the layout as necessary.

For example, if a news application has two fragments in an activity—one to show a list of articles (fragment A) and another to display an article (fragment B)—then fragment A must tell the activity when a list item is selected so that it can tell fragment B to display the article. In this case, the OnArticleSelectedListener interface is declared inside fragment A:

public static class FragmentA extends ListFragment {      ...      // Container Activity must implement this interface      public interface OnArticleSelectedListener {          public void onArticleSelected(Uri articleUri);      }      ...  }

Then the activity that hosts the fragment implements the OnArticleSelectedListener interface and overrides onArticleSelected() to notify fragment B of the event from fragment A. To ensure that the host activity implements this interface, fragment A's onAttach() callback method (which the system calls when adding the fragment to the activity) instantiates an instance of OnArticleSelectedListener by casting theActivity that is passed into onAttach():

public static class FragmentA extends ListFragment {      OnArticleSelectedListener mListener;      ...      @Override      public void onAttach(Activity activity) {          super.onAttach(activity);          try {              mListener = (OnArticleSelectedListener) activity;          } catch (ClassCastException e) {              throw new ClassCastException(activity.toString() + " must implement OnArticleSelectedListener");          }      }      ...  }

If the activity has not implemented the interface, then the fragment throws a ClassCastException. On success, the mListener member holds a reference to activity's implementation ofOnArticleSelectedListener, so that fragment A can share events with the activity by calling methods defined by the OnArticleSelectedListener interface. For example, if fragment A is an extension ofListFragment, each time the user clicks a list item, the system calls onListItemClick() in the fragment, which then calls onArticleSelected() to share the event with the activity:

public static class FragmentA extends ListFragment {      OnArticleSelectedListener mListener;      ...      @Override      public void onListItemClick(ListView l, View v, int position, long id) {          // Append the clicked item's row ID with the content provider Uri          Uri noteUri = ContentUris.withAppendedId(ArticleColumns.CONTENT_URI, id);          // Send the event and Uri to the host activity          mListener.onArticleSelected(noteUri);      }      ...  }

The id parameter passed to onListItemClick() is the row ID of the clicked item, which the activity (or other fragment) uses to fetch the article from the application's ContentProvider.

More information about using a content provider is available in the Content Providers document.

0 件のコメント:

コメントを投稿