IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Android Discussion :

Supprimer les fragments d'un FragmentStatePagerAdapter


Sujet :

Android

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    268
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 268
    Points : 128
    Points
    128
    Par défaut 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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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

  2. #2
    Expert éminent

    Avatar de Feanorin
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    4 589
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 4 589
    Points : 9 149
    Points
    9 149
    Par défaut
    Bonjour,

    Les différents mode sous Android sont géré automatiquement pas la peine de le gérer à haut niveau.

    pour cela il suffit juste de créer les différents layout en fonction de leur modes depuis les ressources.
    layout-port //portrait
    layout-land //paysage
    etc.

    De même dans ton getItem tu créer à chaque fois un nouvel fragment. C'est pas censé récupérer un fragment ?
    Responsable Android de Developpez.com (Twitter et Facebook)
    Besoin d"un article/tutoriel/cours sur Android, consulter la page cours
    N'hésitez pas à consulter la FAQ Android et à poser vos questions sur les forums d'entraide mobile d'Android.

  3. #3
    Membre habitué
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    268
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 268
    Points : 128
    Points
    128
    Par défaut
    Hello Feanorin,

    Content d'avoir une première contribution
    Effectivement Android gère déjà le changement d'orientation mais l'avantage de le gérer manuellement c'est que je peux distinguer facilement les factories et segmenter le code correspondant, mais il y a peut-être une autre façon de faire plus adaptée ...
    Dans getItem, je crée le fragment renvoyé car je ne peux pas le créer en amont étant donné qu'il s'agit de fichiers de pages qui sont des bitmaps (créer 250 bitmaps à la volée ça ne passe évidement pas en mémoire)

Discussions similaires

  1. Comment supprimer les doublons
    Par djelloulc dans le forum MS SQL Server
    Réponses: 9
    Dernier message: 17/09/2013, 14h30
  2. Réponses: 9
    Dernier message: 06/11/2007, 12h36
  3. Réponses: 4
    Dernier message: 10/08/2004, 11h59
  4. [Jsp] Supprimer les caractère spéciaux d'une chaine
    Par PeteMitchell dans le forum Servlets/JSP
    Réponses: 4
    Dernier message: 13/05/2004, 11h11
  5. [String] Comment supprimer les accents
    Par iuz dans le forum Collection et Stream
    Réponses: 7
    Dernier message: 08/03/2004, 02h58

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo