Communiquer entre un fragment et une activité-pratiques exemplaires

cette question Est principalement pour solliciter des opinions sur la meilleure façon de gérer mon application. J'ai trois fragments gérés par une seule activité. Le Fragment a a un élément cliquable la photo et le Fragment B A 4 éléments cliquables les boutons. L'autre fragment n'affiche que des détails lorsque la photo est cliquée. J'utilise ActionBarSherlock.

Screen shot

les boutons avant et arrière doivent changer la photo à la suivante précédente ou à la pose, respectivement. Je pouvais garder la photo et les boutons dans le même fragment, mais je voulais les garder séparés au cas où je voulais les réarranger dans une tablette.

j'ai besoin d'un conseil - dois-je combiner les Fragments A et B? Si non, je vais avoir besoin de comprendre comment mettre en œuvre une interface pour 3 éléments cliquables.

j'ai envisagé D'utiliser Roboguice, mais je vais déjà étendre L'utilisation de SherlockFragmentActivity de sorte que ce est un no go. J'ai vu mention D'Otto, mais je n'ai pas vu de bons tutoriels sur la façon d'inclure dans un projet. Quelle devrait être, selon vous, la meilleure pratique en matière de conception?

j'ai aussi besoin d'aide pour comprendre comment communiquer entre un fragment et une activité. J'aimerais garder quelques données "globales" dans l'application, comme la pose id. Y a-t-il un exemple de code que je peux voir à part les informations du développeur android stock? Qui n'est pas du tout utile.

BTW, je stocke déjà tout les informations sur chaque pose dans une base de données SQLite. C'est la partie facile.

47
demandé sur Vadim Kotov 2013-01-10 02:52:27

9 réponses

la façon la plus facile de communiquer entre votre activité et des fragments est d'utiliser des interfaces. L'idée est essentiellement de définir une interface à l'intérieur d'un fragment a donné et de laisser l'activité implémenter cette interface.

une fois qu'il a implémenté cette interface, vous pouvez faire tout ce que vous voulez dans la méthode qu'il supplante.

L'autre partie importante de l'interface, c'est que vous devez appeler la méthode abstraite à partir de votre fragment et n'oubliez pas de il la jeta à votre activité. Il devrait attraper une ClassCastException s'il n'est pas fait correctement.

il y a un bon tutoriel sur Simple Developer Blog sur la façon de faire exactement ce genre de chose.

j'espère que cela vous a été utile!

64
répondu Eenvincible 2016-03-30 21:59:58

la méthode suggérée pour communiquer entre fragments est d'utiliser des callbacks\listeners qui sont gérés par votre activité principale.

je pense que le code sur cette page est assez clair: http://developer.android.com/training/basics/fragments/communicating.html

vous pouvez également faire référence à L'application Io 2012 Schedule, qui est conçue pour être une application de référence de facto. Il peut être trouvé ici: http://code.google.com/p/iosched /

aussi, Voici une question avec de bonnes informations: Comment transmettre des données entre fragments

22
répondu Booger 2017-05-23 12:18:20

il est mis en œuvre par call back interface: Tout d'abord, nous devons faire une interface:

public interface UpdateFrag {
     public void updatefrag();
    }

en activité do le code suivant:

UpdateFrag updatfrag ;
public void updateApi(UpdateFrag listener) {
        updatfrag = listener;
   }

de l'événement, d'où le rappel ont à feu dans l'activité:

updatfrag.updatefrag();

dans Fragment implémenter l'interface dans CreateView faire le code suivant:

 ((Home)getActivity()).updateApi(new UpdateFrag() {
                @Override
                public void updatefrag() {
                   .....your stuff......
                }
            });
8
répondu Jyoti 2016-09-03 17:48:14

j'ai fait une bibliothèque d'annotation qui peut faire le plâtre pour vous. check this out. https://github.com/zeroarst/callbackfragment /

@CallbackFragment
public class MyFragment extends Fragment {

    @Callback
    interface FragmentCallback {
       void onClickButton(MyFragment fragment);
    }    
    private FragmentCallback mCallback;

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.bt1
                mCallback.onClickButton(this);
                break;
            case R.id.bt2
                // Because we give mandatory = false so this might be null if not implemented by the host.
                if (mCallbackNotForce != null)
                mCallbackNotForce.onClickButton(this);
                break;
        }
    }
}

il génère alors une sous-classe de votre fragment. Et il suffit de l'ajouter à FragmentManager.

public class MainActivity extends AppCompatActivity implements MyFragment.FragmentCallback {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        getSupportFragmentManager().beginTransaction()
            .add(R.id.lo_fragm_container, MyFragmentCallbackable.create(), "MY_FRAGM")
            .commit();
    }

    Toast mToast;

    @Override
    public void onClickButton(MyFragment fragment) {
        if (mToast != null)
            mToast.cancel();
        mToast = Toast.makeText(this, "Callback from " + fragment.getTag(), Toast.LENGTH_SHORT);
        mToast.show();
    }
}
3
répondu Arst 2017-06-22 08:14:13

il y a plusieurs façons de communiquer entre activités, fragments, services, etc. Le plus évident est de communiquer en utilisant des interfaces. Cependant, ce n'est pas un moyen productif de communiquer. Vous devez implémenter les écouteurs, etc.

ma suggestion est d'utiliser un bus d'événement. Le bus d'événements est une implémentation de pattern publier/s'abonner.

vous pouvez vous abonner à des événements dans votre activité et ensuite vous pouvez poster ces événements dans vos fragments, etc.

Ici sur mon blog , vous pouvez trouver plus de détails sur ce modèle et aussi un exemple de projet pour montrer l'utilisation.

2
répondu Gunhan 2016-04-08 13:45:57

Je ne suis pas sûr que j'ai vraiment compris ce que vous voulez faire, mais la façon suggérée de communiquer entre les fragments est d'utiliser des callbacks avec l'activité, jamais directement entre les fragments. Voir ici http://developer.android.com/training/basics/fragments/communicating.html

1
répondu alex 2013-01-09 23:08:20

pour communiquer entre un Activity et Fragment s, il y a plusieurs options, mais après beaucoup de lecture et de nombreuses expériences, j'ai découvert qu'il pourrait être repris de cette façon:

  • Activity veut communiquer avec l'enfant Fragment = > simplement écrire des méthodes publiques dans votre classe Fragment , et laisser le Activity les appeler
  • Fragment veut communiquer avec le parent Activity = > ceci nécessite un peu plus de travail, comme le lien officiel Android https://developer.android.com/training/basics/fragments/communicating suggère, ce serait une bonne idée de définir un interface qui sera mis en œuvre par le Activity , et qui établira un contrat pour tout Activity qui veut communiquer avec ce Fragment . Par exemple, si vous avez FragmentA , qui veut communiquer avec n'importe quel activity qui l'inclut, alors définir le FragmentAInterface qui définira quelle méthode peut le FragmentA appeler le activities qui décident de l'utiliser.
  • Un Fragment veut communiquer avec les autres Fragment => C'est le cas où vous obtenez le plus "compliqué". Puisque vous pourriez avoir besoin de passer des données de FragmentA à FragmentB et viceversa, cela pourrait nous conduire à définir 2 interfaces, FragmentAInterface qui sera mis en œuvre par FragmentB et FragmentAInterface qui sera mis en œuvre par FragmentA . Ça va commencer à rendre les choses difficiles. Et imaginez si vous avez un peu plus Fragment s sur place, et même le parent activity veut communiquer avec eux. Eh bien, cette affaire est un moment parfait pour établir un ViewModel partagé pour le activity et il est fragment S. Plus d'informations ici https://developer.android.com/topic/libraries/architecture/viewmodel . Fondamentalement, vous devez définir une classe SharedViewModel , qui a toutes les données que vous voulez partager entre le activity et le fragments qui auront besoin de communiquer des données entre eux.

l'affaire ViewModel , rend les choses plus simples à la fin, puisque vous n'avez pas à ajouter de logique supplémentaire qui rend les choses sales dans le code et salissant. De Plus, il vous permettra de séparer la collecte (au moyen d'appels vers une base de données SQLite ou une API) des données du Controller ( activities et fragments ).

1
répondu Carlos Alberto Martínez Gadea 2018-08-10 15:33:29

vous pouvez créer déclarer une interface publique avec une déclaration de fonction dans le fragment et mettre en œuvre l'interface dans l'activité. Ensuite, vous pouvez appeler la fonction à partir du fragment.

0
répondu Jacob Abraham 2013-12-31 12:06:22

j'utilise Intents pour communiquer les actions de retour à l'activité principale. L'activité principale consiste à les écouter en les surpassant de nouveau(intention). L'activité principale traduit ces actions en fragments correspondants par exemple.

donc vous pouvez faire quelque chose comme ça:

public class MainActivity extends Activity  {

    public static final String INTENT_ACTION_SHOW_FOO = "show_foo";
    public static final String INTENT_ACTION_SHOW_BAR = "show_bar";


   @Override
   protected void onNewIntent(Intent intent) {
        routeIntent(intent);
   }

  private void routeIntent(Intent intent) {
       String action = intent.getAction();
       if (action != null) {               
            switch (action) {
            case INTENT_ACTION_SHOW_FOO:
                // for example show the corresponding fragment
                loadFragment(FooFragment);
                break;
            case INTENT_ACTION_SHOW_BAR:
                loadFragment(BarFragment);
                break;               
        }
    }
}

puis dans n'importe quel fragment pour montrer le fragment de foo:

Intent intent = new Intent(context, MainActivity.class);
intent.setAction(INTENT_ACTION_SHOW_FOO);
// Prevent activity to be re-instantiated if it is already running.
// Instead, the onNewEvent() is triggered
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
getContext().startActivity(intent);
0
répondu Pepster 2015-12-16 11:17:58