Comment passer des données entre les fragments

J’essaie de passer des données entre deux fragmens dans mon programme. C’est juste une simple chaîne stockée dans la liste. La liste est rendue publique dans les fragments A, et lorsque l’utilisateur clique sur un élément de la liste, j’en ai besoin pour apparaître dans le fragment B. Le fournisseur de contenu semble uniquement prendre en charge les identifiants, ce qui ne fonctionnera pas. Aucune suggestion?

Je pense que la communication entre les fragments devrait se faire via l’activité. Et la communication entre fragment et activité peut se faire de cette manière: https://developer.android.com/training/basics/fragments/communicating.html https://developer.android.com/guide/components/fragments.html#CommunicatingWithActivity

Si vous utilisez Roboguice, vous pouvez utiliser EventManager dans Roboguice pour transmettre des données sans utiliser l’activité comme interface. Ceci est assez propre à mon avis.

Si vous n’utilisez pas Roboguice, vous pouvez également utiliser Otto comme bus d’événements: http://square.github.com/otto/

Mise à jour 20150909: Vous pouvez également utiliser le bus d’événement Green Robot ou même RxJava. Dépend de votre cas d’utilisation.

De la documentation sur les Fragment :

Souvent, vous souhaiterez qu’un fragment communique avec un autre, par exemple pour modifier le contenu en fonction d’un événement utilisateur. Toutes les communications entre fragments sont effectuées via l’activité associée. Deux fragments ne devraient jamais communiquer directement.

Je vous suggère donc de consulter les documents de base sur la formation des fragments dans la documentation. Ils sont assez complets avec un exemple et un guide de passage.

Pourquoi n’utilisez-vous pas un bundle. Voici comment configurer votre premier fragment:

 Fragment fragment = new Fragment(); Bundle bundle = new Bundle(); bundle.putInt(key, value); fragment.setArguments(bundle); 

Ensuite, dans votre deuxième fragment, récupérez les données en utilisant:

 Bundle bundle = this.getArguments(); int myInt = bundle.getInt(key, defaultValue); 

Bundle a mis des méthodes pour beaucoup de types de données. S’il vous plaît voir http://developer.android.com/reference/android/os/Bundle.html

Alors disons que vous avez Activité AB qui contrôle Frag A et Fragment B. Inside Fragment A vous avez besoin d’une interface que Activity AB peut implémenter. Dans l’exemple de code Android, ils ont:

private Callbacks mCallbacks = sDummyCallbacks;

/ * Une interface de rappel que toutes les activités contenant ce fragment doivent implémenter. Ce mécanisme permet aux activités d’être informées des sélections d’éléments. * /

 public interface Callbacks { /*Callback for when an item has been selected. */ public void onItemSelected(Ssortingng id); } /*A dummy implementation of the {@link Callbacks} interface that does nothing. Used only when this fragment is not attached to an activity. */ private static Callbacks sDummyCallbacks = new Callbacks() { @Override public void onItemSelected(Ssortingng id) { } }; 

L’interface de rappel est placée dans l’un de vos fragments (disons Fragment A). Je pense que le but de cette interface Callbacks est comme une classe nestede dans Frag A que n’importe quelle activité peut implémenter. Donc, si le fragment A était un téléviseur, le CallBacks est la télécommande TV (interface) qui permet à l’activité AB d’utiliser le fragment A. Je peux me tromper sur le détail parce que je suis un noob mais j’ai fait en sorte que mon programme fonctionne parfaitement sur toutes les tailles d’écran et c’est ce que j’ai utilisé.

Donc, à l’intérieur du fragment A, nous avons: (je l’ai pris à partir des exemples de programmes d’Android)

 @Override public void onListItemClick(ListView listView, View view, int position, long id) { super.onListItemClick(listView, view, position, id); // Notify the active callbacks interface (the activity, if the // fragment is attached to one) that an item has been selected. mCallbacks.onItemSelected(DummyContent.ITEMS.get(position).id); //mCallbacks.onItemSelected( PUT YOUR SHIT HERE. int, Ssortingng, etc.); //mCallbacks.onItemSelected (Object); } 

Et dans Activity AB, nous remplaçons la méthode onItemSelected:

 public class AB extends FragmentActivity implements ItemListFragment.Callbacks { //... @Override //public void onItemSelected (CATCH YOUR SHIT HERE) { //public void onItemSelected (Object obj) { public void onItemSelected(Ssortingng id) { //Pass Data to Fragment B. For example: Bundle arguments = new Bundle(); arguments.putSsortingng(“FragmentB_package”, id); FragmentB fragment = new FragmentB(); fragment.setArguments(arguments); getSupportFragmentManager().beginTransaction().replace(R.id.item_detail_container, fragment).commit(); } 

Donc, dans Activity AB, vous jetez tout dans un Bundle et vous le transmettez à B. Si vous ne savez pas comment utiliser un Bundle, regardez la classe.

Je vais essentiellement par l’exemple de code fourni par Android. Celui avec le truc DummyContent. Lorsque vous créez un nouveau package d’application Android, c’est celui intitulé MasterDetailFlow.

1- La première manière est de définir une interface

 public interface OnMessage{ void sendMessage(int fragmentId, Ssortingng message); } public interface OnReceive{ void onReceive(Ssortingng message); } 

2- Dans votre activité implémenter l’interface OnMessage

 public class MyActivity implements OnMessage { ... @Override public void sendMessage(int fragmentId, Ssortingng message){ Fragment fragment = getSupportFragmentManager().findFragmentById(fragmentId); ((OnReceive) fragment).sendMessage(); } } 

3- Dans votre fragment implémenter l’interface OnReceive

 public class MyFragment implements OnReceive{ ... @Override public void onReceive(Ssortingng message){ myTextView.setText("Received message:" + message); } } 

C’est la version standard du traitement des messages entre les fragments.

Une autre façon de transférer les données entre les fragments consiste à utiliser un bus d’événement.

1- Inscription / désinscription à un bus d’événement

 @Override public void onStart() { super.onStart(); EventBus.getDefault().register(this); } @Override public void onStop() { EventBus.getDefault().unregister(this); super.onStop(); } 

2- Définir une classe d’événement

 public class Message{ public final Ssortingng message; public Message(Ssortingng message){ this.message = message; } } 

3- Publiez cet événement n’importe où dans votre application

 EventBus.getDefault().post(new Message("hello world")); 

4- S’abonner à cet événement pour le recevoir dans votre fragment

 @Subscribe(threadMode = ThreadMode.MAIN) public void onMessage(Message event){ mytextview.setText(event.message); } 

Pour plus de détails, utilisez des cas et un exemple de projet sur le modèle de bus d’événements.

Cela dépend de la structure du fragment. Si vous pouvez avoir certaines des méthodes statiques de Fragment Class B et de l’object TextView cible statiques, vous pouvez appeler la méthode directement sur Fragment Class A. C’est mieux qu’un écouteur car la méthode est exécutée instantanément, et nous ne le faisons pas. Il n’est pas nécessaire d’avoir une tâche supplémentaire qui effectue l’écoute tout au long de l’activité. Voir exemple ci-dessous:

 Fragment_class_B.setmyText(Ssortingng yourssortingng); 

Sur le fragment B, vous pouvez définir la méthode comme suit:

 public static void setmyText(final Ssortingng ssortingng) { myTextView.setText(ssortingng); } 

N’oubliez pas de définir myTextView comme statique sur le fragment B et importez correctement la classe Fragment B sur le fragment A.

Je viens de faire la procédure sur mon projet récemment et cela a fonctionné. J’espère que ça a aidé.

vous pouvez lire ce document. Ce concept est bien expliqué ici http://developer.android.com/training/basics/fragments/communicating.html

Je travaille sur un projet similaire et je suppose que mon code peut aider dans la situation ci-dessus

Voici l’aperçu de ce que je fais

Mon projet a deux fragments appelés ” FragmentA ” et “FragmentB

FragmentA Contient une vue Liste lorsque vous cliquez sur un élément dans FragmentA Son INDEX est transmis à FragmentB à l’ aide de l’interface Communicator

  • Le modèle de conception est totalement basé sur le concept d’interfaces Java qui dit ” les variables de référence d’interface peuvent faire référence à un object de sous-classe”
  • Laissez MainActivity implémenter l’interface fournie par fragmentA (sinon, nous ne pouvons pas faire de variable de référence d’interface pour pointer vers MainActivity)
  • Dans le code ci-dessous, l’object communicateur fait référence à l’ object de MainActivity en utilisant la méthode ” setCommunicator (Communicatot c) ” présente dans fragmentA .
  • Je déclenche la méthode d’interface response () de FrgamentA en utilisant la référence de MainActivity.

    Le communicateur d’ interface est défini à l’intérieur de fragmentA, c’est-à-dire qu’il fournit un access minimal à l’interface de communication .

ci-dessous est mon code de travail complet

FragmentA.java

 public class FragmentA extends Fragment implements OnItemClickListener { ListView list; Communicator communicater; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // TODO Auto-generated method stub return inflater.inflate(R.layout.fragmenta, container,false); } public void setCommunicator(Communicator c){ communicater=c; } @Override public void onActivityCreated(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onActivityCreated(savedInstanceState); communicater=(Communicator) getActivity(); list = (ListView) getActivity().findViewById(R.id.lvModularListView); ArrayAdapter< ?> adapter = ArrayAdapter.createFromResource(getActivity(), R.array.items, android.R.layout.simple_list_item_1); list.setAdapter(adapter); list.setOnItemClickListener(this); } @Override public void onItemClick(AdapterView< ?> arg0, View arg1, int index, long arg3) { communicater.respond(index); } public interface Communicator{ public void respond(int index); } 

}

fragmentB.java

 public class FragmentA extends Fragment implements OnItemClickListener { ListView list; Communicator communicater; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // TODO Auto-generated method stub return inflater.inflate(R.layout.fragmenta, container,false); } public void setCommunicator(Communicator c){ communicater=c; } @Override public void onActivityCreated(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onActivityCreated(savedInstanceState); communicater=(Communicator) getActivity(); list = (ListView) getActivity().findViewById(R.id.lvModularListView); ArrayAdapter< ?> adapter = ArrayAdapter.createFromResource(getActivity(), R.array.items, android.R.layout.simple_list_item_1); list.setAdapter(adapter); list.setOnItemClickListener(this); } @Override public void onItemClick(AdapterView< ?> arg0, View arg1, int index, long arg3) { communicater.respond(index); } public interface Communicator{ public void respond(int index); } } 

MainActivity.java

 public class MainActivity extends Activity implements FragmentA.Communicator { FragmentManager manager=getFragmentManager(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); FragmentA fragA=(FragmentA) manager.findFragmentById(R.id.fragmenta); fragA.setCommunicator(this); } @Override public void respond(int i) { // TODO Auto-generated method stub FragmentB FragB=(FragmentB) manager.findFragmentById(R.id.fragmentb); FragB.changetext(i); } } 

Fondamentalement Implémenter l’interface pour communiquer entre l’activité et le fragment.

1) activité principale

 public class MainActivity extends Activity implements SendFragment.StartCommunication { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } @Override public void setComm(Ssortingng msg) { // TODO Auto-generated method stub DisplayFragment mDisplayFragment = (DisplayFragment)getFragmentManager().findFragmentById(R.id.fragment2); if(mDisplayFragment != null && mDisplayFragment.isInLayout()) { mDisplayFragment.setText(msg); } else { Toast.makeText(this, "Error Sending Message", Toast.LENGTH_SHORT).show(); } } } 

2) fragment d’émetteur (fragment à activité)

 public class SendFragment extends Fragment { StartCommunication mStartCommunicationListner; Ssortingng msg = "hi"; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // TODO Auto-generated method stub View mView = (View) inflater.inflate(R.layout.send_fragment, container); final EditText mEditText = (EditText)mView.findViewById(R.id.editText1); Button mButton = (Button) mView.findViewById(R.id.button1); mButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { // TODO Auto-generated method stub msg = mEditText.getText().toSsortingng(); sendMessage(); } }); return mView; } interface StartCommunication { public void setComm(Ssortingng msg); } @Override public void onAttach(Activity activity) { // TODO Auto-generated method stub super.onAttach(activity); if(activity instanceof StartCommunication) { mStartCommunicationListner = (StartCommunication)activity; } else throw new ClassCastException(); } public void sendMessage() { mStartCommunicationListner.setComm(msg); } } 

3) fragment de récepteur (activité à fragmenter)

  public class DisplayFragment extends Fragment { View mView; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // TODO Auto-generated method stub mView = (View) inflater.inflate(R.layout.display_frgmt_layout, container); return mView; } void setText(Ssortingng msg) { TextView mTextView = (TextView) mView.findViewById(R.id.textView1); mTextView.setText(msg); } } 

J’ai utilisé ce lien pour la même solution, j’espère que quelqu’un le trouvera utile. Exemple très simple et basique.

http://infobloggall.com/2014/06/22/communication-between-activity-and-fragments/

Dans mon cas, je devais envoyer les données à partir de FragmentB-> FragmentA, donc les Intents n’étaient pas une option car le fragment serait déjà initialisé. Toutes les réponses cidessus semblent bonnes, mais il faut beaucoup de code est allé avec une approche beaucoup plus simple de l’utilisation de LocalBroadcastManager , c’est exactement ce qui précède, mais sans tout le code passe-partout méchant. Un exemple est partagé ci-dessous.

Envoi de fragment (fragment B)

 public class FragmentB { private void sendMessage() { Intent intent = new Intent("custom-event-name"); intent.putExtra("message", "your message"); LocalBroadcastManager.getInstance(this).sendBroadcast(intent); } } 

Et dans le message à recevoir Fragment (FRAGMENT A)

  public class FragmentA { @Override public void onCreate(Bundle savedInstanceState) { ... // Register receiver LocalBroadcastManager.getInstance(this).registerReceiver(receiver, new IntentFilter("custom-event-name")); } // This will be called whenever an Intent with an action named "custom-event-name" is broadcasted. private BroadcastReceiver receiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Ssortingng message = intent.getSsortingngExtra("message"); } }; } 

J’espère que ça aide quelqu’un

Classe de fragment A

 public class CountryListFragment extends ListFragment{ /** List of counsortinges to be displayed in the ListFragment */ ListFragmentItemClickListener ifaceItemClickListener; /** An interface for defining the callback method */ public interface ListFragmentItemClickListener { /** This method will be invoked when an item in the ListFragment is clicked */ void onListFragmentItemClick(int position); } /** A callback function, executed when this fragment is attached to an activity */ @Override public void onAttach(Activity activity) { super.onAttach(activity); try{ /** This statement ensures that the hosting activity implements ListFragmentItemClickListener */ ifaceItemClickListener = (ListFragmentItemClickListener) activity; }catch(Exception e){ Toast.makeText(activity.getBaseContext(), "Exception",Toast.LENGTH_SHORT).show(); } } 

Fragment Classe B

 public class CountryDetailsFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { /** Inflating the layout country_details_fragment_layout to the view object v */ View v = inflater.inflate(R.layout.country_details_fragment_layout, null); /** Getting the textview object of the layout to set the details */ TextView tv = (TextView) v.findViewById(R.id.country_details); /** Getting the bundle object passed from MainActivity ( in Landscape mode ) or from * CountryDetailsActivity ( in Portrait Mode ) * */ Bundle b = getArguments(); /** Getting the clicked item's position and setting corresponding details in the textview of the detailed fragment */ tv.setText("Details of " + Country.name[b.getInt("position")]); return v; } } 

Classe d’activité principale pour transmettre des données entre des fragments

 public class MainActivity extends Activity implements ListFragmentItemClickListener { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } /** This method will be executed when the user clicks on an item in the listview */ @Override public void onListFragmentItemClick(int position) { /** Getting the orientation ( Landscape or Portrait ) of the screen */ int orientation = getResources().getConfiguration().orientation; /** Landscape Mode */ if(orientation == Configuration.ORIENTATION_LANDSCAPE ){ /** Getting the fragment manager for fragment related operations */ FragmentManager fragmentManager = getFragmentManager(); /** Getting the fragmenttransaction object, which can be used to add, remove or replace a fragment */ FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); /** Getting the existing detailed fragment object, if it already exists. * The fragment object is resortingeved by its tag name * */ Fragment prevFrag = fragmentManager.findFragmentByTag("in.wptrafficanalyzer.country.details"); /** Remove the existing detailed fragment object if it exists */ if(prevFrag!=null) fragmentTransaction.remove(prevFrag); /** Instantiating the fragment CountryDetailsFragment */ CountryDetailsFragment fragment = new CountryDetailsFragment(); /** Creating a bundle object to pass the data(the clicked item's position) from the activity to the fragment */ Bundle b = new Bundle(); /** Setting the data to the bundle object */ b.putInt("position", position); /** Setting the bundle object to the fragment */ fragment.setArguments(b); /** Adding the fragment to the fragment transaction */ fragmentTransaction.add(R.id.detail_fragment_container, fragment,"in.wptrafficanalyzer.country.details"); /** Adding this transaction to backstack */ fragmentTransaction.addToBackStack(null); /** Making this transaction in effect */ fragmentTransaction.commit(); }else{ /** Portrait Mode or Square mode */ /** Creating an intent object to start the CountryDetailsActivity */ Intent intent = new Intent("in.wptrafficanalyzer.CountryDetailsActivity"); /** Setting data ( the clicked item's position ) to this intent */ intent.putExtra("position", position); /** Starting the activity by passing the implicit intent */ startActivity(intent); } } } 

Classe d’activité Detailde

 public class CountryDetailsActivity extends Activity{ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); /** Setting the layout for this activity */ setContentView(R.layout.country_details_activity_layout); /** Getting the fragment manager for fragment related operations */ FragmentManager fragmentManager = getFragmentManager(); /** Getting the fragmenttransaction object, which can be used to add, remove or replace a fragment */ FragmentTransaction fragmentTransacton = fragmentManager.beginTransaction(); /** Instantiating the fragment CountryDetailsFragment */ CountryDetailsFragment detailsFragment = new CountryDetailsFragment(); /** Creating a bundle object to pass the data(the clicked item's position) from the activity to the fragment */ Bundle b = new Bundle(); /** Setting the data to the bundle object from the Intent*/ b.putInt("position", getIntent().getIntExtra("position", 0)); /** Setting the bundle object to the fragment */ detailsFragment.setArguments(b); /** Adding the fragment to the fragment transaction */ fragmentTransacton.add(R.id.country_details_fragment_container, detailsFragment); /** Making this transaction in effect */ fragmentTransacton.commit(); } } 

Tableau De Consortinges

 public class Country { /** Array of counsortinges used to display in CountryListFragment */ static Ssortingng name[] = new Ssortingng[] { "India", "Pakistan", "Sri Lanka", "China", "Bangladesh", "Nepal", "Afghanistan", "North Korea", "South Korea", "Japan", "Bhutan" }; } 

Pour plus de détails, visitez ce lien [ http://wptrafficanalyzer.in/blog/itemclick-handler-for-listfragment-in-android/%5D . Il y a un exemple complet ..

Fondamentalement, nous traitons ici de la communication entre les fragments. La communication entre fragments ne peut jamais être directement possible. Cela implique une activité dans le cadre de laquelle les deux fragments sont créés.

Vous devez créer une interface dans le fragment d’envoi et implémenter l’interface dans l’activité qui va récupérer le message et le transférer au fragment de réception.