web-dev-qa-db-fra.com

PagerAdapter.notifyDataSetChanged n'actualise pas les fragments

Ma Activity contient une ViewPager et sa coutume Adapter qui étend FragmentStatePagerAdapter. ViewPager contient 3 fragments

Code pour supprimer les fragments du ViewPager

MainActivity

public void deleteElement(){
    final int currentItem = mViewPager.getCurrentItem();
    mPagerAdapter.removeItem(currentItem);
    mPagerAdapter.notifyDataSetChanged();
}

CustomPagerAdapter

private ArrayList<Item> data;
public void removeItem(int index){
        data.remove(index);
}

lors de la suppression de la Fragment du milieu (index 1):

  • de data je supprime le item correct. 
  • Le problème est que i (je suppose) Fragment 3 est supprimé après notifyDataSetChanged et que la Fragment actuelle est toujours le fragment que l'utilisateur a vu et que les données en cours de chargement proviennent de l'ensemble SavedInstance

Le résultat final est donc que l'utilisateur voit toujours la même Fragment qu'il a essayé de supprimer, ce qui est un peu nul pour lui.

Des idées? 

16
royB

Essayez d'ajouter ceci:

private class MyPagerAdapter extends FragmentStatePagerAdapter {

//... your existing code

    @Override
    public int getItemPosition(Object object){
        return PagerAdapter.POSITION_NONE;
    }

}
26
kelvincer

Vous n'avez pas d'autre choix que de mettre en œuvre PagerAdapter#getItemPosition. En regardant la source, c'est exactement comment ViewPager détermine comment mettre à jour sa position, ajouter de nouveaux fragments ou supprimer des éléments morts après notifyDataSetChanged. Cela ne devrait pas être trop difficile, il vous suffit d'accéder à l'état du fragment transmis et à l'état principal de votre activité qui contient votre commande.

Vous devez également implémenter getItemId pour renvoyer un ID cohérent pour chaque fragment, car ils peuvent être réorganisés.

Voici comment je l'ai traité dans un ViewPager de photos.

    private inner class PhotoPagerAdapter(fm: FragmentManager) : FragmentPagerAdapter(fm) {
    override fun getItem(position: Int): PhotoViewFragment {
        // getItem is called to instantiate the fragment for the given page.
        return PhotoViewFragment.newInstance(position, [email protected][position])
    }

    override fun getItemId(position: Int): Long {
        return [email protected][position].ID!!.hashCode().toLong()
    }

    override fun getItemPosition(`object`: Any): Int {
        val frag = `object` as PhotoViewFragment
        val idx = [email protected] { ph -> ph.ID == frag.dataBinding.photo.ID }
        return if (idx >= 0) idx else PagerAdapter.POSITION_NONE
    }

    override fun getCount(): Int {
        return [email protected]
    }
}
2
androidguy

Vous pouvez essayer d'utiliser FragmentPagerAdapter au lieu de FragmentStatePagerAdapter. Le problème, c’est que j’ai aussi rencontré ce problème et que cela m’a aidé.

0
Chhatrasal Singh

Vous devez d'abord définir l'adaptateur sur null, puis le rétablir:

int currentPosition = mViewPager.getCurrentItem();
mPagerAdapter.notifyDataSetChanged();
mViewPager.setAdapter(null);
mViewPager.setAdapter(mPagerAdapter);
mViewPager.setCurrentItem(currentPosition);
0
Matjaz Kristl