web-dev-qa-db-fra.com

Passage d'interface à Fragment

Considérons un cas où j'ai Fragment A et Fragment B.

B déclare:

public interface MyInterface {
    public void onTrigger(int position);
}

A implémente cette interface.

Lorsque je pousse Fragment B dans la pile, comment dois-je passer la référence Fragment A dans Bundle pour que A puisse obtenir le rappel onTrigger si nécessaire.

Mon scénario d'utilisation est le suivant: A a ListView avec des éléments et B a ViewPager avec des éléments. Les deux contiennent les mêmes éléments et lorsque l'utilisateur passe de B -> A avant d'afficher B, il doit déclencher le rappel de A pour mettre à jour sa position ListView afin qu'elle corresponde à la position B du pageur.

Merci.

17
Niko
Passing interface to Fragment

Je pense que vous communiquez entre deux Fragment

Pour ce faire, vous pouvez consulter Communiquer avec d'autres fragments

public class FragmentB extends Fragment{
    MyInterface mCallback;

    // Container Activity must implement this interface
    public interface MyInterface {
        public void onTrigger();
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);

        // This makes sure that the container activity has implemented
        // the callback interface. If not, it throws an exception
        try {
            mCallback = (MyInterface ) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString()
                    + " must implement MyInterface ");
        }
    }

    ...
}
20
Amit Gupta

Pour Kotlin 1.0.0-beta-3595

interface SomeCallback {}

class SomeFragment() : Fragment(){

    var callback : SomeCallback? = null //some might want late init, but I think this way is safer

    override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        callback = activity as? SomeCallback //returns null if not type 'SomeCallback'

        return inflater!!.inflate(R.layout.frag_some_view, container, false);
    }
}
4
Krtko

Il est optimal que deux fragments ne communiquent que par une activité. Vous pouvez donc définir une interface dans le fragment B qui est implémentée dans l’activité. Ensuite, dans l'activité, définissez dans la méthode d'interface ce que vous voulez qu'il se passe dans le fragment A. 

Dans le fragment B,

MyInterface mCallback;
 public interface MyInterface {
        void onTrigger(int position);
    }

@Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        // This makes sure that the container activity has implemented
        // the callback interface. If not, it throws an exception
        try {
            mCallback = (MyInterface) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString()
                    + " must implement MyInterface");
        }
}

Méthode pour déterminer si l'utilisateur va de B à A

public void onChangeFragment(int position){
//other logic here
 mCallback.onTrigger(position);
}

En activité,

public void onTrigger(int position) {
    //Find listview in fragment A
    listView.smoothScrollToPosition(position);
    }

Bonne chance!

1
Yaya

Je pense que vous devriez utiliser la communication, comme je l'ai écrit ci-dessous. Ce code provient de cette page Android Dev de communication entre Fragments :

HeadlinesFragment

public class HeadlinesFragment extends ListFragment {
OnHeadlineSelectedListener mCallback;

public void setOnHeadlineSelectedListener(Activity activity) {
    mCallback = activity;
}

// Container Activity must implement this interface
public interface OnHeadlineSelectedListener {
    public void onArticleSelected(int position);
}

// ...
}

MainActivity

public static class MainActivity extends Activity
    implements HeadlinesFragment.OnHeadlineSelectedListener{
// ...

@Override
public void onAttachFragment(Fragment fragment) {
    if (fragment instanceof HeadlinesFragment) {
        HeadlinesFragment headlinesFragment = (HeadlinesFragment) fragment;
        headlinesFragment.setOnHeadlineSelectedListener(this);
    }
}

public static class MainActivity extends Activity
    implements HeadlinesFragment.OnHeadlineSelectedListener {
...

public void onArticleSelected(int position) {
    // The user selected the headline of an article from the HeadlinesFragment
    // Do something here to display that article
}
0
Yaroslav Ovdiienko

En utilisant la réponse de @ Amit et en s'adaptant à la question des PO, voici tout le code pertinent:

public class FragmentA extends BaseFragment implements MyInterface {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        // THIS IS JUST AN EXAMPLE OF WHERE YOU MIGHT CREATE FragmentB
        FragmentB myFragmentB = new FragmentB();        
    }


    void onTrigger(int position){
        // My Callback Happens Here!
    }
}

...

public class FragmentB extends BaseFragment {

    private MyInterface callback;

    public interface MyInterface {
        void onTrigger(int position);
    }   

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);

        // This makes sure that the container activity has implemented
        // the callback interface. If not, it throws an exception
        try {
            callback = (MyInterface ) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString() + " must implement MyInterface");
        }
    }
}
0
EdmundYeung99