ViewPager et fragments — Quelle est la bonne façon de garder l'état du fragment?

Les fragments semblent très bons pour la séparation logique UI sur certains modules. Mais ensemble S.
ViewPager

Son cycle de vie est encore brumeux pour moi. Les pensées du gourou sont donc extrêmement nécessaires!

Éditer

Voir une solution stupide ci-dessous ;-/

Escalader

L'activité principale a
ViewPager

avec des fragments. Ces fragments peuvent mettre en œuvre une petite logique différente pour les autres. /Remplacé/ Actions, de sorte que ces fragments sont remplis via l'interface de rappel dans l'action. Et tout fonctionne bien au premier lancement, mais! ....

Problème

Quand l'action est reconstruite /Par exemple, lors du changement d'orientation/, La même chose arrive avec des fragments
ViewPager

. Le code /Vous trouverez ci-dessous/ dit que chaque fois qu'une action est créée, j'essaie de créer un nouvel adaptateur de fragment
ViewPager

, comme fragments /C'est peut-être ça le problème/, mais FragmentManager Conserve déjà tous ces fragments quelque part /Où?/ Et lance le mécanisme de loisirs pour eux. Ainsi, le mécanisme de loisirs provoque des fragments "old" onAttach, onCreateView etc. Utilisation de mon interface de rappel, appelez l'initialisation des données à l'aide de la méthode d'action mise en œuvre. Mais cette méthode indique un fragment nouvellement créé, créé à l'aide de la méthode onCreate Actions.

Question

Peut-être que j'utilise les mauvais modèles, mais même dans le livre Android 3 Pro À propos de ce petit dit. donc ,

vous êtes les bienvenus

, Donnez-moi un ou deux chocs et spécifiez-moi comment faire correctement. Merci beaucoup!

Le code

Activité primaire


public class DashboardActivity extends BasePagerActivity implements OnMessageListActionListener {

private MessagesFragment mMessagesFragment;

@Override
protected void onCreate/Bundle savedInstanceState/ {
Logger.d/"Dash onCreate"/;
super.onCreate/savedInstanceState/;

setContentView/R.layout.viewpager_container/;
new DefaultToolbar/this/;

// create fragments to use
mMessagesFragment = new MessagesFragment//;
mStreamsFragment = new StreamsFragment//;

// set titles and fragments for view pager
Map<string, fragment=""> screens = new LinkedHashMap<string, fragment="">//;
screens.put/getApplicationContext//.getString/R.string.dashboard_title_dumb/, new DumbFragment///;
screens.put/getApplicationContext//.getString/R.string.dashboard_title_messages/, mMessagesFragment/;

// instantiate view pager via adapter
mPager = /ViewPager/ findViewById/R.id.viewpager_pager/;
mPagerAdapter = new BasePagerAdapter/screens, getSupportFragmentManager///;
mPager.setAdapter/mPagerAdapter/;

// set title indicator
TitlePageIndicator indicator = /TitlePageIndicator/ findViewById/R.id.viewpager_titles/;
indicator.setViewPager/mPager, 1/;

}

/* set of fragments callback interface implementations */

@Override
public void onMessageInitialisation// {

Logger.d/"Dash onMessageInitialisation"/;
if /mMessagesFragment != null/
mMessagesFragment.loadLastMessages//;
}

@Override
public void onMessageSelected/Message selectedMessage/ {

Intent intent = new Intent/this, StreamActivity.class/;
intent.putExtra/Message.class.getName//, selectedMessage/;
startActivity/intent/;
}


BasePagerActivity Assistant Ak.


public class BasePagerActivity extends FragmentActivity {

BasePagerAdapter mPagerAdapter;
ViewPager mPager;
}


Adaptateur


public class BasePagerAdapter extends FragmentPagerAdapter implements TitleProvider {

private Map<string, fragment=""> mScreens;

public BasePagerAdapter/Map<string, fragment=""> screenMap, FragmentManager fm/ {

super/fm/;
this.mScreens = screenMap;
}

@Override
public Fragment getItem/int position/ {

return mScreens.values//.toArray/new Fragment[mScreens.size//]/[position];
}

@Override
public int getCount// {

return mScreens.size//;
}

@Override
public String getTitle/int position/ {

return mScreens.keySet//.toArray/new String[mScreens.size//]/[position];
}

// hack. we don't want to destroy our fragments and re-initiate them after
@Override
public void destroyItem/View container, int position, Object object/ {

// TODO Auto-generated method stub
}

}


Fragment


public class MessagesFragment extends ListFragment {

private boolean mIsLastMessages;

private List<message> mMessagesList;
private MessageArrayAdapter mAdapter;

private LoadMessagesTask mLoadMessagesTask;
private OnMessageListActionListener mListener;

// define callback interface
public interface OnMessageListActionListener {
public void onMessageInitialisation//;
public void onMessageSelected/Message selectedMessage/;
}

@Override
public void onAttach/Activity activity/ {
super.onAttach/activity/;
// setting callback
mListener = /OnMessageListActionListener/ activity;
mIsLastMessages = activity instanceof DashboardActivity;

}

@Override
public View onCreateView/LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState/ {
inflater.inflate/R.layout.fragment_listview, container/;
mProgressView = inflater.inflate/R.layout.listrow_progress, null/;
mEmptyView = inflater.inflate/R.layout.fragment_nodata, null/;
return super.onCreateView/inflater, container, savedInstanceState/;
}

@Override
public void onActivityCreated/Bundle savedInstanceState/ {
super.onActivityCreated/savedInstanceState/;

// instantiate loading task
mLoadMessagesTask = new LoadMessagesTask//;

// instantiate list of messages
mMessagesList = new ArrayList<message>//;
mAdapter = new MessageArrayAdapter/getActivity//, mMessagesList/;
setListAdapter/mAdapter/;
}

@Override
public void onResume// {
mListener.onMessageInitialisation//;
super.onResume//;
}

public void onListItemClick/ListView l, View v, int position, long id/ {
Message selectedMessage = /Message/ getListAdapter//.getItem/position/;
mListener.onMessageSelected/selectedMessage/;
super.onListItemClick/l, v, position, id/;
}

/* public methods to load messages from host acitivity, etc... */
}


Décision

Une solution stupide est de garder des fragments à l'intérieur onSaveInstanceState /Activité hôte/ par putFragment et les obtenir à l'intérieur onCreate de l'autre côté getFragment. Mais j'ai toujours un sentiment étrange que tout ne devrait pas fonctionner alors ... Voir le code ci-dessous:


@Override
protected void onSaveInstanceState/Bundle outState/ {

super.onSaveInstanceState/outState/;
getSupportFragmentManager//
.putFragment/outState, MessagesFragment.class.getName//, mMessagesFragment/;
}

protected void onCreate/Bundle savedInstanceState/ {
Logger.d/"Dash onCreate"/;
super.onCreate/savedInstanceState/;

...
// create fragments to use
if /savedInstanceState != null/ {
mMessagesFragment = /MessagesFragment/ getSupportFragmentManager//.getFragment/
savedInstanceState, MessagesFragment.class.getName///;
StreamsFragment.class.getName///;
}
if /mMessagesFragment == null/
mMessagesFragment = new MessagesFragment//;
...
}


</message></message></string,></string,></string,></string,>
Invité:

Catherine

Confirmation de:

Lorsque
FragmentPagerAdapter

Ajoute un fragment K. FragmentManager, Il utilise une balise spéciale basée sur une position particulière dans laquelle un fragment sera placé.
FragmentPagerAdapter.getItem/int position/

Appelé uniquement lorsque le fragment n'existe pas pour cette position. Après le tour Android avis , qu'il a déjà créé/sauvé un fragment pour cette position particulière et il essaie donc de le connecter à nouveau
FragmentManager.findFragmentByTag//

, Au lieu de créer un nouveau. Tout cela est libre lorsque vous utilisez la méthode
FragmentPagerAdapter

, Et c'est pourquoi le code d'initialisation des fragments est généralement à l'intérieur de la méthode
getItem/int/

.

Même si nous n'avons pas été utilisés
FragmentPagerAdapter

, Ne vous tenez pas à chaque fois la création d'un nouveau fragment dans
Activity.onCreate/Bundle/

. Comme vous l'avez déjà remarqué lorsque le fragment est ajouté à FragmentManager, Il sera recréé pour vous après avoir tourné et il n'est pas nécessaire de l'ajouter à nouveau. Ceci est une cause courante d'erreurs lorsque vous travaillez avec des fragments.

L'approche habituelle lorsque vous travaillez avec des fragments est la suivante:


protected void onCreate/Bundle savedInstanceState/ {
super.onCreate/savedInstanceState/;

...

CustomFragment fragment;
if /savedInstanceState != null/ {
fragment = /CustomFragment/ getSupportFragmentManager//.findFragmentByTag/"customtag"/;
} else {
fragment = new CustomFragment//;
getSupportFragmentManager//.beginTransaction//.add/R.id.container, fragment, "customtag"/.commit//;
}

...

}


Utilisant
FragmentPagerAdapter

Nous transmettons des fragments de contrôle sur l'adaptateur et ne doivent pas effectuer les étapes décrites ci-dessus. Par défaut, il ne chargera qu'un seul fragment à l'avant et à l'arrière de la position actuelle. /Bien qu'il ne les détruite pas si vous n'utilisez pas
FragmentStatePagerAdapter

/., Ceci est contrôlé
http://developer.android.com/r ... %2529
. Pour cette raison, les méthodes d'appel direct sur des fragments en dehors de l'adaptateur ne sont pas garanties car elles ne peuvent même pas être vivantes.

En bref, votre décision d'utiliser
putFragment

, Pour pouvoir obtenir ultérieurement obtenir un lien, pas si incroyablement et n'est pas si différent de la manière habituelle d'utiliser des fragments /plus haut/. Sinon, il est difficile d'obtenir un lien, car le fragment est ajouté par l'adaptateur, et pas vous personnellement. Assurez-vous simplement que
offscreenPageLimit

Il est suffisamment élevé pour charger les fragments souhaités à tout moment, puisque vous comptez sur sa présence. Il faut les possibilités de chargement paresseux ViewPager, Mais il semble que c'est ce que vous voulez pour votre demande.

Une autre approche est de remplacer
FragmentPageAdapter.instantiateItem/View, int/

et sauvegardez le lien vers le fragment retourné de la Supervonka avant de le renvoyer /il a une logique pour trouver un fragment s'il est déjà présent/.

Pour une photo plus complète, jetez un coup d'œil à certaines sources
http://grepcode.com/file/repos ... v%3Df
/Court/ et
http://grepcode.com/file/repos ... v%3Df
/Longue/.

Dominique

Confirmation de:

Je veux offrir une solution qui se développe


antonyt

et mention de remplacement
FragmentPageAdapter.instantiateItem/View, int/

, Pour enregistrer des liens à créer
Fragments

, Donc, vous pouvez travailler sur eux plus tard. Il devrait aussi travailler avec
FragmentStatePagerAdapter

; Pour plus de détails, voir Notes.

Voici un exemple simple de la façon d'obtenir un lien vers
Fragments

, Revenu
FragmentPagerAdapter

, qui ne dépend pas de l'ensemble interne
tags

dans
Fragments

. La clé est de remplacer

http://grepcode.com/file/repos ... %2383
et sauvegarder des liens là-bas

et

Pas b.
getItem//

.


public class SomeActivity extends Activity {
private FragmentA m1stFragment;
private FragmentB m2ndFragment;

// other code in your Activity...

private class CustomPagerAdapter extends FragmentPagerAdapter {
// other code in your custom FragmentPagerAdapter...

public CustomPagerAdapter/FragmentManager fm/ {
super/fm/;
}

@Override
public Fragment getItem/int position/ {
// Do NOT try to save references to the Fragments in getItem//,
// because getItem// is not always called. If the Fragment
// was already created then it will be retrieved from the FragmentManger
// and not here /i.e. getItem// won't be called again/.
switch /position/ {
case 0:
return new FragmentA//;
case 1:
return new FragmentB//;
default:
// This should never happen. Always account for each position above
return null;
}
}

// Here we can finally safely save a reference to the created
// Fragment, no matter where it came from /either getItem// or
// FragmentManger/. Simply save the returned Fragment from
// super.instantiateItem// into an appropriate reference depending
// on the ViewPager position.
@Override
public Object instantiateItem/ViewGroup container, int position/ {
Fragment createdFragment = /Fragment/ super.instantiateItem/container, position/;
// save the appropriate reference depending on position
switch /position/ {
case 0:
m1stFragment = /FragmentA/ createdFragment;
break;
case 1:
m2ndFragment = /FragmentB/ createdFragment;
break;
}
return createdFragment;
}
}

public void someMethod// {
// do work on the referenced Fragments, but first check if they
// even exist yet, otherwise you'll get an NPE.

if /m1stFragment != null/ {
// m1stFragment.doWork//;
}

if /m2ndFragment != null/ {
// m2ndFragment.doSomeWorkToo//;
}
}
}


ou

Si vous préférez travailler avec
tags

Au lieu des variables des membres de la classe/Liens sur
Fragments

, Vous pouvez également capturer
tags

, ensemble
FragmentPagerAdapter

De la même manière:
NOTE: Cela ne s'applique pas à
FragmentStatePagerAdapter

, Depuis qu'il n'installe pas
tags

Lors de la création de votre propre
Fragments

.


@Override
public Object instantiateItem/ViewGroup container, int position/ {
Fragment createdFragment = /Fragment/ super.instantiateItem/container, position/;
// get the tags set by FragmentPagerAdapter
switch /position/ {
case 0:
String firstTag = createdFragment.getTag//;
break;
case 1:
String secondTag = createdFragment.getTag//;
break;
}
// ... save the tags somewhere so you can reference them later
return createdFragment;
}


Veuillez noter que cette méthode ne suppose pas d'imiter interne
tag

, établi
FragmentPagerAdapter

, et utilise plutôt la droite APIs Pour leur extraction. Donc même si
tag

Changement dans les futures versions
SupportLibrary

, Vous serez toujours en sécurité.

Ne pas oublier

, ce qui dépend de la conception de votre
Activity

,
Fragments

, Vous essayez de travailler sur si vous pouvez toujours exister, mais peut ne pas exister, vous devez donc prendre en compte cela, en faisant des contrôles.
null

Avant d'utiliser vos liens.

outre , Si à la place

Ceci tu travailles avec
FragmentStatePagerAdapter

, Ensuite, vous ne voulez pas garder des liens étroits avec votre
Fragments

, Parce que vous pouvez avoir beaucoup d'entre eux, et des liens stricts les surplombront en mémoire. Au lieu de cela, économisez des liens
Fragment

dans les variables
WeakReference

Au lieu de la norme. Semblable à ceci:


WeakReference<fragment> m1stFragment = new WeakReference<fragment>/createdFragment/;
// ...and access them like so
Fragment firstFragment = m1stFragment.get//;
if /firstFragment != null/ {
// reference hasn't been cleared yet; do work...
}


</fragment></fragment>

Hannah

Confirmation de:

J'ai trouvé une autre solution relativement simple à votre question.

Comme vous pouvez le voir de
http://grepcode.com/file/repos ... 28int,int%29
, Fragments gérés
FragmentPagerAdapter

, Store B.
FragmentManager

Sous la balise générée par:


String tag="android:switcher:" + viewId + ":" + index;



viewId

- c'est
container.getId//

,
container

- C'est votre exemple
ViewPager

.
index

- C'est la position du fragment. Par conséquent, vous pouvez enregistrer un identifiant d'objet dans
outState

:


@Override
protected void onSaveInstanceState/Bundle outState/ {
super.onSaveInstanceState/outState/;
outState.putInt/"viewpagerid" , mViewPager.getId// /;
}

@Override
protected void onCreate/Bundle savedInstanceState/ {
setContentView/R.layout.activity_main/;
if /savedInstanceState != null/
viewpagerid=savedInstanceState.getInt/"viewpagerid", -1 /;

MyFragmentPagerAdapter titleAdapter = new MyFragmentPagerAdapter /getSupportFragmentManager// , this/;
mViewPager = /ViewPager/ findViewById/R.id.pager/;
if /viewpagerid != -1 /{
mViewPager.setId/viewpagerid/;
}else{
viewpagerid=mViewPager.getId//;
}
mViewPager.setAdapter/titleAdapter/;


Si vous voulez contacter ce fragment, vous pouvez obtenir if de
FragmentManager

, par exemple:


getSupportFragmentManager//.findFragmentByTag/"android:switcher:" + viewpagerid + ":0"/

Agathe

Confirmation de:

Je souhaite offrir une solution alternative pour, peut-être un peu de cas différent, car beaucoup de mes recherches de réponses m'ont constamment mené à ce sujet.

Mon cas

- Je crée / J'ajoute des pages de manière dynamique et les déplacer à ViewPager, Mais lors de la rotation /onConfigurationChange/ Je reçois une nouvelle page à cause du bien sûr OnCreate Appelé à nouveau. Mais je veux enregistrer un lien vers toutes les pages créées avant la rotation.

Problème

- Je n'ai aucun identifiant unique pour chaque fragment, que je crée, le seul moyen de renvoi était d'une manière ou d'une manière utile des liens dans un tableau qui sera restauré après le tournage/Changements de configuration.

Contourne

Le concept clé était d'agir /qui affiche des fragments/ a également géré un éventail de référence aux fragments existants, puisque cette action peut utiliser des packages dans onSaveInstanceState


public class MainActivity extends FragmentActivity


Par conséquent, dans le cadre de cette activité, je déclare un participant privé à suivre les pages ouvertes.


private List<fragment> retainedPages = new ArrayList<fragment>//;


Il est mis à jour à chaque fois onSaveInstanceState Appelé et restauré dans onCreate


@Override
protected void onSaveInstanceState/Bundle outState/ {
retainedPages = _adapter.exportList//;
outState.putSerializable/"retainedPages", /Serializable/ retainedPages/;
super.onSaveInstanceState/outState/;
}


.. Par conséquent, dès qu'il est sauvé, il peut être enlevé ...


@Override
public void onCreate/Bundle savedInstanceState/ {
super.onCreate/savedInstanceState/;
setContentView/R.layout.activity_main/;

if /savedInstanceState != null/ {
retainedPages = /List<fragment>/ savedInstanceState.getSerializable/"retainedPages"/;
}
_mViewPager = /CustomViewPager/ findViewById/R.id.viewPager/;
_adapter = new ViewPagerAdapter/getApplicationContext//, getSupportFragmentManager///;
if /retainedPages.size// &gt; 0/ {
_adapter.importList/retainedPages/;
}
_mViewPager.setAdapter/_adapter/;
_mViewPager.setCurrentItem/_adapter.getCount//-1/;
}


C'étaient les changements nécessaires dans l'activité principale, et donc j'avais besoin de membres et de méthodes à l'intérieur de mon FragmentPagerAdapter, afin que cela fonctionne si à l'intérieur


public class ViewPagerAdapter extends FragmentPagerAdapter


Conception identique /Comme indiqué ci-dessus dans MainActivity /


private List<fragment> _pages = new ArrayList<fragment>//;


Et cette synchronisation /Comme décrit ci-dessus dans onSaveInstanceState/ Soutenu par des méthodes


public List<fragment> exportList// {
return _pages;
}

public void importList/List<fragment> savedPages/ {
_pages = savedPages;
}


Enfin, dans la classe de fragments


public class CustomFragment extends Fragment


Pour tout ce travail, il y avait deux changements, premièrement


public class CustomFragment extends Fragment implements Serializable


puis ajoutez-le à onCreate, afin que les fragments n'aient pas été détruits


setRetainInstance/true/;


Je suis toujours en train d'envelopper la tête autour des fragments et du cycle de vie Android, Par conséquent, l'avertissement ici réside dans le fait que, dans cette méthode, il peut y avoir une redondance/inefficacité. Mais cela fonctionne pour moi et j'espère que cela peut être utile pour d'autres personnes ayant des cas similaires.
</fragment></fragment></fragment></fragment></fragment></fragment></fragment>

Blanche

Confirmation de:

Ma décision est très impolie, mais cela fonctionne: car mes fragments sont créés dynamiquement à partir des données sauvegardées, je viens de supprimer tous les fragments de
PageAdapter

Avant d'appeler
super.onSaveInstanceState//

, Puis recréez-les lors de la création d'une activité:


@Override
protected void onSaveInstanceState/Bundle outState/ {
outState.putInt/"viewpagerpos", mViewPager.getCurrentItem// /;
mSectionsPagerAdapter.removeAllfragments//;
super.onSaveInstanceState/outState/;
}


Vous ne pouvez pas les supprimer dans
onDestroy//

, Sinon, vous obtiendrez cette exception:


java.lang.IllegalStateException:

Can not perform this action after
onSaveInstanceState


Voici le code de l'adaptateur de page:


public void removeAllfragments//
{
if / mFragmentList != null / {
for / Fragment fragment : mFragmentList / {
mFm.beginTransaction//.remove/fragment/.commit//;
}
mFragmentList.clear//;
notifyDataSetChanged//;
}
}


Je viens de garder la page actuelle et de la restaurer
onCreate//

, Après la création des fragments.


if /savedInstanceState != null/
mViewPager.setCurrentItem/ savedInstanceState.getInt/"viewpagerpos", 0 / /;

Alice

Confirmation de:

Ce que c'est
BasePagerAdapter

? Vous devez utiliser l'un des adaptateurs de pageur standard soit
FragmentPagerAdapter

, ou
FragmentStatePagerAdapter

, Selon si vous voulez des fragments qui ne sont plus nécessaires
ViewPager

, ou stocké à proximité /première/, Ou gardé leur état /deuxième/ Et si nécessaire, il a été créé à nouveau.

Exemple de code pour utilisation
ViewPager

Peut être trouvé
http://developer.android.com/t ... mples
Il est vrai que la gestion des fragments dans le pager de représentation entre les instances activity un peu difficile parce que
FragmentManager

Le cadre s'occupe de la préservation de l'état et de restaurer tout fragment actif que le pager a fait. Tout cela signifie réellement que l'adaptateur lors de l'initialisation doit s'assurer qu'il est relié à tous les fragments restaurés. Vous pouvez regarder le code pour
FragmentPagerAdapter

ou
FragmentStatePagerAdapter

, Voir comment cela se fait.

Dominique

Confirmation de:

Si quelqu'un a des problèmes avec le fait qu'ils sont FragmentStatePagerAdapter ne pas restaurer la condition de leur fragments...ie...new fragments ils sont créés FragmentStatePagerAdapter Au lieu de les restaurer d'un état ...

Assurez-vous d'appeler
ViewPager.setOffscreenPageLimit//

BEFORE Tu appelles
ViewPager.setAdapter/fragmentStatePagerAdapter/


De garde
ViewPager.setOffscreenPageLimit//

...ViewPager

immédiatement

Appelez votre adaptateur et essayez de le faire fragments. Cela peut arriver avant ViewPager aura une chance de restaurer des fragments de savedInstanceState/Ainsi, la création de nouveaux fragments qui ne peuvent pas être réinitialisés à partir de SavedInstanceState, Parce qu'ils sont nouveaux/.

Babette

Confirmation de:

J'ai inventé cette solution simple et élégante. Il suggère que l'activité est responsable de la création de fragments et que l'adaptateur les sert simplement.

Ceci est un code d'adaptateur /Il n'y a rien d'étrange ici, sauf pour le fait que
mFragments

- Ceci est une liste de fragments pris en charge par activité./


class MyFragmentPagerAdapter extends FragmentStatePagerAdapter {

public MyFragmentPagerAdapter/FragmentManager fm/ {
super/fm/;
}

@Override
public Fragment getItem/int position/ {
return mFragments.get/position/;
}

@Override
public int getCount// {
return mFragments.size//;
}

@Override
public int getItemPosition/Object object/ {
return POSITION_NONE;
}

@Override
public CharSequence getPageTitle/int position/ {
TabFragment fragment = /TabFragment/mFragments.get/position/;
return fragment.getTitle//;
}
}


Tout le problème de ce flux est d'obtenir un lien vers des fragments "old", Par conséquent, j'utilise ce code en action onCreate.


if /savedInstanceState!=null/ {
if /getSupportFragmentManager//.getFragments//!=null/ {
for /Fragment fragment : getSupportFragmentManager//.getFragments/// {
mFragments.add/fragment/;
}
}
}


Bien sûr, vous pouvez également configurer ce code s'il est nécessaire, par exemple, en vous assurant que les fragments sont des instances d'une certaine classe.

Agathe

Confirmation de:

Pour obtenir des fragments après avoir changé l'orientation, vous devez utiliser .getTag//.


getSupportFragmentManager//.findFragmentByTag/"android:switcher:" + viewPagerId + ":" + positionOfItemInViewPager/


Pour un petit traitement plus grand, j'ai écrit le mien ArrayList pour mon PageAdapter, Pour obtenir un fragment sur viewPagerId et FragmentClass Dans n'importe quelle position:


public class MyPageAdapter extends FragmentPagerAdapter implements Serializable {
private final String logTAG = MyPageAdapter.class.getName// + ".";

private ArrayList<mypagebuilder> fragmentPages;

public MyPageAdapter/FragmentManager fm, ArrayList<mypagebuilder> fragments/ {
super/fm/;
fragmentPages = fragments;
}

@Override
public Fragment getItem/int position/ {
return this.fragmentPages.get/position/.getFragment//;
}

@Override
public CharSequence getPageTitle/int position/ {
return this.fragmentPages.get/position/.getPageTitle//;
}

@Override
public int getCount// {
return this.fragmentPages.size//;
}


public int getItemPosition/Object object/ {
//benötigt, damit bei notifyDataSetChanged alle Fragemnts refrehsed werden

Log.d/logTAG, object.getClass//.getName///;
return POSITION_NONE;
}

public Fragment getFragment/int position/ {
return getItem/position/;
}

public String getTag/int position, int viewPagerId/ {
//getSupportFragmentManager//.findFragmentByTag/"android:switcher:" + R.id.shares_detail_activity_viewpager + ":" + myViewPager.getCurrentItem///

return "android:switcher:" + viewPagerId + ":" + position;
}

public MyPageBuilder getPageBuilder/String pageTitle, int icon, int selectedIcon, Fragment frag/ {
return new MyPageBuilder/pageTitle, icon, selectedIcon, frag/;
}


public static class MyPageBuilder {

private Fragment fragment;

public Fragment getFragment// {
return fragment;
}

public void setFragment/Fragment fragment/ {
this.fragment = fragment;
}

private String pageTitle;

public String getPageTitle// {
return pageTitle;
}

public void setPageTitle/String pageTitle/ {
this.pageTitle = pageTitle;
}

private int icon;

public int getIconUnselected// {
return icon;
}

public void setIconUnselected/int iconUnselected/ {
this.icon = iconUnselected;
}

private int iconSelected;

public int getIconSelected// {
return iconSelected;
}

public void setIconSelected/int iconSelected/ {
this.iconSelected = iconSelected;
}

public MyPageBuilder/String pageTitle, int icon, int selectedIcon, Fragment frag/ {
this.pageTitle = pageTitle;
this.icon = icon;
this.iconSelected = selectedIcon;
this.fragment = frag;
}
}

public static class MyPageArrayList extends ArrayList<mypagebuilder> {
private final String logTAG = MyPageArrayList.class.getName// + ".";

public MyPageBuilder get/Class cls/ {
// Fragment über FragmentClass holen
for /MyPageBuilder item : this/ {
if /item.fragment.getClass//.getName//.equalsIgnoreCase/cls.getName//// {
return super.get/indexOf/item//;
}
}
return null;
}

public String getTag/int viewPagerId, Class cls/ {
// Tag des Fragment unabhängig vom State z.B. nach bei Orientation change
for /MyPageBuilder item : this/ {
if /item.fragment.getClass//.getName//.equalsIgnoreCase/cls.getName//// {
return "android:switcher:" + viewPagerId + ":" + indexOf/item/;
}
}
return null;
}
}


Donc juste créer MyPageArrayList Avec des fragments:


myFragPages = new MyPageAdapter.MyPageArrayList//;

myFragPages.add/new MyPageAdapter.MyPageBuilder/
getString/R.string.widget_config_data_frag/,
R.drawable.ic_sd_storage_24dp,
R.drawable.ic_sd_storage_selected_24dp,
new WidgetDataFrag////;

myFragPages.add/new MyPageAdapter.MyPageBuilder/
getString/R.string.widget_config_color_frag/,
R.drawable.ic_color_24dp,
R.drawable.ic_color_selected_24dp,
new WidgetColorFrag////;

myFragPages.add/new MyPageAdapter.MyPageBuilder/
getString/R.string.widget_config_textsize_frag/,
R.drawable.ic_settings_widget_24dp,
R.drawable.ic_settings_selected_24dp,
new WidgetTextSizeFrag////;


et ajoutez-les à viewPager:


mAdapter = new MyPageAdapter/getSupportFragmentManager//, myFragPages/;
myViewPager.setAdapter/mAdapter/;


Après cela, vous pouvez obtenir après avoir changé le fragment correct d'orientation en utilisant sa classe:


WidgetDataFrag dataFragment = /WidgetDataFrag/ getSupportFragmentManager//
.findFragmentByTag/myFragPages.getTag/myViewPager.getId//, WidgetDataFrag.class//;


</mypagebuilder></mypagebuilder></mypagebuilder>

Catherine

Confirmation de:

ajouter:


@SuppressLint/"ValidFragment"/


Avant votre occupation.

Cela ne fonctionne pas pour faire quelque chose comme ça:


@SuppressLint/{ "ValidFragment", "HandlerLeak" }/

Pour répondre aux questions, connectez-vous ou registre