Skip to content

Instantly share code, notes, and snippets.

@butelo
Created January 31, 2014 10:44
Show Gist options
  • Save butelo/8729891 to your computer and use it in GitHub Desktop.
Save butelo/8729891 to your computer and use it in GitHub Desktop.
Create Callbacks on Android: A Fragment or View makes a Callback to the hosting Activity

Steps to make a Fragment or View to have a Callback to its parent Activity.

Step by step from info taken from here:

http://developer.android.com/guide/components/fragments.html#CommunicatingWithActivity


  • We have an Activity that hosts a Fragment or a View
  • We have a Fragment or View with a ListView or a Button or some element that we want the Activity to know about. i.e. we load detailed info of an element chosen on a ListView or something.
  • You have to define a callback interface inside the Fragment or the view:
public static class FragmentA extends Fragment {
    ...
    // Put this interface on the Fragment or the View
    public interface OnItemClickedListener {
        public void OnItemClicked(Parameters params);
    }
    ...
}
  • Main Activity has to implement the interface and override OnItemClicked()
public class ParentActivity extends Activity implements FragmentA.OnItemClickedListener {
...
@Override
	public void OnItemClicked(Parameters recieveparams) {
	
		whateverYouWantDone();
	}
	...
}
  • To ensure that the host activity implements the interface instantiate an instance of OnItemClicked() cast the Activity passed into onAttach() if you use a callback in a custom View you can use onAttachedToWindow() to perform the same:
public static class FragmentA extends Fragment {
    OnItemClickedListener mListener;
    ...
    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            mListener = (OnItemClickedListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString() + " must implement OnItemClickedListener");
        }
    }
    ...
}

on a View

public static class CustomView extends View {
    OnItemClickedListener mListener;
    ...
	@Override
	protected void onAttachedToWindow() {
		super.onAttachedToWindow();
		mListener = (OnItemClickedListener) this.getContext();
	}
    ...
}
  • The last thing you have to do is to create a dummyCallback implementation that does nothing but avoids a NullPointerException when the Fragment or View is not attached to an activity check also here for more explanation:

http://stackoverflow.com/questions/16956476/dummy-callback-interface

public static class FragmentA extends Fragment {
    OnItemClickedListener mListener	  = sDummyCallbacks;
    ...
	private static OnItemClickedListener sDummyCallbacks = new OnItemClickedListener() {
		@Override
		public void OnItemClicked(Parameters params) {
		}
	};

    ...
}
  • And that's it. Now when you click on a button inside a Fragment or perform any action on a View that info can be received by the Activity who can perform any actions you want. Just let the button make the call: (Or the element on the ListView or the picture you draw on a Canvas... or whatever)
public static class FragmentA extends Fragment {
    OnItemClickedListener mListener	  = sDummyCallbacks;
    ...
		Button button = (Button) view.findViewById(R.id.imageButton1);
		button.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
			//hello! anybody home?
				mListener.OnItemClicked(Parameters params);
			}
		});
		
		    ...
}
@mlostekk
Copy link

I created a whole baseclass for my Fragments

package momentum.instabeat.Fragment;

import android.app.Activity;
import android.app.Fragment;

import java.lang.reflect.ParameterizedType;

/**
 * Created by mlostek on 09.09.2015.
 *
 * My base class for a fragment that callbacks to the activity
 */
public abstract class FragmentBase<CALLBACK> extends Fragment
{
    /**
     * The callback class back to the activity
     */
    private CALLBACK callback = null;

    /**
     * Get the callback
     */
    protected CALLBACK callback()
    {
        return this.callback;
    }

    @Override
    @SuppressWarnings({"unchecked", "deprecation"})
    public void onAttach(Activity activity)
    {
        super.onAttach(activity);
        try
        {
            this.callback = (CALLBACK) activity;
        }
        catch(ClassCastException e)
        {
            String name = ((Class<CALLBACK>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0]).getSimpleName();
            throw new ClassCastException(activity.toString() + " must implement '" + name + "'");
        }
    }

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

@yoganlegendkiller
Copy link

onattach deprecated in api 23

@maheshwarLigade
Copy link

onAttach is deprecated onAttach(Activity activity)

but there is another onAttach

@Override
public void onAttach(Context context) {
    super.onAttach(context);

    Activity a;

    if (context instanceof Activity){
        a=(Activity) context;
    }

}

Copy link

ghost commented May 20, 2016

Please, how do I create call backs between a recyclerview adapter and a fragment?

@arvindrajachourasiya
Copy link

Hi,
can anyone please tell me what is callback interface exactly used for? is it used to pass data from adapter class to fragment. Thank you.

@kosratdev
Copy link

What about if my parent class is Fragment?? like tabbed fragment inside a fragment.
How can I get parent fragment??

@banguyenht
Copy link

why static class ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment