android - studio - Pasar datos entre un fragmento y su actividad de contenedor
pasar variables a un fragment (11)
¿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
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");
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);
}
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();
}
}
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<String> 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();
}
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 intento 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();
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");
...
...
...
}
Simplemente puede usar EventBus , es fácil y funciona muy bien
EventBus en 3 pasos
Definir eventos:
public static class MessageEvent { /* Additional fields if needed */ }
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);
}
Publicar eventos:
EventBus.getDefault().post(new MessageEvent());
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 declaración 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
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;
}
}
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();
@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;
}