Enviar datos de la actividad a fragmento en Android

Tengo dos clases. Primero es actividad, segundo es un fragmento donde tengo algunos edittexts. En actividad tengo una subclase con tarea asincrónica y en el método doInBackground obtengo algún resultado, que doInBackground en variable. ¿Cómo puedo enviar esta variable de la subclase “mi actividad” a este fragmento?

De Activity envías datos con intención como:

 Bundle bundle = new Bundle(); bundle.putString("edttext", "From Activity"); // set Fragmentclass Arguments Fragmentclass fragobj = new Fragmentclass(); fragobj.setArguments(bundle); 

y en el método Fragment onCreateView:

 @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { String strtext = getArguments().getString("edttext"); return inflater.inflate(R.layout.fragment, container, false); } 

También puede acceder a los datos de actividad desde el fragmento:

Actividad:

 public class MyActivity extends Activity { private String myString = "hello"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_my); ... } public String getMyData() { return myString; } } 

Fragmento:

 public class MyFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { MyActivity activity = (MyActivity) getActivity(); String myDataFromActivity = activity.getMyData(); return view; } } 

He encontrado muchas respuestas aquí en stackoverflow.com pero definitivamente esta es la respuesta correcta de:

“Enviar datos de la actividad a fragmentar en Android”.

Actividad:

  Bundle bundle = new Bundle(); String myMessage = "Stackoverflow is cool!"; bundle.putString("message", myMessage ); FragmentClass fragInfo = new FragmentClass(); fragInfo.setArguments(bundle); transaction.replace(R.id.fragment_single, fragInfo); transaction.commit(); 

Fragmento:

Leyendo el valor en el fragmento

  @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { Bundle bundle = this.getArguments(); String myValue = bundle.getString("message"); ... ... ... } 

o solo

  @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { String myValue = this.getArguments().getString("message"); ... ... ... } 

Esta respuesta puede ser demasiado tarde. pero será útil para futuros lectores.

Tengo algunos criterios. He codificado para elegir el archivo del bash. y el archivo seleccionado para pasar a un fragmento particular para un proceso posterior. Tengo muchos fragmentos que tienen la funcionalidad de File picking. en ese momento, cada vez que verifica la condición y obtiene el fragmento y pasa el valor es bastante desagradable. entonces, he decidido pasar el valor usando la interfaz.

Paso 1: crea la interfaz en la actividad principal.

  public interface SelectedBundle { void onBundleSelect(Bundle bundle); } 

Paso 2: crea el método en la misma actividad

  public void setOnBundleSelected(SelectedBundle selectedBundle) { this.selectedBundle = selectedBundle; } 

Paso 3: crea la referencia SelectedBundle en la misma actividad

  SelectedBundle selectedBundle; 

Paso 4: es necesario inicializar la referencia SelectedBundle, que son todos los fragmentos que necesitan la funcionalidad del creador de archivos. Colocas este código en tu fragmento en el onCreateView(..)

  ((MainActivity)getActivity()).setOnBundleSelected(new MainActivity.SelectedBundle() { @Override public void onBundleSelect(Bundle bundle) { updateList(bundle); } }); 

Paso 5: onActivityResult desde MainActivity, pasa los valores a los fragmentos usando la interfaz.

  @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { selectedBundle.onBundleSelect(bundle); } 

Eso es todo. Implementa cada fragmento que necesites en FragmentClass. Eres genial. has hecho. GUAU…

La idea básica del uso de fragmentos (F) es crear componentes de interfaz de usuario autosustentables reutilizables en aplicaciones de Android. Estos Fragmentos están contenidos en actividades y hay una forma (la mejor) común de crear vías de comunicación desde A -> F y FA, ​​es imprescindible comunicarse entre FF a través de una Actividad porque entonces solo los Fragmentos se desacoplan y son autosuficientes.

Entonces pasar datos de A -> F va a ser el mismo explicado por ρяσѕρєя K. Además de esa respuesta, después de la creación de los Fragmentos dentro de una Actividad, también podemos pasar datos a los métodos de llamadas de fragmentos en Fragmentos.

Por ejemplo:

  ArticleFragment articleFrag = (ArticleFragment) getSupportFragmentManager().findFragmentById(R.id.article_fragment); articleFrag.updateArticleView(position); 

Si pasa una referencia al fragmento (subclase concreta de) en la tarea asíncrona, puede acceder al fragmento directamente.

Algunas formas de pasar la referencia de fragmento a la tarea asíncrona:

  • Si su tarea asíncrona es una clase totalmente desarrollada (la class FooTask extends AsyncTask ), pase su fragmento al constructor.
  • Si su tarea asíncrona es una clase interna, solo declare una variable de Fragmento final en el ámbito de la tarea asíncrona, o como un campo de la clase externa. Podrás acceder a eso desde la clase interna.

El enfoque mejor y más conveniente es llamar instancia de fragmento y enviar datos en ese momento. cada fragmento por defecto tiene un método de instancia

Por ejemplo: si su nombre de fragmento es MyFragment

entonces llamarás a tu fragmento de una actividad como esta:

 getSupportFragmentManager().beginTransaction().add(R.id.container, MyFragment.newInstance("data1","data2"),"MyFragment").commit(); 

* R.id.container es una identificación de mi FrameLayout

entonces en MyFragment.newInstance (“data1”, “data2”) puede enviar datos al fragmento y en su fragmento obtiene estos datos en MyFragment newInstance (String param1, String param2)

 public static MyFragment newInstance(String param1, String param2) { MyFragment fragment = new MyFragment(); Bundle args = new Bundle(); args.putString(ARG_PARAM1, param1); args.putString(ARG_PARAM2, param2); fragment.setArguments(args); return fragment; } 

y luego en el método de fragmento de onCreate obtendrá los datos:

 @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (getArguments() != null) { mParam1 = getArguments().getString(ARG_PARAM1); mParam2 = getArguments().getString(ARG_PARAM2); } } 

entonces ahora mParam1 tiene data1 y mParam2 tiene data2

ahora puedes usar este mParam1 y mParam2 en tu fragmento.

Publicación muy antigua, aún me atrevo a agregar una pequeña explicación que hubiera sido útil para mí.

Técnicamente, puede establecer directamente miembros de cualquier tipo en un fragmento de la actividad.
Entonces, ¿por qué Bundle?
La razón es muy simple: el paquete proporciona una manera uniforme de manejar:
– creando / abriendo fragmento
– reconfiguración (rotación de pantalla) – simplemente agregue el paquete inicial / actualizado a outState en onSaveInstanceState ()
– Restauración de la aplicación después de ser recogida de basura en el fondo (como con la reconfiguración).

Puede (si le gustan los experimentos) crear una solución alternativa en situaciones simples, pero el enfoque Bundle simplemente no ve la diferencia entre un fragmento y mil en un backstack: se mantiene simple y directo.
Es por eso que la respuesta de @Elenasys es la solución más elegante y universal.
Y es por eso que la respuesta dada por @Martin tiene trampas

De la Actividad envías datos con Bundle como:

 Bundle bundle = new Bundle(); bundle.putString("data", "Data you want to send"); // Your fragment MyFragment obj = new MyFragment(); obj.setArguments(bundle); 

Y en el método Fragment onCreateView obtén los datos:

 @Override public View onCreateView(LayoutInflater inflater, ViewGroup container,`Bundle savedInstanceState) { String data = getArguments().getString("data");// data which sent from activity return inflater.inflate(R.layout.myfragment, container, false); } 

el mejor enfoque para enviar datos de clase de actividad a fragmento pasa a través de métodos setter. Me gusta

 FragmentClass fragmentClass = new FragmentClass(); fragmentClass.setMyList(mylist); fragmentClass.setMyString(myString); fragmentClass.setMyMap(myMap); 

y obtenga estos datos de la clase fácilmente.

A veces puede recibir intenciones en su actividad y necesita pasar la información a su fragmento de trabajo.
Las respuestas dadas son correctas si necesita iniciar el fragmento, pero si aún funciona, setArguments() no es muy útil.
Se produce otro problema si la información pasada hará que interactúe con su UI. En ese caso, no puede llamar a algo como myfragment.passData() porque android rápidamente le informa que solo el subproceso con el que creó la vista puede interactuar.

Entonces mi propuesta es usar un receptor. De esta forma, puede enviar datos desde cualquier lugar, incluida la actividad, pero el trabajo se realizará dentro del contexto del fragmento.

En tu fragmento onCreate() :

 protected DataReceiver dataReceiver; public static final String REC_DATA = "REC_DATA"; @Override public void onCreate(Bundle savedInstanceState) { data Receiver = new DataReceiver(); intentFilter = new IntentFilter(REC_DATA); getActivity().registerReceiver(dataReceiver, intentFilter); } private class DataReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { int data= intent.getIntExtra("data", -1); // Do anything including interact with your UI } } 

En tu actividad:

 // somewhere Intent retIntent = new Intent(RE_DATA); retIntent.putExtra("data", myData); sendBroadcast(retIntent); 

Si una activity necesita hacer que un fragment realice una acción después de la inicialización, la manera más fácil es hacer que la activity invoque un método en la instancia del fragment . En el fragment , agrega un método:

 public class DemoFragment extends Fragment { public void doSomething(String param) { // do something in fragment } } 

y luego en la activity , obtenga acceso al fragment usando el administrador de fragment y llame al method :

 public class MainActivity extends FragmentActivity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); DemoFragment fragmentDemo = (DemoFragment) getSupportFragmentManager().findFragmentById(R.id.fragmentDemo); fragmentDemo.doSomething("some param"); } } 

y luego la activity puede comunicarse directamente con el fragment al invocar este method .

Puede crear un método público estático en fragmento donde obtendrá referencias estáticas de ese fragmento y luego pasar datos a esa función y establecer esos datos en argumentos en el mismo método y obtener datos a través de getArgument en el método de fragmentación oncreate, y establecer esos datos en local variables.

Use la siguiente interfaz para comunicarse entre actividad y fragmento

 public interface BundleListener { void update(Bundle bundle); Bundle getBundle(); } 

O use este oyente genérico para comunicación bidireccional utilizando la interfaz

  /** * Created by Qamar4P on 10/11/2017. */ public interface GenericConnector { T getData(); void updateData(E data); void connect(GenericConnector connector); } 

fragmento de mostrar el método

 public static void show(AppCompatActivity activity) { CustomValueDialogFragment dialog = new CustomValueDialogFragment(); dialog.connector = (GenericConnector) activity; dialog.show(activity.getSupportFragmentManager(),"CustomValueDialogFragment"); } 

También puedes GenericConnector tu contexto a GenericConnector en onAttach(Context)

en tu actividad

 CustomValueDialogFragment.show(this); 

en tu fragmento

 ... @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); connector.connect(new GenericConnector() { @Override public Object getData() { return null; } @Override public void updateData(Object data) { } @Override public void connect(GenericConnector connector) { } }); } ... public static void show(AppCompatActivity activity, GenericConnector connector) { CustomValueDialogFragment dialog = new CustomValueDialogFragment(); dialog.connector = connector; dialog.show(activity.getSupportFragmentManager(),"CustomValueDialogFragment"); } 

Nota: Nunca lo use como "".toString().toString().toString(); camino.

Me gustaría agregar para los principiantes que la diferencia entre las 2 respuestas más votadas aquí está dada por el uso diferente de un fragmento.

Si usa el fragmento dentro de la clase java donde tiene los datos que desea pasar, puede aplicar la primera respuesta para pasar datos:

 Bundle bundle = new Bundle(); bundle.putString("edttext", "From Activity"); Fragmentclass fragobj = new Fragmentclass(); fragobj.setArguments(bundle); 

Sin embargo, si utiliza, por ejemplo, el código predeterminado proporcionado por Android Studio para fragmentos con tabs, este código no funcionará.

No funcionará incluso si reemplaza el Fragmento de marcador de posición por defecto con sus FragmentClasses, e incluso si corrige el FragmentPagerAdapter a la nueva situación añadiendo un modificador para getItem () y otro modificador para getPageTitle () (como se muestra aquí )

Advertencia: el clip mencionado anteriormente tiene errores de código, que explicaré más adelante, ¡pero es útil para ver cómo se pasa del código predeterminado al código editable para fragmentos con tabs! El rest de mi respuesta tiene mucho más sentido si considera las clases de Java y los archivos xml de ese clip (representativo para un primer uso de fragmentos con tabs en un escenario para principiantes).

La razón principal por la que la respuesta más votada de esta página no funcionará es que en ese código predeterminado para fragmentos con tabs, los fragmentos se usan en otra clase Java: ¡FragmentPagerAdapter!

Entonces, para enviar los datos, está tentado de crear un paquete en MotherActivity y pasarlo en el FragmentPagerAdapter, usando la respuesta no.2.

Solo que eso está mal de nuevo. ( Probablemente podría hacerlo así, pero es solo una complicación que no es realmente necesaria ).

La forma correcta / más fácil de hacerlo, creo, es pasar los datos directamente al fragmento en cuestión, usando la respuesta no.2. Sí, habrá un estrecho acoplamiento entre la Actividad y el Fragmento, PERO, para fragmentos con tabs, eso es algo esperado. Incluso te aconsejaría que crees los fragmentos con tabs dentro de la clase Java de MotherActivity (como subclases, ya que nunca se usarán fuera de MotherActivity). Es fácil, solo agrega dentro de la clase Java de MotherActivity tantos Fragmentos como necesites:

  public static class Tab1 extends Fragment { public Tab1() { } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.your_layout_name_for_fragment_1, container, false); return rootView; } }. 

Por lo tanto, para pasar datos de MotherActivity a dicho Fragment, deberá crear Strings / Bundles privados encima de la actividad onCreate of the Mother, que puede completar con los datos que desea pasar a los fragmentos y pasarlos a través de un método creado después de onCreate (aquí llamado getMyData ()).

 public class MotherActivity extends Activity { private String out; private Bundle results; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_mother_activity); // for example get a value from the previous activity Intent intent = getIntent(); out = intent.getExtras().getString("Key"); } public Bundle getMyData() { Bundle hm = new Bundle(); hm.putString("val1",out); return hm; } } 

Y luego en la clase de fragmento, usas getMyData:

 public static class Tab1 extends Fragment { /** * The fragment argument representing the section number for this * fragment. */ public Tab1() { } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.your_layout_name_for_fragment_1, container, false); TextView output = (TextView)rootView.findViewById(R.id.your_id_for_a_text_view_within_the_layout); MotherActivity activity = (MotherActivity)getActivity(); Bundle results = activity.getMyData(); String value1 = results.getString("val1"); output.setText(value1); return rootView; } } 

Si tiene consultas en la base de datos, le aconsejo que las haga en MotherActivity (y pase sus resultados como cadenas / enteros adjuntos a claves dentro de un paquete como se muestra arriba), ya que dentro de los fragmentos tabulados, su syntax será más compleja (esto se convierte en getActivity () por ejemplo, y getIntent se convierte en getActivity (). getIntent), pero también tiene la opción de hacer lo que desee.

Mi consejo para principiantes es centrarse en pequeños pasos. En primer lugar, obtenga su intención de abrir una actividad con tabs muy simple, sin pasar NINGÚN dato. ¿Funciona? ¿Abre las tabs que esperas? Si no, ¿por qué?

A partir de eso, y aplicando soluciones como las presentadas en este clip , vea lo que falta. Para ese clip en particular, el mainactivity.xml nunca se muestra. Eso seguramente te confundirá. Pero si prestas atención, verás que, por ejemplo, el contexto (herramientas: contexto) es incorrecto en los archivos de fragmentos xml. Cada fragmento XML necesita apuntar a la clase de fragmento correcta (o subclase usando el separador $).

También verá que en la clase java de actividad principal necesita agregar tabLayout.setupWithViewPager (mViewPager), justo después de la línea TabLayout tabLayout = (TabLayout) findViewById (R.id.tabs); sin esta línea, su vista en realidad no está vinculada a los archivos XML de los fragmentos, pero muestra SOLAMENTE el archivo xml de la actividad principal.

Además de la línea en la clase java de la actividad principal, en el archivo XML de actividad principal necesita cambiar las tabs para adaptarlas a su situación (por ejemplo, agregar o quitar TabItems). Si no tiene tabs en el XML de actividad principal, posiblemente no haya elegido el tipo de actividad correcto cuando lo creó en primer lugar (actividad nueva – actividad con tabs).

Tenga en cuenta que en los últimos 3 párrafos, ¡hablo sobre el video! Entonces, cuando digo XML de actividad principal, es el XML de actividad principal en el video, que en su situación es el archivo XML de MotherActivity.

La manera más inteligente y comprobada de pasar datos entre fragmentos y actividad es crear variables, por ejemplo:

 class StorageUtil { public static ArrayList employees; } 

Luego, para pasar datos de fragmento a actividad, lo hacemos en el método onActivityCreated:

 //a field created in the sending fragment ArrayList employees; @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); employees=new ArrayList(); //java 7 and above syntax for arraylist else use employees=new ArrayList() for java 6 and below //Adding first employee Employee employee=new Employee("1","Andrew","Sam","1984-04-10","Male","Ghanaian"); employees.add(employee); //Adding second employee Employee employee=new Employee("1","Akuah","Morrison","1984-02-04","Female","Ghanaian"); employees.add(employee); StorageUtil.employees=employees; } 

Ahora puede obtener el valor de StorageUtil.employees desde cualquier lugar. ¡Buena suerte!

Mi solución es escribir un método estático dentro del fragmento:

 public TheFragment setData(TheData data) { TheFragment tf = new TheFragment(); tf.data = data; return tf; } 

De esta manera, estoy seguro de que todos los datos que necesito están dentro del Fragmento antes de cualquier otra operación posible que podría necesitar trabajar con él. También se ve más limpio en mi opinión.

Marque esta respuesta, si desea pasar los datos a fragmento después de que se haya creado https://stackoverflow.com/a/46467866/1594998

En tu actividad declara variable estática

 public static HashMap contactItems=new HashMap(); 

Luego, en tu fragmento, haz clic en seguir

 ActivityName.contactItems.put(Number,contactsModal);