Retrieve a Fragment from a Viewpager

Getting the current Fragment instance in the viewpager

by selecting an option, I need to update the fragment that is
currently visible.

A simple way of doing this is using a trick related to the FragmentPagerAdapter implementation:

case R.id.addText:
Fragment page = getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.pager + ":" + ViewPager.getCurrentItem());
// based on the current position you can then cast the page to the correct
// class and call the method:
if (ViewPager.getCurrentItem() == 0 && page != null) {
((FragmentClass1)page).updateList("new item");
}
return true;

Please rethink your variable naming convention, using as the variable name the name of the class is very confusing(so no ViewPager ViewPager, use ViewPager mPager for example).

How to get fragment reference from ViewPager

Use viewPager.getAdapter.getItem(position); from your Activity or parent Fragment.

Description (Modified) - As you wrote addFragment() adds a fragment to mFragmentList and you are adding fragment by this method too by calling:

mSectionsPageAdapter.addFragment(new MyChatsFragment())

And getItem() returns a fragment from mFragmentList where you added your fragment. So if you want to get MyChatsFragment reference just use:

MyChatsFragment myChatsFragment = (MyChatsFragment) 
mSectionsPageAdapter .getItem(position);

or

MyChatsFragment myChatsFragment = (MyChatsFragment) 
viewPager.getAdapter.getItem(position);

How to get Current Fragment in ViewPager2

  1. Create property in your adapter to save all your fragments
  2. Save current position
  3. Get fragment from fragment list (property) by position when you need it

Something like this:

    val fragments: MutableList<Fragment> = mutableListOf()

private val config: TribunConfig?
override fun createFragment(position: Int): Fragment {
val fragment = TribunNewsFragment.newInstance(if (menuTribun!!.get(position) == "News") "home"
else menuTribun!!.get(position)!!.replace(" ", "").toLowerCase(), config)!!

fragments.add(fragment)
return fragment
}

Parent:

 yourTabLayout.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
override fun onTabSelected(tab: TabLayout.Tab?) {
val fragment = adapter.fragments[tab!!.position]
// cast fragment to your fragment class and do what you want
}

override fun onTabUnselected(tab: TabLayout.Tab?) {
}

override fun onTabReselected(tab: TabLayout.Tab?) {
}
})

Also you can use when or if-else for your fragments position or create base class with methods you need and cast getting fragment to it.

How to get current Fragment name in viewpager?

Inside CustomTabLayout add

tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener()
{
@Override
public void onTabSelected(TabLayout.Tab tab)
{
int position = tab.getPosition();


}

@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {

}
});

How to get elements of fragments created by ViewPager in MainActivity?

Unfortunately the only "safe" way to do it is to check the source code of FragmentPagerAdapter, and see what tag is the fragment is added with - because findFragmentByTag is the only safe way to get a Fragment from a FragmentManager.

Of course, we need to hope that this implementation detail doesn't change between support library versions, but it actually hasn't changed in years :)


Anyways, so FragmentPagerAdapter says:

    // Do we already have this fragment?
String name = makeFragmentName(container.getId(), itemId);
Fragment fragment = mFragmentManager.findFragmentByTag(name);

So what is name?

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

What is viewId and what is id?

ViewId is container.getId(), where container is the ViewPager itself.

id is: final long itemId = getItemId(position); which by default is return position;.


So you can find the Fragment as follows:

Fragment fragment = fragmentManager.findFragmentByTag("android:switcher:" + viewPager.getId() + ":" + fragmentPosition);
// if fragment is null, it was not created yet by ViewPager

NOTE:

It is worth noting that you should NOT rely on getItem(int position) { to return the same fragment instance as you passed in, because that will lead you to this problem. (This question does it correctly, the getItem() method must always return a new Fragment instance.)

How to get the current fragment displayed in a specific tab of a viewpager?

First define a SparseArray in your ViewPagers' adapters like below. In this array we'll hold the instance of fragments.

SparseArray<Fragment> registeredFragments = new SparseArray<>();

And Override your Adapters' instantiateItem method.

@Override
public Object instantiateItem(ViewGroup container, int position) {
Fragment fragment = (Fragment) super.instantiateItem(container, position);
registeredFragments.put(position, fragment);
return fragment;
}

Also Override destroyItem method of your ViewPagers

@Override
public void destroyItem(ViewGroup container, int position, Object object) {
registeredFragments.remove(position);
super.destroyItem(container, position, object);
}

And define a new method to get your ViewPager Fragments instance.

public Fragment getRegisteredFragment(int position) {
return registeredFragments.get(position);
}

And finally set add a PageChangeListener to your ViewPagers:

viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {

@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

}

@Override
public void onPageSelected(int position) {
// Here's your instance
YourFragment fragment =(YourFragment)yourPagerAdapter.getRegisteredFragment(position);

}

@Override
public void onPageScrollStateChanged(int state) {

}
});

I hope this'll help you. Good luck.

Edit: I'm sorry i cannot understand exactly what you're planning to do but if you need to keep sub fragment (b_1, b_2) instance you can define a method to your activity such as

public void setCurrentFragment(Fragment fragment){
this.currentFragment = fragment;
}

and in your sub view pager's adapter you can call this method like below:

subViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {

@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

}

@Override
public void onPageSelected(int position) {
// Here's your instance
YourFragment fragment =(YourFragment)yourSubPagerAdapter.getRegisteredFragment(position);
((MyActivity)getActivity).setCurrentFragment(fragment);
}

@Override
public void onPageScrollStateChanged(int state) {

}
});

With this way you can keep one instance and your top fragment.



Related Topics



Leave a reply



Submit