102 votes

Le fragment dans le ViewPager utilisant FragmentPagerAdapter est vide la deuxième fois qu'il est visualisé.

J'ai une interface de fragment avec des onglets en bas qui ouvrent différents fragments dans la vue principale.

J'ai un fragment particulier qui est une liste d'éléments. Si l'utilisateur sélectionne l'un des éléments de cette liste, un autre fragment s'ouvre et contient un viewpager qui fait défiler horizontalement tous les éléments de la liste du fragment précédent. Cela fonctionne très bien.

Le viewpager utilise un FragmentPagerAdapter pour afficher les éléments.

Le problème survient lorsque l'utilisateur sélectionne un élément de la liste, le visualise, puis appuie sur le bouton de la barre d'onglets pour revenir à la liste, puis sélectionne un autre élément. La deuxième fois qu'un élément est sélectionné, un écran vide apparaît à la place du viewpager. Je ne reçois aucune erreur dans mon LogCat lorsque cela se produit.

Pourquoi le viewpager n'apparaît-il que la première fois ?

FragmentPagerAdapter:

public class ViewPagerAdapter extends FragmentPagerAdapter {
    Cursor mCursor;

    public ViewPagerAdapter(FragmentManager fm, Cursor c) {
        super(fm);
        mCursor = c;
    }

    public void changeCursor(Cursor c) {
        mCursor = c;
        this.notifyDataSetChanged();
    }

    @Override
    public int getCount() {
        if (mCursor == null) return 0;
        else return mCursor.getCount();
    }

    @Override
    public Fragment getItem(int position) {
        mCursor.moveToPosition(position);
        return TeamCardFragment.newInstance(mCursor, position);
    }
}

PagerFragment:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    Bundle bundle = getArguments();
    mCursorPosition = bundle.getInt(TeamCardCommon.BUNDLE_KEY_CURSOR_POSITION);

    View mView = inflater.inflate(R.layout.team_card_master, container, false);
    mViewPager = (ViewPager)mView.findViewById(R.id.team_card_master_view_pager);

    mAdapter = new ViewPagerAdapter(getFragmentManager(), cursor);
    new setAdapterTask().execute();

    return mView;
}

private class setAdapterTask extends AsyncTask<Void, Void, Void> {
    protected Void doInBackground(Void... params) {
        return null;
    }

    @Override
    protected void onPostExecute(Void result) {
        mViewPager.setAdapter(mAdapter);
        mViewPager.setCurrentItem(mCursorPosition);
    }
}

1voto

Riaz Ali Khan Points 11

Appeler simplement getChildFragmentManager() Dans ce cas, vous n'obtiendrez pas de blanc en cas de clics multiples.

0voto

Patrick Points 5

Vous pouvez également initialiser l'adaptateur pour les cas où vous rencontrez cette erreur lorsque votre application est réduite puis appelée.

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    Bundle bundle = getArguments();
    mCursorPosition = bundle.getInt(TeamCardCommon.BUNDLE_KEY_CURSOR_POSITION);
    View mView = inflater.inflate(R.layout.team_card_master, container, false);
    mViewPager = (ViewPager)mView.findViewById(R.id.team_card_master_view_pager);
    initViewPagerAdapter();
    return mView;
}
private void initViewPagerAdapter(){
    mAdapter = new ViewPagerAdapter(getFragmentManager(), cursor);
    new setAdapterTask().execute();
}

@Override
public void onResume(){
    super.onResume();
    initViewPagerAdapter();
}

0voto

Arka-57 Points 26

J'ai eu la même chose, la deuxième fois que j'appelle l'adaptateur Pager, la vue enfant renvoie une NullPointerException. La modification de l'adaptateur dans FragmentStatePagerAdapter a également résolu mon problème.

0voto

Mostafa Anter Points 1086

Changer FragmentPagerAdapter en FragmentStatePagerAdapter Utilisation getChildFragmentManager() au lieu de getFragmentManager()

getChildFragmentManager() - car, d'après la documentation, il renverra un gestionnaire de fragments privé pour placer et gérer les fragments à l'intérieur de ce fragment. En attendant getFragmentManager() renvoie le gestionnaire de fragments permettant d'interagir avec les fragments associés à cette activité.

0voto

stackoverknow Points 1

J'ai rencontré un problème similaire en utilisant ViewPager2 y FragmentStateAdapter . Lors du remplacement du Fragment (contenant un viewpager2 et des onglets de fragments), j'ai réalisé que la onDestroyView() était appelée après la mise en place du nouveau fragment. J'ai corrigé ce problème en appelant FragmentTransaction.popBackStack() avant de remplacer le fragment, ce qui semble nettoyer l'ancien fragment avant de créer le nouveau.

Ce problème a commencé pour moi après la mise à jour androidx.appcompat:appcompat au-delà de la version 1.2. Mon fragment utilisait également setRetainInstance(false) qui est maintenant obsolète, je ne sais pas si cela fait partie du problème.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X