Mise à jour des données dans ListFragment dans le cadre de ViewPager
Je suis en utilisant la v4 compatibilité ViewPager dans Android. Mon FragmentActivity a un tas de données qui doivent être affichés de différentes manières sur les différentes pages de mon ViewPager. Jusqu'à présent j'ai juste 3 instances de la même ListFragment, mais dans le futur, je vais avoir 3 instances de différents ListFragments. Le ViewPager est sur une verticale de l'écran du téléphone, les listes ne sont pas côte à côte.
Maintenant un bouton sur le ListFragment commence un distinct en pleine page de l'activité (via le FragmentActivity), qui retourne et FragmentActivity modifie les données, il enregistre, puis tente de mettre à jour toutes les vues de son ViewPager. C'est ici, où je suis coincé.
public class ProgressMainActivity extends FragmentActivity
{
MyAdapter mAdapter;
ViewPager mPager;
@Override
public void onCreate(Bundle savedInstanceState)
{
...
mAdapter = new MyAdapter(getSupportFragmentManager());
mPager = (ViewPager) findViewById(R.id.viewpager);
mPager.setAdapter(mAdapter);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
...
updateFragments();
...
}
public void updateFragments()
{
//Attempt 1:
//mAdapter.notifyDataSetChanged();
//mPager.setAdapter(mAdapter);
//Attempt 2:
//HomeListFragment fragment = (HomeListFragment) getSupportFragmentManager().findFragmentById(mAdapter.fragId[0]);
//fragment.updateDisplay();
}
public static class MyAdapter extends FragmentPagerAdapter implements
TitleProvider
{
int[] fragId = {0,0,0,0,0};
public MyAdapter(FragmentManager fm)
{
super(fm);
}
@Override
public String getTitle(int position){
return titles[position];
}
@Override
public int getCount(){
return titles.length;
}
@Override
public Fragment getItem(int position)
{
Fragment frag = HomeListFragment.newInstance(position);
//Attempt 2:
//fragId[position] = frag.getId();
return frag;
}
@Override
public int getItemPosition(Object object) {
return POSITION_NONE; //To make notifyDataSetChanged() do something
}
}
public class HomeListFragment extends ListFragment
{
...
public static HomeListFragment newInstance(int num)
{
HomeListFragment f = new HomeListFragment();
...
return f;
}
...
Maintenant, comme vous pouvez le voir, ma première tentative a été de notifyDataSetChanged sur l'ensemble de la FragmentPagerAdapter, et cela a montré à mettre à jour les données parfois, mais d'autres, j'ai eu une IllegalStateException: vous ne Pouvez pas effectuer cette action après onSaveInstanceState.
Ma deuxième tentative involed vous essayez d'appeler une fonction de mise à jour dans mon ListFragment, mais getId dans getItem retourné 0. Selon les docs que j'ai essayé par
l'acquisition d'une référence pour le Fragment de la FragmentManager, à l'aide de
findFragmentById() ou findFragmentByTag()
mais je ne sais pas la marque ou de l'id de mes Fragments! J'ai un android:id="@+id/viewpager" pour ViewPager, et un android:id="@android:id/liste" pour ma ListView dans le ListFragment mise en page, mais je ne pense pas qu'ils sont utiles.
Donc, comment je peux soit:
a) mise à jour de l'ensemble de la ViewPager en toute sécurité dans un aller (idéalement retour de l'utilisateur à la page qu'il était avant) - il est ok pour l'utilisateur de voir le changement de vue.
Ou, de préférence,
b) l'appel d'une fonction dans chaque ListFragment pour mettre à jour la liste manuellement.
Toute aide serait très appréciée!
Vous devez vous connecter pour publier un commentaire.
Essayez d'enregistrer le tag à chaque fois qu'un Fragement est instancié.
null
pour fragment.FragmentPagerAdapter
et (je pense)FragmentStatePagerAdapter
. En outre, il ne permet pas de contenir des références à des ces fragments, de sorte qu'il permet le cadre de gestion GC, etcmakeFragmentName()
.FragmentPagerAdaper
, mais échoue pourFragmentStatePagerAdaper
(Fragment.getTag()
toujours revenirnull
.getItem
? J'ai penségetItem
a été appelé parinstantiateItem
. Dans ce cas, comment estposition
utilisé?Barkside réponse travaille avec
FragmentPagerAdapter
mais ne fonctionne pas avecFragmentStatePagerAdapter
, car il n'a pas mis de balises sur des fragments de passer àFragmentManager
.Avec
FragmentStatePagerAdapter
il semble que nous pouvons obtenir par le biais de soninstantiateItem(ViewGroup container, int position)
appel. Elle retourne la référence de fragment à la positionposition
. SiFragmentStatePagerAdapter
déjà fait référence à l'fragment en question,instantiateItem
renvoie simplement référence à ce fragment, et de ne pas faire appelgetItem()
de l'instancier à nouveau.Donc, supposons que, je suis actuellement à la recherche au fragment n ° 50, et souhaitez accéder à l'fragment n ° 49. Parce qu'elles sont proches, il ya une bonne chance que le #49 sera déjà instancié. Donc,
FragmentStatePagerAdapter
, à l'aide de code ci-dessus aveca.instantiateItem(viewPager, viewPager.getCurrentItem());
(pour se débarrasser de l'49) proposé par @mblackwell8 fonctionne parfaitement.instantiateItem
doit être entouré par desstartUpdate
/finishUpdate
appels. les détails sont dans ma réponse à une question similaire: stackoverflow.com/questions/14035090/...OK, je crois que j'ai trouvé un moyen pour effectuer la demande b) dans ma question alors je vais partager pour les autres prestations. La balise de fragments à l'intérieur d'un ViewPager est dans la forme
"android:switcher:VIEWPAGER_ID:INDEX"
, oùVIEWPAGER_ID
est leR.id.viewpager
en XML de mise en page, et l'INDICE de la position dans le viewpager. Donc, si la position est connue (par exemple 0), je peux effectuer dansupdateFragments()
:Je n'ai aucune idée si c'est un moyen valable de le faire, mais ça fera l'affaire jusqu'à ce que quelque chose de mieux est suggéré.
makeFragmentName
utilisé pour générer la Balise que vous pouvez utiliser à la place pour un peu-moins-hacky approche:HomeListFragment fragment = (HomeListFragment) getSupportFragmentManager().findFragmentByTag(FragmentPagerAdapter.makeFragmentName(R.id.viewpager, 0));
private static
méthode, vous ne pouvez donc pas y avoir accès.Si vous me demandez, la deuxième solution sur la page ci-dessous, en gardant la trace de tous les "actifs" fragment de pages, c'est mieux: http://tamsler.blogspot.nl/2011/11/android-viewpager-and-fragments-part-ii.html
La réponse de barkside est trop hacky pour moi.
vous de garder une trace de tous les "actifs" fragment de pages. Dans ce cas, vous conservez la trace du fragment pages dans la FragmentStatePagerAdapter, qui est utilisé par le ViewPager.
Pour éviter de conserver une référence à "inactif" fragment de pages, nous avons besoin de mettre en œuvre la FragmentStatePagerAdapter de destroyItem(...) méthode:
... et quand vous en avez besoin pour accéder à la page actuellement visible, vous appelez:
... où le MyAdapter de getFragment(int) méthode ressemble à ceci:
"
Bon, après avoir testé la méthode par @barkside ci-dessus, je ne pouvais pas le faire fonctionner avec mon application. Puis je me suis souvenu que le IOSched2012 app utilise un
viewpager
ainsi, et c'est là que j'ai trouvé ma solution. Il n'utilise pas de fragment de cartes d'identité ou des Balises que ce ne sont pas stockées parviewpager
d'une manière aisément accessible.Voici la les parties importantes de la IOSched apps HomeActivity. Payer une attention particulière à la commentaire, que là se trouve la clef.:
Et stocker les instances de vous
Fragments
dans leFragmentPagerAdapter
comme suit:Aussi, n'oubliez pas de protéger votre
Fragment
appelle comme ça:getItem()
pas être appelée après que le parent est recréé en raison d'un changement du cycle de vie. Voir stackoverflow.com/a/24662049/236743. Dans l'exemple, c'est en partie en garde contre pour un fragment, mais pas les deux autresVous pouvez copier
FragmentPagerAdapter
et de modifier le code source, ajoutergetTag()
méthodepar exemple
puis l'étendre, remplacer ces méthode abstraite,n'ont pas besoin d'avoir peur de Android de changement de Groupe
FragmentPageAdapter
code source dans le futurFonctionne aussi sans problèmes:
quelque part dans le fragment de page la mise en page:
dans le fragment de la onCreateView():
et méthode pour retourner un Fragment de ViewPager, s'il en existe un:
Alternativement, vous pouvez remplacer
setPrimaryItem
méthode deFragmentPagerAdapter
comme suit:Je veux donner à mon approche dans le cas où il peut aider quelqu'un d'autre:
C'est mon téléavertisseur adaptateur:
Dans mon activité, j'ai:
Ensuite pour obtenir le courant fragment de ce que je fais, c'est:
C'est ma solution, car je n'ai pas besoin de garder une trace de mes onglets et de la nécessité d'actualiser tous de toute façon.