Je ne peux pas mettre à jour le contenu dans ViewPager.
Une question: Quelle est la relation et l’usage correct des méthodes instantiateItem () et getItem () dans la classe FragmentPagerAdapter?
J'utilisais seulement getItem () pour instancier et renvoyer mes fragments:
@Override
public Fragment getItem(int position) {
return new MyFragment(context, paramters);
}
Cela a bien fonctionné (mais comme dit je ne peux pas changer le contenu).
J'ai donc trouvé ceci: ViewPager PagerAdapter ne mettant pas à jour la vue
En particulier celui dans lequel on parle de méthode instantiateItem ():
"Mon approche consiste à utiliser la méthode setTag () pour toute vue instanciée dans la méthode instantiateItem ()"
Alors maintenant, je veux implémenter instantiateItem () pour le faire. Mais je ne sais pas ce que je dois y retourner (return est Object) et quelle est la relation avec getItem (int position)?
J'utilise actuellement getItem pour instancier le fragment, est-ce faux? Mais alors dois-je mettre les fragments dans une variable d'instance ou ne pas implémenter getItem () du tout ...? Je ne comprends tout simplement pas.
J'ai essayé de lire la référence :
public abstract Fragment getItem (int position)
Renvoie le fragment associé à une position spécifiée.
public Object instantiateItem (conteneur ViewGroup, int position)
Créez la page pour la position donnée. L'adaptateur est responsable de l'ajout de la vue au conteneur indiqué ici, même s'il doit uniquement s'assurer que cela est fait au moment où il revient de finishUpdate (ViewGroup) . Paramètres
conteneur La vue contenant dans laquelle la page sera affichée . position La position de la page à instancier.
Résultats
Renvoie un objet représentant la nouvelle page. Cela n'a pas besoin d'être une vue, mais peut être un autre conteneur de la page.
... mais je ne comprends toujours pas comment ils sont liés et ce que je dois faire.
Voici mon code. J'utilise le package de support v4.
ViewPagerTest
public class ViewPagerTest extends FragmentActivity {
private ViewPager pager;
private MyFragmentAdapter adapter;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.pager1);
pager = (ViewPager)findViewById(R.id.slider);
String[] data = {"page1", "page2", "page3", "page4", "page5", "page6"};
adapter = new MyFragmentAdapter(getSupportFragmentManager(), 6, this, data);
pager.setAdapter(adapter);
((Button)findViewById(R.id.button)).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
reload();
}
});
}
private void reload() {
String[] data = {"changed1", "changed2", "changed3", "changed4", "changed5", "changed6"};
//adapter = new MyFragmentAdapter(getSupportFragmentManager(), 6, this, data);
adapter.setData(data);
adapter.notifyDataSetChanged();
pager.invalidate();
//pager.setCurrentItem(0);
}
}
MyFragmentAdapter
class MyFragmentAdapter extends FragmentPagerAdapter {
private int slideCount;
private Context context;
private String[] data;
public MyFragmentAdapter(FragmentManager fm, int slideCount, Context context, String[] data) {
super(fm);
this.slideCount = slideCount;
this.context = context;
this.data = data;
}
@Override
public Fragment getItem(int position) {
return new MyFragment(data[position], context);
}
@Override
public int getCount() {
return slideCount;
}
public void setData(String[] data) {
this.data = data;
}
@Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
}
Mon Fragment
public final class MyFragment extends Fragment {
private String text;
public MyFragment(String text, Context context) {
this.text = text;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.slide, null);
((TextView)view.findViewById(R.id.text)).setText(text);
return view;
}
}
Voici aussi quelqu'un avec un problème similaire, pas de réponse ...
http://www.mail-archive.com/[email protected]/msg200477.html
Lorsque vous utilisez FragmentPagerAdapter ou FragmentStatePagerAdapter, il est préférable de traiter uniquement avec getItem()
et de ne pas toucher à instantiateItem()
du tout. L'interface instantiateItem()
-destroyItem()
-isViewFromObject()
sur PagerAdapter est une interface de niveau inférieur que FragmentPagerAdapter utilise pour implémenter l'interface beaucoup plus simple getItem()
.
Avant d'entrer dans cela, je devrais préciser que
Si vous souhaitez remplacer les fragments actuellement affichés, vous devez éviter FragmentPagerAdapter et utiliser FragmentStatePagerAdapter.
Une version antérieure de cette réponse faisait l'erreur d'utiliser FragmentPagerAdapter pour son exemple. Cela ne fonctionnera pas car FragmentPagerAdapter ne détruit jamais un fragment après sa première visualisation.
Je ne recommande pas les solutions de contournement setTag()
et findViewWithTag()
fournies dans le message que vous avez lié. Comme vous l'avez découvert, l'utilisation de setTag()
et findViewWithTag()
ne fonctionne pas avec les fragments, ce n'est donc pas une bonne correspondance.
La bonne solution consiste à remplacer getItemPosition()
. Lorsque notifyDataSetChanged()
est appelé, ViewPager appelle getItemPosition()
sur tous les éléments de son adaptateur pour voir s'ils doivent être déplacés ou supprimés.
Par défaut, getItemPosition()
renvoie POSITION_UNCHANGED
, ce qui signifie: "Cet objet convient parfaitement, ne le détruisez pas et ne le supprimez pas." Retourner POSITION_NONE
corrige le problème en disant plutôt: "Cet objet n'est plus un élément que je suis en train d'afficher, supprimez-le." Cela a donc pour effet de supprimer et de recréer chaque élément de votre adaptateur.
C'est une solution tout à fait légitime! Avec ce correctif, notifyDataSetChanged se comporte comme un adaptateur standard sans recyclage de vue. Si vous implémentez ce correctif et que les performances sont satisfaisantes, vous êtes prêt pour la course. Travail accompli.
Si vous avez besoin de meilleures performances, vous pouvez utiliser une implémentation plus sophistiquée de getItemPosition()
. Voici un exemple pour un pager créant des fragments à partir d'une liste de chaînes:
ViewPager pager = /* get my ViewPager */;
// assume this actually has stuff in it
final ArrayList<String> titles = new ArrayList<String>();
FragmentManager fm = getSupportFragmentManager();
pager.setAdapter(new FragmentStatePagerAdapter(fm) {
public int getCount() {
return titles.size();
}
public Fragment getItem(int position) {
MyFragment fragment = new MyFragment();
fragment.setTitle(titles.get(position));
return fragment;
}
public int getItemPosition(Object item) {
MyFragment fragment = (MyFragment)item;
String title = fragment.getTitle();
int position = titles.indexOf(title);
if (position >= 0) {
return position;
} else {
return POSITION_NONE;
}
}
});
Avec cette implémentation, seuls les fragments affichant de nouveaux titres seront affichés. Tous les fragments affichant des titres qui sont encore dans la liste seront déplacés vers leur nouvel emplacement dans la liste, et les fragments avec des titres qui ne sont plus du tout dans la liste seront détruits.
Que se passe-t-il si le fragment n'a pas été recréé, mais doit quand même être mis à jour? Les mises à jour d'un fragment vivant sont mieux traitées par le fragment lui-même. C'est l'avantage d'avoir un fragment, après tout - c'est son propre contrôleur. Un fragment peut ajouter un auditeur ou un observateur à un autre objet dans onCreate()
, puis le supprimer dans onDestroy()
, en gérant ainsi les mises à jour. Vous n'avez pas besoin de mettre tout le code de mise à jour dans getItem()
comme vous le faites dans un adaptateur pour un type ListView ou un autre type AdapterView.
Une dernière chose - le fait que FragmentPagerAdapter ne détruit pas un fragment ne signifie pas que getItemPosition est totalement inutile dans un FragmentPagerAdapter. Vous pouvez toujours utiliser ce rappel pour réorganiser vos fragments dans ViewPager. Cependant, il ne les supprimera jamais complètement de FragmentManager.
Au lieu de renvoyer POSITION_NONE
à partir de getItemPosition()
et de provoquer une reconstitution de vue complète, procédez comme suit:
//call this method to update fragments in ViewPager dynamically
public void update(UpdateData xyzData) {
this.updateData = xyzData;
notifyDataSetChanged();
}
@Override
public int getItemPosition(Object object) {
if (object instanceof UpdateableFragment) {
((UpdateableFragment) object).update(updateData);
}
//don't return POSITION_NONE, avoid fragment recreation.
return super.getItemPosition(object);
}
Vos fragments doivent implémenter l'interface UpdateableFragment
:
public class SomeFragment extends Fragment implements
UpdateableFragment{
@Override
public void update(UpdateData xyzData) {
// this method will be called for every fragment in viewpager
// so check if update is for this fragment
if(forMe(xyzData)) {
// do whatever you want to update your UI
}
}
}
et l'interface:
public interface UpdateableFragment {
public void update(UpdateData xyzData);
}
Votre classe de données:
public class UpdateData {
//whatever you want here
}
pour ceux qui sont toujours confrontés au même problème que celui auquel je faisais face auparavant lorsque j’ai un ViewPager avec 7 fragments. la valeur par défaut pour ces fragments pour charger le contenu anglais à partir du service api mais le problème ici que je veux changer la langue à partir de l’activité paramètres et une fois terminé de l'utilisateur et charge le contenu arabe si l'utilisateur choisit l'arabe ici ce que j'ai fait pour travailler depuis la première fois
1- Vous devez utiliser FragmentStatePagerAdapter comme mentionné ci-dessus.
2-on mainActivity i remplacer le onResume et fait ce qui suit
if (!(mPagerAdapter == null)) {
mPagerAdapter.notifyDataSetChanged();
}
3-i a remplacé getItemPosition () dans mPagerAdapter et lui a renvoyé POSITION_NONE.
@Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
fonctionne comme un charme
J'ai rencontré ce problème et l'ai finalement résolu aujourd'hui, alors j'écris ce que j'ai appris et j'espère que cela sera utile pour quelqu'un qui est nouveau sur la version ViewPager
d'Android et qu'il met à jour comme je le fais. J'utilise FragmentStatePagerAdapter
dans l'API de niveau 17 et je n'ai actuellement que 2 fragments. Je pense qu'il doit y avoir quelque chose de pas correct, corrigez-moi, merci .
Les données sérialisées doivent être chargées en mémoire. Cela peut être fait avec un CursorLoader
/AsyncTask
/Thread
. Le chargement automatique dépend de votre code. Si vous utilisez un CursorLoader
, il est chargé automatiquement car il existe un observateur de données enregistré.
Une fois que vous avez appelé viewpager.setAdapter(pageradapter)
, la fonction getCount()
de l'adaptateur est appelée en permanence pour générer des fragments. Ainsi, si des données sont en cours de chargement, getCount()
peut renvoyer 0, vous n'avez donc pas besoin de créer de fragments factices pour aucune donnée affichée.
Une fois les données chargées, l'adaptateur ne crée pas de fragments automatiquement car getCount()
est toujours égal à 0. Nous pouvons donc définir le numéro des données réellement chargées à renvoyer par getCount()
, puis appeler le notifyDataSetChanged()
de l'adaptateur. ViewPager
commence à créer des fragments (uniquement les 2 premiers fragments) à l'aide de données en mémoire. C'est fait avant que notifyDataSetChanged()
soit retourné. Alors le ViewPager
a les bons fragments dont vous avez besoin.
Si les données de la base de données et de la mémoire sont toutes les deux mises à jour (écriture continue), ou si seules les données en mémoire le sont (écriture arrière), ou si seules les données de la base de données sont mises à jour. Dans les deux derniers cas, si les données ne sont pas automatiquement chargées de la base de données dans la mémoire (comme indiqué ci-dessus) . L'adaptateur ViewPager
et le pager traitent uniquement les données en mémoire.
Ainsi, lorsque les données en mémoire sont mises à jour, il suffit d'appeler la fonction notifyDataSetChanged()
de l'adaptateur. Étant donné que le fragment est déjà créé, la fonction onItemPosition()
de l'adaptateur sera appelée avant le retour de notifyDataSetChanged()
. Rien ne doit être fait dans getItemPosition()
. Ensuite, les données sont mises à jour.
Essayez destroyDrawingCache()
sur ViewPager après notifyDataSetChanged()
dans votre code.
Après des heures de frustration en essayant toutes les solutions ci-dessus pour surmonter ce problème et en essayant de nombreuses solutions sur d'autres questions similaires, telles que ceci , ceci et ceci que tous ont échoué avec moi pour résoudre ce problème. et faire en sorte que ViewPager
détruise l'ancien Fragment
et remplisse pager
par le nouveau Fragment
s. J'ai résolu le problème comme suit:
1) Transforme la classe ViewPager
en extension FragmentPagerAdapter
comme suit:
public class myPagerAdapter extends FragmentPagerAdapter {
2) Créez un élément pour la ViewPager
qui stocke la title
et la fragment
comme suit:
public class PagerItem {
private String mTitle;
private Fragment mFragment;
public PagerItem(String mTitle, Fragment mFragment) {
this.mTitle = mTitle;
this.mFragment = mFragment;
}
public String getTitle() {
return mTitle;
}
public Fragment getFragment() {
return mFragment;
}
public void setTitle(String mTitle) {
this.mTitle = mTitle;
}
public void setFragment(Fragment mFragment) {
this.mFragment = mFragment;
}
}
3) Demander au constructeur de ViewPager
de prendre mon instance FragmentManager
pour la stocker dans ma class
comme suit:
private FragmentManager mFragmentManager;
private ArrayList<PagerItem> mPagerItems;
public MyPagerAdapter(FragmentManager fragmentManager, ArrayList<PagerItem> pagerItems) {
super(fragmentManager);
mFragmentManager = fragmentManager;
mPagerItems = pagerItems;
}
4) Créez une méthode pour redéfinir les données adapter
avec les nouvelles données en supprimant toute la précédente fragment
de la fragmentManager
elle-même afin que la adapter
définisse à nouveau la nouvelle fragment
de la nouvelle liste comme suit:
public void setPagerItems(ArrayList<PagerItem> pagerItems) {
if (mPagerItems != null)
for (int i = 0; i < mPagerItems.size(); i++) {
mFragmentManager.beginTransaction().remove(mPagerItems.get(i).getFragment()).commit();
}
mPagerItems = pagerItems;
}
5) Dans le conteneur Activity
ou Fragment
, ne réinitialisez pas l'adaptateur avec les nouvelles données. Définissez les nouvelles données à l'aide de la méthode setPagerItems
avec les nouvelles données comme suit:
ArrayList<PagerItem> pagerItems = new ArrayList<PagerItem>();
pagerItems.add(new PagerItem("Fragment1", new MyFragment1()));
pagerItems.add(new PagerItem("Fragment2", new MyFragment2()));
mPagerAdapter.setPagerItems(pagerItems);
mPagerAdapter.notifyDataSetChanged();
J'espère que ça aide.
Pour une raison quelconque, aucune des réponses ne fonctionnait pour moi, alors j'ai dû remplacer la méthode restoreState sans appeler super dans fragmentStatePagerAdapter. Code:
private class MyAdapter extends FragmentStatePagerAdapter {
// [Rest of implementation]
@Override
public void restoreState(Parcelable state, ClassLoader loader) {}
}
J'ai légèrement modifié la solution fournie par Bill Phillips pour répondre à mes besoins
private class PagerAdapter extends FragmentStatePagerAdapter{
Bundle oBundle;
FragmentManager oFragmentManager;
ArrayList<Fragment> oPooledFragments;
public PagerAdapter(FragmentManager fm) {
super(fm);
oFragmentManager=fm;
}
@Override
public int getItemPosition(Object object) {
Fragment oFragment=(Fragment)object;
oPooledFragments=new ArrayList<>(oFragmentManager.getFragments());
if(oPooledFragments.contains(oFragment))
return POSITION_NONE;
else
return POSITION_UNCHANGED;
}
}
de sorte que la getItemPosition()
renvoie POSITION_NONE
uniquement pour les fragments qui se trouvent actuellement dans la variable FragmentManager
lorsque la variable getItemPosition
est appelée . (Notez que cette FragmentStatePager
et la ViewPager
associée à il est contenu dans un fragment pas dans une activité)
J'avais un problème similaire mais je ne voulais pas faire confiance aux solutions existantes (noms de balises codées en dur, etc.) et je ne pouvais pas utiliser la solution de M-WaJeEh pour moi. Voici ma solution:
Je garde des références aux fragments créés dans getItem dans un tableau. Cela fonctionne bien tant que l'activité n'est pas détruite pour des raisons de configuration. Changement ou manque de mémoire ou autre (-> lors du retour à l'activité, les fragments reviennent à leur dernier état sans que 'getItem' soit appelé à nouveau et donc sans mettre à jour le tableau ).
Pour éviter ce problème, j'ai implémenté instantiateItem (ViewGroup, int) et mis à jour mon tableau là-bas, comme ceci:
@Override
public Object instantiateItem(ViewGroup container, int position) {
Object o = super.instantiateItem(container, position);
if(o instanceof FragmentX){
myFragments[0] = (FragmentX)o;
}else if(o instanceof FragmentY){
myFragments[1] = (FragmentY)o;
}else if(o instanceof FragmentZ){
myFragments[2] = (FragmentZ)o;
}
return o;
}
Donc, d’un côté, je suis heureux d’avoir trouvé une solution qui marche pour moi et que je veuille la partager avec vous, mais je voulais aussi demander si quelqu'un d’autre avait essayé quelque chose de similaire et s’il y avait une raison pour que je ne devrais pas le faire. le faire comme ça? Jusqu'à présent, cela fonctionne très bien pour moi ...
J'ai vécu le même problème et j'ai cherché trop de fois. Toute réponse donnée dans stackoverflow ou via google n’était pas une solution à mon problème. Mon problème était facile. J'ai une liste, je montre cette liste avec viewpager. Lorsque j'ajoute un nouvel élément en tête de la liste et que j'actualise les remarques du viewpager. Ma solution finale était très facile à utiliser. Lorsqu'un nouvel élément est ajouté à la liste et que vous souhaitez l'actualiser. Définissez d'abord l'adaptateur viewpager sur null, puis recréez l'adaptateur et définissez-y sur viewpager.
myVPager.setAdapter(null);
myFragmentAdapter = new MyFragmentAdapter(getSupportFragmentManager(),newList);
myVPager.setAdapter(myFragmentAdapter);
Assurez-vous que votre adaptateur doit étendre FragmentStatePagerAdapter
Si vous souhaitez utiliser FragmentStatePagerAdapter, consultez https://code.google.com/p/Android/issues/detail?can=2&start=0&num=100&q=&colspec=ID%20Type%20Status%20Owner% 20Summary% 20Stars & groupby = & sort = & id = 37990 . Il existe des problèmes avec FragmentStatePagerAdapter qui peuvent ou non gêner votre cas d'utilisation.
En outre, le lien a peu de solutions aussi .. peu peut convenir à votre condition.
J'utilise EventBus library pour mettre à jour le contenu Fragment
dans ViewPager
. La logique est simple, tout comme le document de EventBus comment procéder . Il n'est pas nécessaire de contrôler l'instance FragmentPagerAdapter
. Le code est ici:
1: Définir les événements
Définissez le message à mettre à jour.
public class UpdateCountEvent {
public final int count;
public UpdateCountEvent(int count) {
this.count = count;
}
}
2.Préparer des abonnés
Ecrivez ci-dessous le code dans le fragment qui doit être mis à jour.
@Override
public void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
@Override
public void onStop() {
EventBus.getDefault().unregister(this);
super.onStop();
}
public void onEvent(UpdateCountEvent event) {//get update message
Toast.makeText(getActivity(), event.count, Toast.LENGTH_SHORT).show();
}
3. événements postérieurs
Ecrivez ci-dessous le code dans une autre variable Activity
ou Fragment
qui doit mettre à jour le paramètre
//input update message
EventBus.getDefault().post(new UpdateCountEvent(count));
Je sais que je suis en retard pour le parti. J'ai résolu le problème en appelant TabLayout#setupWithViewPager(myViewPager);
juste après FragmentPagerAdapter#notifyDataSetChanged();
Cela pourrait être utile à quelqu'un - dans mon cas, lors de l'insertion d'une nouvelle page, le pager de vue demandait deux fois la position d'un fragment existant, mais ne demandait pas la position du nouvel élément, ce qui entraînait un comportement incorrect et l'absence d'affichage des données.
Copiez le source pour FragmentStatePagerAdapter (semble ne pas avoir été mis à jour depuis des lustres).
Remplacer notifyDataSetChanged ()
@Override
public void notifyDataSetChanged() {
mFragments.clear();
super.notifyDataSetChanged();
}
Ajoutez un contrôle de cohérence à destroyItem () pour éviter les plantages:
if (position < mFragments.size()) {
mFragments.set(position, null);
}
Voici mon implémentation qui intègre les informations de @Bill PhillipsOne obtient la plupart du temps la mise en cache des fragments, sauf lorsque les données ont changé. Simple et semble bien fonctionner.
MyFragmentStatePagerAdapter.Java
private boolean mIsUpdating = false;
public void setIsUpdating(boolean mIsUpdating) {
this.mIsUpdating = mIsUpdating;
}
@Override
public int getItemPosition(@NonNull Object object) {
if (mIsUpdating) {
return POSITION_NONE;
}
else {
return super.getItemPosition(object);
}
}
MyActivity.Java
mAdapter.setIsUpdating(true);
mAdapter.notifyDataSetChanged();
mAdapter.setIsUpdating(false);
J'ai parcouru toutes les réponses ci-dessus et un certain nombre d'autres publications, mais je n'ai toujours pas trouvé quelque chose qui fonctionnait pour moi (avec différents types de fragments, avec l'ajout et la suppression dynamiques d'onglets). L’approche suivante de FWIW est ce qui a fonctionné pour moi (au cas où quelqu'un aurait les mêmes problèmes).
public class MyFragmentStatePageAdapter extends FragmentStatePagerAdapter {
private static final String TAB1_TITLE = "Tab 1";
private static final String TAB2_TITLE = "Tab 2";
private static final String TAB3_TITLE = "Tab 3";
private ArrayList<String> titles = new ArrayList<>();
private Map<Fragment, Integer> fragmentPositions = new HashMap<>();
public MyFragmentStatePageAdapter(FragmentManager fm) {
super(fm);
}
public void update(boolean showTab1, boolean showTab2, boolean showTab3) {
titles.clear();
if (showTab1) {
titles.add(TAB1_TITLE);
}
if (showTab2) {
titles.add(TAB2_TITLE);
}
if (showTab3) {
titles.add(TAB3_TITLE);
}
notifyDataSetChanged();
}
@Override
public int getCount() {
return titles.size();
}
@Override
public Fragment getItem(int position) {
Fragment fragment = null;
String tabName = titles.get(position);
if (tabName.equals(TAB1_TITLE)) {
fragment = Tab1Fragment.newInstance();
} else if (tabName.equals(TAB2_TITLE)) {
fragment = Tab2Fragment.newInstance();
} else if (tabName.equals(TAB3_TITLE)) {
fragment = Tab3Fragmen.newInstance();
}
((BaseFragment)fragment).setTitle(tabName);
fragmentPositions.put(fragment, position);
return fragment;
}
@Override
public CharSequence getPageTitle(int position) {
return titles.get(position);
}
@Override
public int getItemPosition(Object item) {
BaseFragment fragment = (BaseFragment)item;
String title = fragment.getTitle();
int position = titles.indexOf(title);
Integer fragmentPosition = fragmentPositions.get(item);
if (fragmentPosition != null && position == fragmentPosition) {
return POSITION_UNCHANGED;
} else {
return POSITION_NONE;
}
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
super.destroyItem(container, position, object);
fragmentPositions.remove(object);
}
}
Utilisez FragmentStatePagerAdapter au lieu de FragmentPagerAdapter Si vous souhaitez recréer ou recharger un fragment sur une base d'index Par exemple, si vous souhaitez recharger un fragment autre que FirstFragment, vous pouvez vérifier l'instance et la position renvoyée de la manière suivante
public int getItemPosition(Object item) {
if(item instanceof FirstFragment){
return 0;
}
return POSITION_NONE;
}
Cette solution ne fonctionnera pas pour tout le monde, mais dans mon cas, chaque fragment de mon ViewPager est une classe différente et un seul d'entre eux existe à la fois.
Avec cette contrainte, cette solution est sûre et devrait pouvoir être utilisée en production en toute sécurité.
private void updateFragment(Item item) {
List<Fragment> fragments = getSupportFragmentManager().getFragments();
for (Fragment fragment : fragments) {
if (fragment instanceof MyItemFragment && fragment.isVisible()) {
((MyItemFragment) fragment).update(item);
}
}
}
Si vous avez plusieurs versions du même fragment, vous pouvez utiliser cette même stratégie pour appeler des méthodes sur ces fragments afin de déterminer s'il s'agit du fragment que vous souhaitez mettre à jour.
J'avais essayé tellement d'approches différentes, aucune ne réglait vraiment mon problème. Voici comment je le résous avec un mélange de solutions fournies par vous tous. Merci tout le monde.
class PagerAdapter extends FragmentPagerAdapter {
public boolean flag_refresh=false;
public PagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int page) {
FragmentsMain f;
f=new FragmentsMain();
f.page=page;
return f;
}
@Override
public int getCount() {
return 4;
}
@Override
public int getItemPosition(Object item) {
int page= ((FragmentsMain)item).page;
if (page == 0 && flag_refresh) {
flag_refresh=false;
return POSITION_NONE;
} else {
return super.getItemPosition(item);
}
}
@Override
public void destroyItem(View container, int position, Object object) {
((ViewPager) container).removeView((View) object);
}
}
Je veux seulement actualiser la page 0 après onResume ().
adapter=new PagerAdapter(getSupportFragmentManager());
pager.setAdapter(adapter);
@Override
protected void onResume() {
super.onResume();
if (adapter!=null) {
adapter.flag_refresh=true;
adapter.notifyDataSetChanged();
}
}
Dans mon FragmentsMain, il existe un entier public "page" qui peut me dire si c'est la page que je veux actualiser.
public class FragmentsMain extends Fragment {
private Cursor cursor;
private static Context context;
public int page=-1;