Pasar datos entre un fragmento y su actividad de contenedor

¿Cómo puedo pasar datos entre un fragmento y su actividad contenedor? ¿Hay algo similar a pasar datos entre actividades a través de intenciones?

Leí esto, pero no ayudó mucho:
http://developer.android.com/guide/topics/fundamentals/fragments.html#CommunicatingWithActivity

En tu fragmento puedes llamar a getActivity() .

Esto le dará acceso a la actividad que creó el fragmento. Desde allí, obviamente puede llamar a cualquier tipo de método de acceso que se encuentre en la actividad.

por ejemplo, para un método llamado getResult() en su actividad:

 ((MyActivity) getActivity()).getResult(); 

Intenta usar interfaces.

Cualquier fragmento que debería pasar datos a su actividad contenedora debería declarar una interfaz para manejar y pasar los datos. Luego, asegúrese de que su actividad contenedora implemente esas interfaces. Por ejemplo:

En tu fragmento, declara la interfaz …

 public interface OnDataPass { public void onDataPass(String data); } 

Luego, conecte la implementación de la clase contenedora de la interfaz al fragmento en el método onAttach, de esta forma:

 OnDataPass dataPasser; @Override public void onAttach(Context context) { super.onAttach(context); dataPasser = (OnDataPass) context; } 

Dentro de su fragmento, cuando necesite manejar el paso de datos, simplemente llámelo al objeto dataPasser:

 public void passData(String data) { dataPasser.onDataPass(data); } 

Finalmente, en su actividad de contenedor que implementa OnDataPass

 @Override public void onDataPass(String data) { Log.d("LOG","hello " + data); } 
 @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { Bundle b = getActivity().getIntent().getExtras(); wid = b.getString("wid"); rid = b.getString("rid"); View view = inflater.inflate(R.layout.categoryfragment, container, false); return view; } 

Enfoque más fácil pero no recomendado

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

Pasar datos entre un fragmento y su actividad de contenedor

Actividad:

  Bundle bundle = new Bundle(); bundle.putString("message", "Alo Elena!"); 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) { String myValue = this.getArguments().getString("message"); ... ... ... } 

No sé si esta es la mejor manera o no. He estado buscando en Google bastante tiempo para encontrar cómo puedo pasar un paquete de un fragmento a su actividad de contenedor, pero todo lo que encontré fue enviar datos de la actividad a fragmentos en su lugar. (lo cual fue un poco confuso para mí ya que soy novato).

más tarde probé algo propio que funcionó exactamente para mí como yo quería. así que lo publicaré aquí caso de que alguien como yo busque lo mismo.

// Pasar datos desde Fragment.

 Bundle gameData = new Bundle(); gameData.putStringArrayList(Constant.KEY_PLAYERS_ARR,players); gameData.putString(Constant.KEY_TEAM_NAME,custom_team_name); gameData.putInt(Constant.KEY_REQUESTED_OVER,requestedOver); Intent intent = getActivity().getIntent(); intent.putExtras(gameData); 

// Obtener datos del paquete de su actividad de contenedor.

 Bundle gameData = getIntent().getExtras(); if (gameData != null) { int over = gameData.getInt(Constant.KEY_REQUESTED_OVER); ArrayList players = gameData.getStringArrayList(Constant.KEY_PLAYERS_ARR); String team = gameData.getString(Constant.KEY_TEAM_NAME); } else if (gameData == null) { Toast.makeText(this, "Bundle is null", Toast.LENGTH_SHORT).show(); } 

La interfaz es una de las mejores soluciones:

Interfaz de pegamento:

 public interface DataProviderFromActivity { public String getName(); public String getId); } 

Mi actividad:

 public class MyActivity implements DataProviderFromActivity{ String name = "Makarov"; String id = "sys533"; ... ... ... ... ... .... .... ... ... ... ... ... .... .... public String getName(){ return name; }; public String getId(){ return id; }; } 

MyFragment:

 public class MyFragment extends Fragment{ String fragName = ""; String fragId = ""; ... ... ... ... ... .... .... ... ... ... ... ... .... .... @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); DataProviderFromActivity myActivity= (DataProviderFromActivity) getActivity(); fragName = myActivity.getName(); fragId = myActivity.getId(); ... ... ... ... ... .... .... ... ... ... ... ... .... .... updateFragmentView(); } } 

Usé una AppCompatActivity que implementa Date Listeners. Los fragmentos vinieron como una necesidad ya que necesitaba codificar un selector de rango de fechas. Y también necesitaba que el contenedor recibiera las fechas seleccionadas para devolverlas a la actividad principal.

Para la actividad del contenedor, esta es la statement de clase:

 public class AppCompatDateRange extends AppCompatActivity implements DateIniRangeFragment.OnDateIniSelectedListener, DateFimRangeFragment.OnDateFimSelectedListener 

Y las interfaces para las devoluciones de llamada:

 @Override public void onDateIniSelected(String dataIni) { Log.i("data inicial:", dataIni); } @Override public void onDateFimSelected(String dataFim) { Log.i("data final:", dataFim); } 

Las devoluciones de llamada son cadenas porque las fechas son parámetros en una selección de consulta.

El código para los fragmentos (basado en el fragmento de fecha inicial):

 public class DateIniRangeFragment extends Fragment { OnDateIniSelectedListener callbackIni; private DatePicker startDatePicker; public DateIniRangeFragment() { ///required empty constructor } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } ///through this interface the fragment sends data to the container activity public interface OnDateIniSelectedListener { void onDateIniSelected(String dataIni); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { ///layout for the fragment View v = inflater.inflate(R.layout.date_ini_fragment, container, false); ///initial date for the picker, in this case, current date startDatePicker = (DatePicker) v.findViewById(R.id.start_date_picker_appcompat); Calendar c = Calendar.getInstance(); int ano = c.get(Calendar.YEAR); int mes = c.get(Calendar.MONTH); int dia = c.get(Calendar.DAY_OF_MONTH); startDatePicker.setSpinnersShown(false); startDatePicker.init(ano, mes, dia, dateSetListener); return v; } ///listener that receives the selected date private DatePicker.OnDateChangedListener dateSetListener = new DatePicker.OnDateChangedListener() { public void onDateChanged(DatePicker view, int year, int monthOfYear, int dayOfMonth) { if (view.isShown()) { ///if the datepicker is on the screen String sDataIni = year + "-" + (monthOfYear + 1) + "-" + dayOfMonth; callbackIni.onDateIniSelected(sDataIni); //apply date to callback, string format } } }; @Override public void onAttach(Activity activity) { super.onAttach(activity); /* * this function guarantees that the container activity implemented the callback interface * */ try { callbackIni = (OnDateIniSelectedListener) activity; } catch (ClassCastException e) { throw new ClassCastException(activity.toString() + " deve implementar OnDateIniSelectedListener"); } } 

}

Para componer el contenedor + fragmentos, utilicé ViewPager (AppCompat) con una clase personalizada que amplía FragmentPagerAdapter. Sin diálogos

Simplemente puede usar EventBus , es fácil y funciona muy bien

EventBus en 3 pasos

  1. Definir eventos:

    public static class MessageEvent { /* Additional fields if needed */ }

  2. Preparar suscriptores: declare y anote su método de suscripción; opcionalmente, especifique un modo de secuencia:

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMessageEvent(MessageEvent event) {/* Do something */};

Regístrese y elimine el registro de su suscriptor. Por ejemplo, en Android, las actividades y los fragmentos generalmente deberían registrarse de acuerdo con su ciclo de vida:

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

    EventBus.getDefault().post(new MessageEvent());

Esto es trabajo para mí..

en la actividad agrega este método

  public void GetData(String data) { // do something with your data } 

y en Fragment agrega esta línea

 ((YourActivity)getContext).GetData("your data here"); 

Otra forma simple de obtener datos, pasados ​​de otra actividad, en un fragmento en una actividad de contenedor: por ejemplo:

Activity_A => Activity_B (Fragmento)

En tu Activity_A creas un bash como si estuvieras enviando datos (String aquí) a otra actividad:

 Intent intent = new Intent(getBaseContext(),Activity_B.class); intent.putExtra("NAME", "Value"); startActivity(intent); 

en tu Fragmento, contenido en tu Activity_B:

 String data = getActivity().getIntent().getExtras();