2017-05-19 1 views
0

La liste ListView d'un fragment contenant un ViewPager est vide lorsque j'y retourne. Ce ViewPager est à l'intérieur d'un fragment parce que j'utilise une disposition de tiroir de navigation. Je vais essayer de l'expliquer plus en détail maintenant:ListView d'un fragment (d'un ViewPager dans un fragment) qui implémente LoaderCallbacks <Cursor> est vide lorsque j'y retourne

J'utilise une disposition de tiroir de navigation et, par conséquent, en utilisant des fragments. Dans l'activité principale, dans onCreate, je place le fragment courant avec ces lignes de code:

@Override 
protected void onCreate(Bundle savedInstanceState) { 

    /* More code */ 

    currentFragment = new MainFragment(); 
    FragmentManager fragmentManager = getSupportFragmentManager(); 
    fragmentManager.beginTransaction().replace(R.id.layout_for_fragments, currentFragment).commit(); 
} 

La classe MainFragment contient un ViewPager qui est initialisé avec ces lignes de code dans le onCreateView():

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 
    View rootView = inflater.inflate(R.layout.fragment_main, container, false); 

    /* More code */ 

    ViewPager viewPager = (ViewPager) rootView.findViewById(R.id.main_view_pager); 
    viewPager.setAdapter(new SimpleFragmentPagerAdapter(getActivity(), getActivity().getSupportFragmentManager())); 

    /* Code for Tablayout */ 

    return rootView; 
} 

un des fragments de la classe SimpleFragmentPagerAdapter est celui qui met en œuvre LoaderManager.LoaderCallbacks

public class ExpensesFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor> { 

    private ExpenseCursorAdapter mExpenseCursorAdapter; 

    private static final int EXPENSE_LOADER = 1; 

    public ExpensesFragment() { 
     // Required empty public constructor 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 

     View rootView = inflater.inflate(R.layout.fragment_expenses, container, false); 

     ListView expensesListView = (ListView) rootView.findViewById(R.id.expenses_list_view); 
     mExpenseCursorAdapter = new ExpenseCursorAdapter(getContext(), null); 
     expensesListView.setAdapter(mExpenseCursorAdapter); 

     getLoaderManager().initLoader(EXPENSE_LOADER, null, this); 

     return rootView; 
    } 

    @Override 
    public Loader<Cursor> onCreateLoader(int id, Bundle args) { 
     return new CursorLoader(/* arguments */); 
    } 

    @Override 
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) { 
     mExpenseCursorAdapter.swapCursor(data); 
    } 

    @Override 
    public void onLoaderReset(Loader<Cursor> loader) { 
     mExpenseCursorAdapter.swapCursor(null); 
    } 
} 

Sur la première manche, tout fonctionne bien . Cependant, si je clique sur le menu du panneau de navigation, que je suis mise en œuvre de cette façon, le ListView devient vide:

public boolean onNavigationItemSelected(@NonNull MenuItem item) { 
    int id = item.getItemId(); 

    if (id == R.id.nav_main) { 

     FragmentManager fragmentManager = getSupportFragmentManager(); 
     fragmentManager.beginTransaction().remove(currentFragment).commit(); 

     currentFragment = new MainFragment(); 
     fragmentManager.beginTransaction().replace(R.id.layout_for_fragments, currentFragment).commit(); 

    } else if (id == R.id.nav_blank) { 

     FragmentManager fragmentManager = getSupportFragmentManager(); 
     fragmentManager.beginTransaction().remove(currentFragment).commit(); 

     currentFragment = new BlankFragment(); 
     fragmentManager.beginTransaction().replace(R.id.layout_for_fragments, currentFragment).commit(); 

    } 

    drawer.closeDrawer(GravityCompat.START); 
    return true; 
} 

Le problème existe aussi quand je tourne l'appareil. Il y a une différence cependant. Lorsque j'utilise le menu Navigation Drawer, aucune des méthodes de LoaderManager.LoaderCallbacks n'est appelée, mais lorsque je fais pivoter le périphérique, onLoadFinished est appelé.

Quoi qu'il en soit, le problème persiste. Des ideias comment le résoudre?

Merci d'avance.

Répondre

0

J'ai trouvé la solution!

Fondamentalement, j'ai fait deux erreurs. Le premier concerne la rotation de l'appareil. Lorsque l'appareil est pivoté, l'activité est détruite et onCreate est appelé à nouveau. Dans ce cas, je ne devrais pas appeler le nouveau MainFragment(). Donc, je vérifie si la savedInstanceState est nulle avant que je l'appelle, comme ceci:

if (savedInstanceState == null) { 
    currentFragment = new MainFragment(); 
    FragmentManager fragmentManager = getSupportFragmentManager(); 
    fragmentManager.beginTransaction(). 
      replace(R.id.layout_for_fragments, currentFragment).commit(); 
} 

Le second est d'un fragment dans un fragment. Dans ce cas, je ne peux pas simplement appeler getSupportFragmentManager(). Je devrais appeler getChildFragmentManager() à la place et c'est tout!