Skip to content

Instantly share code, notes, and snippets.

@butelo
Created January 31, 2014 10:44
Show Gist options
  • Select an option

  • Save butelo/8729891 to your computer and use it in GitHub Desktop.

Select an option

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);
			}
		});
		
		    ...
}
@JesseScott

Copy link
Copy Markdown

nice gist.
any tips on making an interface safe from a ClassCastException ?

@mlostekk

Copy link
Copy Markdown

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
Copy Markdown

onattach deprecated in api 23

@maheshwarLigade

Copy link
Copy Markdown

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

}

ghost commented May 20, 2016

Copy link
Copy Markdown

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

@arvindrajachourasiya

Copy link
Copy Markdown

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
Copy Markdown

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

@banguyenht

Copy link
Copy Markdown

why static class ?

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