Supprimer les fragments d'un FragmentStatePagerAdapter
Bonjour à tous,
Je tente de développer une app Android qui permet de lire un livre dans lequel les images sont des Bitmaps. A cet effet, j'ai 2 "factories" qui gèrent respectivement le mode portrait (créant des pages) et le mode paysage (créant des pages doubles).
Le système est relativement simple, je dispose d'un ViewPager dont le contenu est géré par un FragmentStatePagerAdapter qui se charge d'appeler les fabriques en fonction de l'orientation de la tablette. Les pages sont créées au fur et à mesure par l'adapter par la méthode getItem. Je ne peux pas créer 250 pages (Bitmap) et tout mettre dans une ArrayList à la création du fragment principal car ça pose un problème de mémoire.
L'app fonctionne parfaitement dans les 2 modes. Cependant lorsque je change d'orientation le FragmentStatePagerAdapter réutilise les anciens fragments créés du mode d'affichage précédent avant de créé les pages du mode courant.
Exemple:
- je lance l'app en portrait, l'adapter crée 2 pages (1 et 2), je vois bien la page 1
- je passe en landscape, l'adapter reprends les 2 pages créées en mode portrait, du coup, je vois toujours la page 1 du mode portrait
- je swipe
- je vois la page 2 du mode portrait alors que je devrais avoir la page double 2 et 3
- je swipe encore une fois
- et là c'est bon, je vois la page double 3 et 4
et ainsi de suite jusqu'a obtenir une OutOfMemoryError car à chaque changement d'orientation, les 2 derniers fragments ne sont pas supprimés ...
PlayerFragmentActivity.java
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
|
public class PlayerFragmentActivity extends FragmentActivity {
private Intent mIntent;
private ViewPager mPortraitPager;
private ViewPager mLandscapePager;
private Boolean mIsLandscape;
private String mKey;
private int mNbPages;
private int mNbDoublePages;
private PageFactory mPageFactory;
private DoublePageFactory mDoublePageFactory;
private PagerAdapter mPagerAdapter;
@Override
protected void onStop(){
super.onStop();
mPagerAdapter = null;
mDoublePageFactory = null;
mPageFactory = null;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_activity_player);
mIntent = getIntent();
mKey = mIntent.getStringExtra("key");
mNbPages = mIntent.getIntExtra("nbPages", 0);
mNbDoublePages = DoublePageFactory.getDoublePageNumFromPageNum(mNbPages);
Resources res = getResources();
mIsLandscape = (res.getConfiguration().orientation == 1) ? false : true;
mPortraitPager = (ViewPager) findViewById(R.id.portraitPager);
mLandscapePager = (ViewPager) findViewById(R.id.landscapePager);
mPagerAdapter = new MyPagerAdapter(getSupportFragmentManager());
if (mIsLandscape) {
mDoublePageFactory = new DoublePageFactory(this, mKey, mNbPages, res.getInteger(R.integer.nb_page_columns), res.getInteger(R.integer.nb_page_columns));
mPortraitPager.setVisibility(View.GONE);
mLandscapePager.setAdapter(mPagerAdapter);
mPortraitPager.setAdapter(null);
} else {
mPageFactory = new PageFactory(this, mKey, this.mNbPages, res.getInteger(R.integer.nb_page_columns), res.getInteger(R.integer.nb_page_columns));
mLandscapePager.setVisibility(View.GONE);
mPortraitPager.setAdapter(mPagerAdapter);
mLandscapePager.setAdapter(null);
}
}
public class MyPagerAdapter extends FragmentStatePagerAdapter {
public MyPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
Bundle args = new Bundle();
if(mIsLandscape){
Fragment doublePageFragment = new DoublePageFragment();
args.putInt(DoublePageFragment.ARG_DOUBLEPAGE_NUM, position + 1);
doublePageFragment.setArguments(args);
return doublePageFragment;
}else{
Fragment pageFragment = new PageFragment();
args.putInt(PageFragment.ARG_PAGE_NUM, position + 1);
pageFragment.setArguments(args);
return pageFragment;
}
}
@Override
public int getCount() {
return (mIsLandscape) ? mNbDoublePages:mNbPages;
}
/* j'ai essayé cette méthode mais ça ne fonctionne pas :( */
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
FragmentManager manager = ((Fragment) object).getFragmentManager();
FragmentTransaction trans = manager.beginTransaction();
trans.remove((Fragment) object);
trans.commit();
super.destroyItem(container, position, object);
}
@Override
public int getItemPosition(Object object){
return PagerAdapter.POSITION_NONE;
}
@Override
public CharSequence getPageTitle(int position) {
return "p." + position + 1;
}
}
public boolean isLandscape() {
return mIsLandscape;
}
public ImageView getSinglePage(int position) {
return mPageFactory.getPage(position);
}
public LinearLayout getDoublePage(int position) {
return mDoublePageFactory.getDoublePage(position);
}
} |
PageFragment
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
/* fragment d'une page en mode portrait */
public class PageFragment extends Fragment {
private PlayerFragmentActivity mPlayerFragmentActivity;
public static final String ARG_PAGE_NUM = "page_number";
public static final String ARG_WOBOOK_DIRECTORY = "book_directory";
public static final String ARG_NB_PAGE_COLUMNS = "nb_page_columns";
public static final String ARG_NB_PAGE_ROWS = "nb_page_rows";
@Override
public ImageView onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mPlayerFragmentActivity = ((PlayerFragmentActivity) getActivity());
return mPlayerFragmentActivity.getSinglePage(getArguments().getInt(ARG_PAGE_NUM));
}
@Override
public void onStop(){
super.onStop();
mPlayerFragmentActivity = null;
}
} |
DoublePageFragment
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
public class DoublePageFragment extends Fragment {
private PlayerFragmentActivity mPlayerFragmentActivity;
public static final String ARG_DOUBLEPAGE_NUM = "double_page_number";
public static final String ARG_WOBOOK_DIRECTORY = "book_directory";
public static final String ARG_NB_PAGE_COLUMNS = "nb_page_columns";
public static final String ARG_NB_PAGE_ROWS = "nb_page_rows";
@Override
public LinearLayout onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mPlayerFragmentActivity = ((PlayerFragmentActivity) getActivity());
return mPlayerFragmentActivity.getDoublePage(getArguments().getInt(ARG_DOUBLEPAGE_NUM));
}
@Override
public void onStop(){
super.onStop();
mPlayerFragmentActivity = null;
}
} |
J'ai aussi testé cette méthode méthode en vain. Je pense que c'est aussi lié à ce topic mais je reste novice en Java et je n'arrive pas à résoudre ce problème, je m'en remets donc aux experts :)
Merci de votre aide