web-dev-qa-db-fra.com

Actualiser/Recharger/Réinstancier un fragment dans un système de tabulation Android

J'ai une activité avec un viewpager qui a 3 onglets et 3 fragments, à l'intérieur de chaque onglet se trouve un fragment. Je sais que le gestionnaire de fragments stocke les instances initiales des fragments, de sorte que si je glisse hors d'un onglet, puis que je retourne à cet onglet, celui-ci est chargé en mémoire et aucune mise à jour n'y est appliquée. 

J'ai besoin de l'inverse, à savoir: chaque fois que je glisse dans un onglet, une nouvelle instance du fragment dans cet onglet doit être chargée pour que les données soient mises à jour.

J'ai essayé:

  1. détacher attacher un fragment dans onTabSelected (rien ne se passe) 
  2. remove add fragment dans onTabSelected (rien ne se passe) 
  3. setOffscreenPageLimit (0) (rien ne se passe) 
  4. fonction de rafraîchissement à l'intérieur de chaque fragment à appeler onTabSelected (donne nullPointerException)

Je me bats avec ce problème depuis une semaine sans progrès. J'apprécie toute aide, que ce soit un indice, un commentaire, une suggestion.

Laissez-moi savoir quel code devrais-je poster, Merci.

12
Pacemaker

Je voudrais utiliser quelque chose semblable à ce qui suit:

public class MainActivity extends FragmentActivity implements ActionBar.TabListener {

    private ViewPager ViewPager;
    private TabsPagerAdapter SectionsPagerAdapter;
    private ActionBar actionBar;

    private String[] tabs = { "Event Details", "Line-up", "Donations", };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

     // Initialisation
        ViewPager = (ViewPager) findViewById(R.id.pager);
        actionBar = getActionBar();
        SectionsPagerAdapter = new TabsPagerAdapter(getSupportFragmentManager());

        ViewPager.setAdapter(SectionsPagerAdapter);
        actionBar.setHomeButtonEnabled(false);
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); 

     // Adding Tabs
        for (String tab_name : tabs) {
            actionBar.addTab(actionBar.newTab().setText(tab_name).setTabListener(this));
        }

        ViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {

            @Override
            public void onPageSelected(int position) {
                // on changing the page
                // make respected tab selected
                actionBar.setSelectedNavigationItem(position);
            }

            @Override
            public void onPageScrolled(int arg0, float arg1, int arg2) {
            }

            @Override
            public void onPageScrollStateChanged(int arg0) {
            }
        });
    }

    @Override
    public void onTabReselected(Tab tab, Android.app.FragmentTransaction ft) {

    }

    @Override
    public void onTabSelected(Tab tab, Android.app.FragmentTransaction ft) {
        ViewPager.setCurrentItem(tab.getPosition());
    }

    @Override
    public void onTabUnselected(Tab tab, Android.app.FragmentTransaction ft) {

    }

//Attaching the fragments to the tabPagerAdapter
public class TabsPagerAdapter extends FragmentPagerAdapter {

        public TabsPagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int index) {

            switch (index) {
            case 0:
                return new EventFragment();
            case 1:
                // Points to the Lineup class
                return new LineupFragment();
            case 2:
                // Points to the 
                return new DonationFragment();
            case 3:

                return new ConcertFragment();
            }

            return null;
        }
@Override
        public int getCount() {
            // get item count - equal to number of tabs
            return 4;
        }
    }

//Add your fragments here

J'espère que cela vous aide :)

4
Michele La Ferla

Je sais que la réponse est ancienne, mais ... j'ai trouvé une solution. Je ne peux pas dire si c'est le meilleur, mais dans mon cas, résolu.

En activité:

@Override
public void onTabSelected(ActionBar.Tab tab,
        FragmentTransaction fragmentTransaction) {
    // When the given tab is selected, switch to the corresponding page in
    // the ViewPager.
    mViewPager.setCurrentItem(tab.getPosition());


        if (tab.getPosition() == 0) {

            LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this);
            Intent i = new Intent("TAG_REFRESH");
            lbm.sendBroadcast(i);

        }

}

Et votre fragment:

public class MyFragment extends Fragment {

MyReceiver r;
public void refresh() {
    //yout code in refresh.
    Log.i("Refresh", "YES");
}

public void onPause() {
    super.onPause();
    LocalBroadcastManager.getInstance(context).unregisterReceiver(r);
}

public void onResume() {
    super.onResume();
    r = new MyReceiver();
    LocalBroadcastManager.getInstance(context).registerReceiver(r,
            new IntentFilter("TAG_REFRESH"));
}

private class MyReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        MyFragment.this.refresh();
    }
}
22
Edwin Wachs

Voici l'approche la plus compacte, touchant une seule méthode dans votre classe Fragment uniquement:

public class MyFragment extends Fragment {

  @Override
  public void setUserVisibleHint(boolean isVisibleToUser) {

    super.setUserVisibleHint(isVisibleToUser);

    if (isVisibleToUser) {

      // Refresh tab data:

      if(getFragmentManager() != null) {

        getFragmentManager()
        .beginTransaction()
        .detach(this)
        .attach(this)
        .commit();
    }
  }
}
0
Zon