SHAHM
SHAHM

Reputation: 373

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?

Upvotes: 1

Views: 246

Answers (3)

s0nerik
s0nerik

Reputation: 691

  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.

P.S. 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.

Upvotes: 1

Sanjeet A
Sanjeet A

Reputation: 5227

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.

Upvotes: 0

fab
fab

Reputation: 790

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);

Upvotes: 0

Related Questions