Comment puis-je transmettre des données entre un fragment et son activité conteneur? Existe-t-il quelque chose de similaire à la transmission de données entre activités par intentions?
J'ai lu ceci, mais ça n'a pas beaucoup aidé:
http://developer.Android.com/guide/topics/fundamentals/fragments.html#CommunicatingWithActivity
Dans votre fragment, vous pouvez appeler getActivity()
.
Cela vous donnera accès à l'activité qui a créé le fragment. À partir de là, vous pouvez évidemment appeler n'importe quelle méthode d'accès figurant dans l'activité.
par exemple. pour une méthode appelée getResult()
sur votre activité:
((MyActivity) getActivity()).getResult();
Essayez d'utiliser des interfaces.
Tout fragment devant renvoyer des données à son activité doit déclarer une interface permettant de gérer et de transmettre les données. Assurez-vous ensuite que votre activité qui contient implémente ces interfaces. Par exemple:
Dans votre fragment, déclarez l'interface ...
public interface OnDataPass {
public void onDataPass(String data);
}
Ensuite, connectez l'implémentation de l'interface de la classe contenante au fragment de la méthode onAttach, comme suit:
OnDataPass dataPasser;
@Override
public void onAttach(Context context) {
super.onAttach(context);
dataPasser = (OnDataPass) context;
}
Dans votre fragment, lorsque vous devez gérer le transfert de données, appelez-le simplement sur l'objet dataPasser:
public void passData(String data) {
dataPasser.onDataPass(data);
}
Enfin, dans votre activité contenant qui implémenteOnDataPass
...
@Override
public void onDataPass(String data) {
Log.d("LOG","hello " + data);
}
Approche la plus facile mais non recommandée
Vous pouvez accéder aux données d'activité à partir de fragment:
Activité:
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;
}
}
fragment:
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;
}
}
@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;
}
Passer des données entre un fragment et son activité conteneur
Activité:
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();
fragment:
Lecture de la valeur dans le fragment
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
String myValue = this.getArguments().getString("message");
...
...
...
}
Je ne sais pas si c'est la meilleure façon ou non. Je cherche depuis longtemps sur Google. Comment puis-je passer d'un paquet à un conteneur, mais tout ce que j'ai trouvé, c'est d'envoyer des données d'activité à fragment à la place (ce qui était un peu déroutant pour moi car je suis novice).
plus tard, j'ai essayé quelque chose qui m'était propre et qui a fonctionné exactement comme je le voulais. je vais donc le poster ici au cas où quelqu'un comme moi chercherait la même chose.
// Passing data from 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);
// Obtention des données du paquet à partir de son activité de conteneur.
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();
}
L'interface est l'une des meilleures solutions:
Interface de colle:
public interface DataProviderFromActivity {
public String getName();
public String getId);
}
Mon activité:
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();
}
}
J'ai utilisé un AppCompatActivity qui implémente Date Listeners. Les fragments venaient comme une nécessité car je devais coder un sélecteur de plage de dates. Et j’avais également besoin du conteneur pour recevoir les dates sélectionnées et les renvoyer à l’activité parente.
Pour l'activité conteneur, il s'agit de la déclaration de classe:
public class AppCompatDateRange extends AppCompatActivity implements
DateIniRangeFragment.OnDateIniSelectedListener, DateFimRangeFragment.OnDateFimSelectedListener
Et les interfaces pour les callbacks:
@Override
public void onDateIniSelected(String dataIni) {
Log.i("data inicial:", dataIni);
}
@Override
public void onDateFimSelected(String dataFim) {
Log.i("data final:", dataFim);
}
Les callbacks sont des chaînes car les dates sont des paramètres dans une requête de sélection.
Le code pour les fragments (basé sur le fragment de date initial):
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");
}
}
}
Pour composer le conteneur + fragments, j'ai utilisé un ViewPager (AppCompat) avec une classe personnalisée qui étend FragmentPagerAdapter. Pas de dialogues.
Vous pouvez simplement utiliser EventBus c'est facile et fonctionne très bien
EventBus en 3 étapes
Définir les événements:
public static class MessageEvent { /* Additional fields if needed */ }
Préparez les abonnés: Déclarez et annotez votre méthode d'abonnement, spécifiez éventuellement un mode de thread:
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(MessageEvent event) {/* Do something */};
Enregistrez et désinscrivez votre abonné. Par exemple, sur Android, les activités et les fragments doivent généralement s'inscrire en fonction de leur cycle de vie:
@Override
public void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
@Override
public void onStop() {
super.onStop();
EventBus.getDefault().unregister(this);
}
Événements post:
EventBus.getDefault().post(new MessageEvent());
Je sais que cela pourrait être tard. Mais j'ai aussi toujours été perdu sur cette question. Je partage ce lien ... parce que c'est peut-être la meilleure explication que j'ai jamais trouvée sur le Web pour cela. Cela résout fragment à activité & fragment à fragment !
public class Fragmentdemo extends Fragment {
public interface onDemoEventListener {
public void demoEvent(String s);
}
onDemoEventListener demoEventListener;
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
demoEventListener = (onDemoEventListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must implement onDemoEventListener");
}
}
final String LOG_TAG = "TAG";
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragmentdemo, null);
Button button = (Button) v.findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
demoEventListener.someEvent("Test text to Fragment1");
}
});
enter code here
return v;
}
}
Cela fonctionne pour moi..
dans Activité ajouter cette méthode
public void GetData(String data)
{
// do something with your data
}
et dans Fragment ajouter cette ligne
((YourActivity)getContext).GetData("your data here");