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
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
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);
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.