Call an activity method from a fragment
AndroidAndroid FragmentsAndroid Problem Overview
Trying to call a method in my activity from a fragment. I want the fragment to give the method data and to get the data when the method return. I want to achieve similar to call on a static method, but without the use of static because it create problems in the activity.
New to fragments so I need an easy and pedagogic explanation!
Thanks!
Android Solutions
Solution 1 - Android
From fragment to activty:
((YourActivityClassName)getActivity()).yourPublicMethod();
From activity to fragment:
FragmentManager fm = getSupportFragmentManager();
//if you added fragment via layout xml
YourFragmentClass fragment = (YourFragmentClass)fm.findFragmentById(R.id.your_fragment_id);
fragment.yourPublicMethod();
If you added fragment via code and used a tag
string when you added your fragment, use findFragmentByTag
instead:
YourFragmentClass fragment = (YourFragmentClass)fm.findFragmentByTag("yourTag");
Solution 2 - Android
You should probably try to decouple the fragment from the activity in case you want to use it somewhere else. You can do this by creating a interface that your activity implements.
So you would define an interface like the following:
Suppose for example you wanted to give the activity a String and have it return a Integer:
public interface MyStringListener{
public Integer computeSomething(String myString);
}
This can be defined in the fragment or a separate file.
Then you would have your activity implement the interface.
public class MyActivity extends FragmentActivity implements MyStringListener{
@Override
public Integer computeSomething(String myString){
/** Do something with the string and return your Integer instead of 0 **/
return 0;
}
}
Then in your fragment you would have a MyStringListener variable and you would set the listener in fragment onAttach(Activity activity) method.
public class MyFragment {
private MyStringListener listener;
@Override
public void onAttach(Context context) {
super.onAttach(context);
try {
listener = (MyStringListener) context;
} catch (ClassCastException castException) {
/** The activity does not implement the listener. */
}
}
}
edit(17.12.2015):onAttach(Activity activity) is deprecated, use onAttach(Context context) instead, it works as intended
The first answer definitely works but it couples your current fragment with the host activity. Its good practice to keep the fragment decoupled from the host activity in case you want to use it in another acitivity.
Solution 3 - Android
For Kotlin developers
(activity as YourActivityClassName).methodName()
For Java developers
((YourActivityClassName) getActivity()).methodName();
Solution 4 - Android
Update after I understand more how fragments work. Each fragment belongs to a parent activity. So just use:
getActivity().whatever
From within the fragment. It is a better answer because you avoid superflous casts. If you cannot avoid the casts with this solution use the one below.
============
what you have to do is to cast to the outer activity
((MainActivity) getActivity()).Method();
creating a new instance will be confusing the android frame and it will not be able to recognize it. see also :
Solution 5 - Android
Although i completely like Marco's Answer i think it is fair to point out that you can also use a publish/subscribe based framework to achieve the same result for example if you go with the event bus you can do the following
fragment :
EventBus.getDefault().post(new DoSomeActionEvent());
Activity:
@Subscribe
onSomeActionEventRecieved(DoSomeActionEvent doSomeActionEvent){
//Do something
}
Solution 6 - Android
In kotlin you can call activity method from fragment like below:
var mainActivity: MainActivity = activity as MainActivity
mainActivity.showToast() //Calling show toast method of activity
Solution 7 - Android
Here is how I did this:
first make interface
interface NavigationInterface {
fun closeActivity()
}
next make sure activity implements interface and overrides interface method(s)
class NotesActivity : AppCompatActivity(), NavigationInterface {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_notes)
setSupportActionBar(findViewById(R.id.toolbar))
}
override fun closeActivity() {
this.finish()
}
}
then make sure to create interface listener in fragment
private lateinit var navigationInterface: NavigationInterface
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
//establish interface communication
activity?.let {
instantiateNavigationInterface(it)
}
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_notes_info, container, false)
}
private fun instantiateNavigationInterface(context: FragmentActivity) {
navigationInterface = context as NavigationInterface
}
then you can make calls like such:
view.findViewById<Button>(R.id.button_second).setOnClickListener {
navigationInterface.closeActivity()
}
Solution 8 - Android
Thanks @BIJAY_JHA and @Manaus. I used the Kotlin version to call my signIn() method that lives in the Activity and that I'm calling from a Fragment. I'm using Navigation Architecture in Android so the Listener interface pattern isn't in the Fragment:
(activity as MainActivity).signIn()
Solution 9 - Android
For accessing a function declared in your Activity via your fragment please use an interface, as shown in the answer by marco.
For accessing a function declared in your Fragment via your activity you can use this if you don't have a tag or an id
private void setupViewPager(ViewPager viewPager) {
//fragmentOne,fragmentTwo and fragmentThree are all global variables
fragmentOne= new FragmentOne();
fragmentTwo= new FragmentTwo();
fragmentThree = new FragmentThree();
viewPagerAdapteradapter = new ViewPagerAdapter(getSupportFragmentManager());
viewPagerAdapteradapter.addFragment(fragmentOne, "Frag1");
viewPagerAdapteradapter.addFragment(fragmentTwo, "Frag2");
viewPagerAdapteradapter.addFragment(fragmentThree, "Frag3");
//viewPager has to be instantiated when you create the activity:
//ViewPager viewPager = (ViewPager)findViewById(R.id.pager);
//setupViewPager(viewPager);
//Where R.id.pager is the id of the viewPager defined in your activity's xml page.
viewPager.setAdapter(viewPagerAdapteradapter);
//frag1 and frag2 are also global variables
frag1 = (FragmentOne)viewPagerAdapteradapter.mFragmentList.get(0);
frag2 = (FragmentTwo)viewPagerAdapteradapter.mFragmentList.get(1);;
//You can use the variable fragmentOne or frag1 to access functions declared in FragmentOne
}
This is the ViewpagerAdapterClass
class ViewPagerAdapter extends FragmentPagerAdapter {
public final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
@Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
@Override
public int getCount() {
return mFragmentList.size();
}
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
@Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
This answer is for noobs like me. Have a good day.
Solution 10 - Android
This is From Fragment class...
((KidsStoryDashboard)getActivity()).values(title_txt,bannerImgUrl);
This Code From Activity Class...
public void values(String title_txts, String bannerImgUrl) {
if (!title_txts.isEmpty()) {
//Do something to set text
}
imageLoader.displayImage(bannerImgUrl, htab_header_image, doption);
}
Solution 11 - Android
((your_activity) getActivity).method_name()
Where your_activity
is the name of your activity and method_name()
is the name of the method you want to call.
Solution 12 - Android
I have been looking for the best way to do that since not every method we want to call is located in Fragment with same Activity Parent.
In your Fragment
public void methodExemple(View view){
// your code here
Toast.makeText(view.getContext(), "Clicked clicked",Toast.LENGTH_LONG).show();
}
In your Activity
new ExempleFragment().methodExemple(context);
Solution 13 - Android
I have tried with all the methods shown in this thread and none worked for me, try this one. It worked for me.
((MainActivity) getContext().getApplicationContext()).Method();
Solution 14 - Android
For Kotlin try it out
class DataForm : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
Tasks(this).getData()
}
fun getResponse(response: String) {
// code
}
}
class Tasks(private val context: Any) {
fun getData() {
val getContext = (context as DataForm).activity
val getFragment = (context as DataForm)
val responseListener = Response.Listener<String> { response ->
getFragment.getResponse(response)
}
val errorListener = Response.ErrorListener { error ->
error.printStackTrace();
}
val stringRequest = StringRequest(Request.Method.GET, url, responseListener, errorListener)
Volley.newRequestQueue(getContext).add(stringRequest)
}
}
Solution 15 - Android
Best way to call the activity method from their respective fragment
(activity as YourActivity).activtiyMethod()
use this line from your activity. For example
Suppose You have Activity A and method add() and your fragment ABC and you want to call the method add from Fragment ABC,
(activity as A).add()
Solution 16 - Android
((YourActivityName)getActivity()).functionName();
Example : ((SessionActivity)getActivity()).changeFragment();
Note : class name should be in public
Solution 17 - Android
From fragment to activity:
((YourActivityClassName)requireActivity()).yourPublicMethod();