Cómo pasar datos entre fragmentos

Estoy tratando de pasar datos entre dos fragmentos en mi progtwig. Es solo una cadena simple que se almacena en la Lista. La lista se hace pública en los fragmentos A, y cuando el usuario hace clic en un elemento de la lista, necesito que aparezca en el fragmento B. El proveedor de contenido solo parece admitir ID, por lo que no funcionará. ¿Alguna sugerencia?

Creo que la comunicación entre fragmentos debe hacerse a través de la actividad. Y la comunicación entre el fragmento y la actividad se puede hacer de esta manera: https://developer.android.com/training/basics/fragments/communicating.html https://developer.android.com/guide/components/fragments.html#CommunicatingWithActivity

Si usa Roboguice, puede usar el EventManager en Roboguice para pasar datos sin utilizar la Actividad como interfaz. Esto es bastante limpio IMO.

Si no está usando Roboguice, puede usar Otto también como un bus de eventos: http://square.github.com/otto/

Actualización 20150909: también puede usar Green Robot Event Bus o incluso RxJava ahora también. Depende de tu caso de uso.

De la documentación de Fragment :

A menudo, deseará que un Fragmento se comunique con otro, por ejemplo, para cambiar el contenido en función de un evento del usuario. Toda la comunicación de Fragmento a Fragmento se realiza a través de la Actividad asociada. Dos fragmentos nunca deberían comunicarse directamente.

Por lo tanto, le sugiero que consulte los documentos básicos de formación de fragmentos en la documentación. Son bastante completos con un ejemplo y una guía práctica.

¿Por qué no usas un paquete? Desde su primer fragmento, así es cómo configurarlo:

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

Luego, en su segundo Fragmento, recupere los datos usando:

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

Bundle ha puesto métodos para muchos tipos de datos. Por favor, consulte http://developer.android.com/reference/android/os/Bundle.html

Digamos que tienes la Actividad AB que controla el Fragmento A y el Fragmento B. Dentro del Fragmento A, necesitas una interfaz que la Actividad AB pueda implementar. En el código de muestra de Android, tienen:

private Callbacks mCallbacks = sDummyCallbacks;

/ * Una interfaz de callback que todas las actividades que contienen este fragmento deben implementar. Este mecanismo permite que las actividades sean notificadas de selecciones de elementos. * /

 public interface Callbacks { /*Callback for when an item has been selected. */ public void onItemSelected(String 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(String id) { } }; 

La interfaz de callback se coloca dentro de uno de sus fragmentos (digamos el Fragmento A). Creo que el propósito de esta interfaz Callbacks es como una clase anidada dentro del Fragmento A que cualquier actividad puede implementar. Entonces, si el Fragmento A era un televisor, CallBacks es el control remoto de TV (interfaz) que permite que el Fragmento A sea utilizado por la Actividad AB. Puedo estar equivocado acerca de los detalles porque soy un novato pero hice que mi progtwig funcione perfectamente en todos los tamaños de pantalla y esto es lo que usé.

Entonces, dentro del Fragmento A, tenemos: (Tomé esto de los progtwigs de Muestra de 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, String, etc.); //mCallbacks.onItemSelected (Object); } 

Y dentro de Activity AB anulamos el método 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(String id) { //Pass Data to Fragment B. For example: Bundle arguments = new Bundle(); arguments.putString(“FragmentB_package”, id); FragmentB fragment = new FragmentB(); fragment.setArguments(arguments); getSupportFragmentManager().beginTransaction().replace(R.id.item_detail_container, fragment).commit(); } 

Entonces, dentro de la Actividad AB, básicamente tiras todo en un Bundle y lo pasas a B. Si no estás seguro de cómo usar un Bundle, mira la clase.

Básicamente voy por el código de muestra que proporciona Android. El que tiene las cosas de DummyContent. Cuando creas un nuevo paquete de aplicaciones de Android, es el que se titula MasterDetailFlow.

1- La primera forma es definir una interfaz

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

2- En tu actividad implementa la interfaz OnMessage

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

3- En tu fragmento implementa la interfaz OnReceive

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

Esta es la versión repetitiva del manejo del mensaje que pasa entre los fragmentos.

Otra forma de entregar el paso de datos entre fragmentos es mediante el uso de un bus de eventos.

1- Registrar / anular el registro en un autobús de eventos

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

2- Definir una clase de evento

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

3- Publica este evento en cualquier lugar de tu aplicación

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

4- Suscríbete a ese evento para recibirlo en tu Fragmento

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

Para obtener más detalles, use casos y un proyecto de ejemplo sobre el patrón de bus de eventos.

Eso depende de cómo esté estructurado el fragmento. Si puede tener algunos de los métodos en el Fragmento Clase B estáticos y también el objective Objeto TextView estático, puede invocar el método directamente en el Fragmento Clase A. Esto es mejor que un oyente ya que el método se realiza instantáneamente, y nosotros no lo hacemos. Necesito tener una tarea adicional que realice escucha durante toda la actividad. Vea el siguiente ejemplo:

 Fragment_class_B.setmyText(String yourstring); 

En el Fragmento B puede tener el método definido como:

 public static void setmyText(final String string) { myTextView.setText(string); } 

Simplemente no se olvide de tener myTextView configurado como estático en el Fragmento B e importar correctamente la clase Fragmento B en el Fragmento A.

Acabo de hacer el procedimiento en mi proyecto recientemente y funcionó. Espero que haya ayudado.

puedes leer este documento. Este concepto está bien explicado aquí http://developer.android.com/training/basics/fragments/communicating.html

Estoy trabajando en un proyecto similar y creo que mi código puede ayudar en la situación anterior

Aquí está el resumen de lo que estoy haciendo

Mi proyecto tiene dos fragmentos llamados ” FragmentA ” y “FragmentB

FragmentA Contiene una vista de lista, cuando hace clic en un elemento en FragmentA Su INDEX se pasa a FragmentB usando la interfaz de Communicator

  • El patrón de diseño se basa totalmente en el concepto de interfaces java que dice que “las variables de referencia de la interfaz pueden referirse a un objeto de subclase”
  • Deje que MainActivity implemente la interfaz proporcionada por fragmentA (de lo contrario, no podemos hacer que la variable de referencia de la interfaz apunte a MainActivity)
  • En el código siguiente, el objeto comunicador se hace para referirse al objeto MainActivity utilizando el métodosetCommunicator (Communicatot c) ” presente en fragmentA .
  • Estoy activando el método de interfaz response () de FrgamentA utilizando la referencia de MainActivity.

    Interface Communcator se define dentro de fragmentA, esto es para proporcionar acceso previo de menor acceso a la interfaz del comunicador .

a continuación está mi código de trabajo completo

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); } } 

Básicamente Implemente la interfaz para comunicarse entre Actividad y fragmento.

1) actividad principal

 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(String 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) fragmento del remitente (fragmento a actividad)

 public class SendFragment extends Fragment { StartCommunication mStartCommunicationListner; String 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().toString(); sendMessage(); } }); return mView; } interface StartCommunication { public void setComm(String 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) fragmento del receptor (actividad-a-fragmento)

  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(String msg) { TextView mTextView = (TextView) mView.findViewById(R.id.textView1); mTextView.setText(msg); } } 

Utilicé este enlace para la misma solución, espero que alguien lo encuentre útil. Ejemplo muy simple y básico.

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

En mi caso, tuve que enviar los datos hacia atrás desde FragmentB-> FragmentA, por lo tanto Intents no era una opción ya que el fragmento ya estaría inicializado. Aunque todas las respuestas anteriores suenan bien, se necesita mucho código de placa de caldera para implementarla , así que fue con un enfoque mucho más simple de usar LocalBroadcastManager , exactamente lo dicho anteriormente, pero sin todo el desagradable código repetitivo. Un ejemplo se comparte a continuación.

En el fragmento de envío (Fragmento B)

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

Y en el Mensaje para ser Recibido Fragmento (FRAGMENTO 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) { String message = intent.getStringExtra("message"); } }; } 

Espero que ayude a alguien

Fragmento clase A

 public class CountryListFragment extends ListFragment{ /** List of countries 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(); } } 

Fragmento clase 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; } } 

Clase de actividad principal para pasar datos entre fragmentos

 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 retrieved 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); } } } 

Clase de accion de 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(); } } 

Array Of Contries

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

Para obtener más detalles, visite este enlace [ http://wptrafficanalyzer.in/blog/itemclick-handler-for-listfragment-in-android/%5D . Hay un ejemplo completo ..

Básicamente aquí estamos tratando con la comunicación entre Fragmentos. La comunicación entre fragmentos nunca puede ser directamente posible. Implica actividad en cuyo contexto se crean los dos fragmentos.

Debe crear una interfaz en el fragmento de envío e implementar la interfaz en la actividad que suspenderá el mensaje y se transferirá al fragmento receptor.