varios una studio pasar otro navegar fragments fragmentos fragmento entre datos con comunicar boton activity actividad android android-fragments

android - una - pasar variables activity a fragment



Cómo pasar datos entre fragmentos (13)

¿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

Estoy tratando de pasar datos entre dos fragmentos en mi programa. 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?


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.


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/


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.


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 devolución de llamada 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 devolución de llamada 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 programa 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 programas 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.


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


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 objetivo 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.


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étodo " setCommunicator (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); } }


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/] . Hay un ejemplo completo ..


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.


puedes leer este documento. Este concepto está bien explicado aquí documentation



De la documentation 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 documentation en la documentación. Son bastante completos con un ejemplo y una guía práctica.