简体   繁体   中英

Fragment communicating with an Activity

I am confused about how communication with a Fragment and an Activity is made. For example, an interface was defined here ( https://developer.android.com/training/basics/fragments/communicating.html ).

public class HeadlinesFragment extends ListFragment {
    OnHeadlineSelectedListener mCallback;

    // Container Activity must implement this interface
    public interface OnHeadlineSelectedListener {
        public void onArticleSelected(int position);
    }
...

    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        // The user clicked on a list item.
        mCallback.onArticleSelected(position);
    }
}

Eventually, the following method is called from the MainActivity.

public static class MainActivity extends Activity
    implements HeadlinesFragment.OnHeadlineSelectedListener{
    ...

    public void onArticleSelected(int position) {
        // Do something
    }
}

My questions are:

  1. How does mCallback "know" which onArticleSelected method to call (as there might be other classes that have implemented OnHeadlineSelectedListener).

     mCallback.onArticleSelected(position); 

    I wouldn't be confused if it went:

     mCallback = new OnHeadSelectedListener() { @Override public void onArticleSelected(int position) // Do something } 

    and then mCallback is referred in some way in MainActivity to utilize the onArticleSelected method in some way. In the example code, however, the line intelligently sticks to "an" interface. How does that happen?

  2. Also, I found that the Log I implemented onArticleSelected method from MainActivity is called previously to the one in onListItemClick method in HeadlineFragment. Is it expected?

  1. Since you defined the OnHeadlineSelectedListener interface with only one method, and your activity implements it, there's no ambiguity in choosing the method when you use the activity as instance of this interface, 'cause all you know about activity while using it as instance of OnHeadlineSelectedListener interface is a presence of onArticleSelected(int) method in it.
  2. It depends on when you call the logging function - before or after calling the callback method.

PS While this kind of communication between Activity and Fragment (or any other objects) is perfectly fine, personally I prefer the Event Bus approach, 'cause it gives us a possibility to organize code in a low coupled manner. Here are some nice implementations of Event Bus pattern:

Take a look at them if you are interested in this approach.

Your mCallback is your activity, in the onAttach method of your fragment, you will set the activity as listener for your fragment. By this way, this is normal that the activity is notified when you call mCallback.onArticleSelected(position);

For your first part of question

You should have a look on onAttach and onDetach methods-

 @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            mCallbacks = (OnHeadlineSelectedListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException("Activity must implement OnHeadlineSelectedListener.");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        mCallbacks = null;
    }

Second part- The behavior is not expected. You should not make your activity class static as well.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM