web-dev-qa-db-fra.com

Appeler une méthode d'activité à partir d'un fragment

Essayer d'appeler une méthode dans mon activité à partir d'un fragment. Je veux que le fragment donne les données de la méthode et les récupère au retour de la méthode. Je veux réaliser similaire à faire appel à une méthode statique, mais sans utiliser de statique, car cela crée des problèmes dans l'activité 

Nouveau pour les fragments, j'ai donc besoin d'une explication simple et pédagogique!

Merci!

262
Joakim Ericsson

De fragment en activité:

((YourActivityClassName)getActivity()).yourPublicMethod();

D'activité en fragment:

FragmentManager fm = getSupportFragmentManager();

//if you added fragment via layout xml
YourFragmentClass fragment = (YourFragmentClass)fm.findFragmentById(R.id.your_fragment_id);
fragment.yourPublicMethod();

Si vous avez ajouté fragment via code et utilisé une chaîne tag lorsque vous avez ajouté votre fragment, utilisez plutôt findFragmentByTag

YourFragmentClass fragment = (YourFragmentClass)fm.findFragmentByTag("yourTag");
710
Richard

Vous devriez probablement essayer de découpler le fragment de l'activité au cas où vous voudriez l'utiliser ailleurs. Vous pouvez le faire en créant une interface implémentée par votre activité. 

Donc, vous définiriez une interface comme celle-ci:

Supposons par exemple que vous vouliez attribuer à l'activité une chaîne et la renvoyer à un entier:

public interface MyStringListener{
    public Integer computeSomething(String myString);
}

Cela peut être défini dans le fragment ou dans un fichier séparé. 

Ensuite, votre activité implémenterait l'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;
  }

}

Ensuite, dans votre fragment, vous aurez une variable MyStringListener et définissez le programme d'écoute dans la méthode fragment onAttach (Activity activity). 

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

La première réponse fonctionne, mais elle couple votre fragment actuel à l’activité Hôte. Il est recommandé de garder le fragment découplé de l'activité de l'hôte au cas où vous souhaiteriez l'utiliser dans une autre activité. 

172
Marco RS

Pour Kotlin développeurs

(activity as YourActivityClassName).methodName()

Pour Java developers

((YourActivityClassName) getActivity()).methodName();
18
Wasim K. Memon

Mise à jour après avoir mieux compris le fonctionnement des fragments. Chaque fragment appartient à une activité parent. Alors utilisez simplement:

getActivity().whatever

De l'intérieur du fragment. C'est une meilleure réponse car vous évitez les moulages superflous. Si vous ne pouvez pas éviter les lancers avec cette solution, utilisez celle ci-dessous.

============

ce que vous devez faire est de jeter à l'activité extérieure 

((MainActivity) getActivity()).Method();

créer une nouvelle instance déroutera le cadre Android et ne pourra pas le reconnaître. voir également : 

https://stackoverflow.com/a/12014834/1984636

https://stackoverflow.com/a/2042829/1984636

12
sivi

Bien que j'aime complètement la réponse de Marco, je pense qu'il est juste de souligner que vous pouvez également utiliser un cadre basé sur la publication/abonnement pour obtenir le même résultat, par exemple si vous utilisez le bus d'événements, vous pouvez effectuer les opérations suivantes: 

fragment:  

EventBus.getDefault().post(new DoSomeActionEvent()); 

Activité:

 @Subscribe
onSomeActionEventRecieved(DoSomeActionEvent doSomeActionEvent){
//Do something

}
8
A.Alqadomi

Dans kotlin, vous pouvez appeler une méthode d’activité depuis un fragment comme ci-dessous:

var mainActivity: MainActivity = activity as MainActivity
        mainActivity.showToast() //Calling show toast method of activity
3
Maya Mohite

Pour accéder à une fonction déclarée dans votre activité via votre fragment, veuillez utiliser une interface, comme indiqué dans la réponse de marco.

Pour accéder à une fonction déclarée dans votre Fragment via votre activité, vous pouvez l'utiliser si vous n'avez ni tag ni identifiant

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


}

C'est le 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);
    }
}

Cette réponse est pour noobs comme moi. Bonne journée.

2
hispeed

J'ai essayé avec toutes les méthodes montrées dans ce fil et aucune n'a fonctionné pour moi, essayez celle-ci. Cela a fonctionné pour moi.

((MainActivity) getContext().getApplicationContext()).Method();
1

Ceci est de la classe Fragment ...

((KidsStoryDashboard)getActivity()).values(title_txt,bannerImgUrl);

Ce code de la classe d'activité ...

 public void values(String title_txts, String bannerImgUrl) {
    if (!title_txts.isEmpty()) {

//Do something to set text 
    }
    imageLoader.displayImage(bannerImgUrl, htab_header_image, doption);
}
1
Mathan Chinna

((YourActivityName)getActivity()).functionName();

Exemple: ((SessionActivity)getActivity()).changeFragment();

Note: le nom de la classe devrait être en public

0

Je cherchais le meilleur moyen de le faire car toutes les méthodes que nous souhaitons appeler ne se trouvent pas dans Fragment avec le même Parent d'activité.

Dans ton fragment

public void methodExemple(View view){

        // your code here

        Toast.makeText(view.getContext(), "Clicked clicked",Toast.LENGTH_LONG).show();
    }

Dans votre activité

new ExempleFragment().methodExemple(context); 
0
Maravilho Singa