web-dev-qa-db-fra.com

Comment définir une balise pour les fragments de viewpager?

I, m utilise slidingTabLayout avec 4 onglets et un viewpager et 4 classes de fragments pour chaque onglet. 

j'ai besoin de recharger l'un de mes fragments (premier onglet) dans mon projet lorsque l'utilisateur clique sur un bouton, et pour cela, j'ai besoin d'une balise pour ce fragment

ma question est: comment puis-je définir une balise pour l'un des fragment de viewpagers ???

Onglet Mon MainActivity et codes de viewpager:

public class MainActivity extends AppCompatActivity
    implements NavigationView.OnNavigationItemSelectedListener {



Toolbar toolbar;
ViewPager pager;
ViewPagerAdapter adapter;
SlidingTabLayout tabs;
CharSequence Titles[]={"نوع","قیمت","برند","همه"};
int Numboftabs = 4;




@Override
protected void attachBaseContext(Context newBase) {
    super.attachBaseContext(CalligraphyContextWrapper.wrap(newBase));
}



@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);




    FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Snackbar.make(view, "درج آگهی رایگان", Snackbar.LENGTH_LONG)
                    .setAction("Action", null).show();
        }
    });



    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);

    NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
    navigationView.setNavigationItemSelectedListener(this);




    // Creating The ViewPagerAdapter and Passing Fragment Manager, Titles fot the Tabs and Number Of Tabs.
    adapter =  new ViewPagerAdapter(getSupportFragmentManager(),Titles,Numboftabs);

    // Assigning ViewPager View and setting the adapter
    pager = (ViewPager) findViewById(R.id.pager);
    pager.setAdapter(adapter);

    // Assiging the Sliding Tab Layout View
    tabs = (SlidingTabLayout) findViewById(R.id.tabs);
    tabs.setDistributeEvenly(true); // To make the Tabs Fixed set this true, This makes the tabs Space Evenly in Available width

    // Setting Custom Color for the Scroll bar indicator of the Tab View
    tabs.setCustomTabColorizer(new SlidingTabLayout.TabColorizer() {
        @Override
        public int getIndicatorColor(int position) {
            return getResources().getColor(R.color.colorWhite);
        }
    });

    // Setting the ViewPager For the SlidingTabsLayout
    tabs.setViewPager(pager);
    pager.setCurrentItem(3);




} and ....

Merci beaucoup

13
K1-Aria

Il existe deux solutions pour cela. 

1). Lorsque la FragmentPagerAdapter ajoute une Fragment à la FragmentManager, elle utilise une balise spéciale basée sur la position particulière à laquelle la Fragment sera placée. Ainsi, vous pouvez simplement obtenir la Fragment visible actuelle dans votre ViewPager en utilisant ces lignes de code

 Fragment fragment = getSupportFragmentManager().findFragmentByTag("Android:switcher:" + R.id.pager + ":" + ViewPager.getCurrentItem());
 // based on the current position you can then cast the page to the correct Fragment class and call some method inside that fragment to reload the data:
 if (0 == ViewPager.getCurrentItem() && null != fragment) {
      ((TabFragment1)fragment).reloadFragmentData();     
 } 

2) Vous devriez garder une trace de tous les fragments actifs dans la FragmentStatePagerAdapter. Pour un exemple de démonstration, vous pouvez vous référer à la deuxième approche ici

3) Vous pouvez utiliser EventBus pour publier des événements sur votre Fragment de n’importe où. Tout ce que vous avez à faire est d’enregistrer votre Fragment pour cet événement spécifique. Pour la documentation officielle, référez-vous this

26
Mukesh Rana

Voici la méthode utilisée par FragmentPagerAdapter pour créer le nom de balise Fragment:

private static String makeFragmentName(int viewId, long id) {
    return "Android:switcher:" + viewId + ":" + id;
}

viewId est l'id de ViewPager.
id est la position du fragment à l'intérieur de ViewPager.

Exemple:

String fragmentTag = makeFragmentName(myViewPager.getId(), 2);
Fragment fragment = getSupportFragmentManager().findFragmentByTag(fragmentTag);
7
vovahost

Bien que cette question a déjà été répondu. J'ai une autre approche pour y parvenir et celle-ci pourrait être meilleure car la manière dont les fragments sont étiquetés dans le code est soumise à modification. De plus, l'utilisation de adapter.getItem (position) ne renvoie pas l'instance de fragment en cours d'affichage, cela dépend de notre propre implémentation de la méthode getItem.

Donc, fondamentalement, le problème est que nous n’avons pas l’instance de Fragments présente dans le viewPager. L'idée est de remplacer la méthode 

public Object instantiateItem(ViewGroup container, int position) {
    // If we already have this item instantiated, there is nothing
    // to do.  This can happen when we are restoring the entire pager
    // from its saved state, where the fragment manager has already
    // taken care of restoring the fragments we previously had instantiated.
    if (mFragments.size() > position) {
        Fragment f = mFragments.get(position);
        if (f != null) {
            return f;
        }
    }

    if (mCurTransaction == null) {
        mCurTransaction = mFragmentManager.beginTransaction();
    }

    Fragment fragment = getItem(position);
    if (DEBUG) Log.v(TAG, "Adding item #" + position + ": f=" + fragment);
    if (mSavedState.size() > position) {
        Fragment.SavedState fss = mSavedState.get(position);
        if (fss != null) {
            fragment.setInitialSavedState(fss);
        }
    }
    while (mFragments.size() <= position) {
        mFragments.add(null);
    }
    fragment.setMenuVisibility(false);
    fragment.setUserVisibleHint(false);
    mFragments.set(position, fragment);
    mCurTransaction.add(container.getId(), fragment);

    return fragment;
}

de FragmentStatePagerAdapter. Si nous examinons l'implémentation par défaut de cette méthode, elle instancie les nouveaux fragments s'ils n'existent pas et les restitue. En outre, il les stocke dans une liste de fragments qui est privée. Nous pouvons donc remplacer cette méthode et stocker les instances sur des fragments de notre propre liste. Ceci peut être implémenté de la manière suivante 

private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {

    private ArrayList<Fragment> fragmentList;

    private final int NUM_PAGES;

    public ScreenSlidePagerAdapter(FragmentManager fm, int numPages) {
        super(fm);
        NUM_PAGES = numPages;
        fragmentList = new ArrayList<>(NUM_PAGES);
    }

    @Override
    public Fragment getItem(int position) {
        Fragment fragment = new CustomFragment();
        //this method can be modified according to the requirement
        return fragment;
    }

    @Override
    public int getCount() {
        return NUM_PAGES;
    }

    public Fragment getFragment(int position){
        return fragmentList.get(position);
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position){
        Fragment fragment = (Fragment) super.instantiateItem(container,position);
        if(fragmentList.size()<NUM_PAGES&&!fragmentList.contains(fragment)){
            fragmentList.add(fragment);
        }
        return fragment;
    }
}

Par conséquent, nous aurons les instances de tous les fragments disponibles avec nous, nous n'aurions plus besoin de balises pour trouver les instances de fragments affichées à l'utilisateur.

0
Utkarsh Saxena