Well I have a tablayout, inside the tablayout is 3 tabs(fragments) and inside of the fragment i need to update the whole tablayout using swiperefreshlayout. anyone knows how to do that?
You can get parent fragment which hold child fragments in a child fragment like this:
private FragmentMain getMainFragment() {
return (FragmentMain) getParentFragment(); }
Then you can call a method from a child fragment to all other child fragments for overcome whatever task you want to accomplish.
if((MainFragmentPagerAdapter) getMainFragment().viewPager.getAdapter().getItem(1) instanceof ChildFragment1){
((ChildFragment1) ((MainFragmentPagerAdapter)getMainFragment().viewPager.getAdapter()).getItem(1)).setTask();
} else if((MainFragmentPagerAdapter) getMainFragment().viewPager.getAdapter().getItem(2) instanceof ChildFragment2){
((ChildFragment2) ((MainFragmentPagerAdapter)getMainFragment().viewPager.getAdapter()).getItem(2)).setTask();
}
Related
I have main fragment with ViewPager2 that contains other fragments.
Each child fragment can open another detail fragment (main fragment replaced with details fragment).
When I go back to from detail fragment, ViewPager2 recreate all child fragments.
If I try to reuse the adapter (FragmentStateAdapter):
if (pagerAdapter == null) {
pagerAdapter = Adapter(this)
binding.viewPager.adapter = pagerAdapter
}else{
binding.viewPager.adapter = pagerAdapter
}
I got crash:
java.lang.IllegalArgumentException
at androidx.core.util.Preconditions.checkArgument(Preconditions.java:38)
at androidx.viewpager2.adapter.FragmentStateAdapter.onAttachedToRecyclerView(FragmentStateAdapter.java:132)
at androidx.recyclerview.widget.RecyclerView.setAdapterInternal(RecyclerView.java:1209)
at androidx.recyclerview.widget.RecyclerView.setAdapter(RecyclerView.java:1161)
at androidx.viewpager2.widget.ViewPager2.setAdapter(ViewPager2.java:461)
How to avoid creating new fragment every time?
I solved the problem. I init adapter every time in onCreate, before I used lazy for init adapter.
logVP2.adapter = SummaryDetailsPageAdapter(childFragmentManager, lifecycle).apply {
setData(args?.list)
}
My ViewPager is located in nested fragment, because i also have navigation drawer. My question is how can i call instance of viewpager in MainActivity.java, so i can set current item of viewpager using method setCurrentItem() from MainActivity.java in method onBackPressed(), when for example user is on third fragment of viewpager and when he presses back button he should be returned on first fragment.
First, you have to declare RecyclerView as public. Not sure if it has to be static, but it'll tell you if it has to.
Second, you need to call an instance of the fragment that holds the RecyclerView.
For example, Fragment recyclerFrag = new RecyclerFrag();
After that, try calling your RecyclerView from that instance and use setCurrentItem(). For example, recyclerFrag.recyclerView.setCurrentItem(0).
I have found a solution. You should first create one method in FragmentActivity where is initialized your ViewPager and set return type ViewPager. Something like this:
public ViewPager getViewPager() {
return mViewPager; // instance of view pager
}
After that create object of your Fragment in Activity where you are calling instance of view pager like this:
YourFragment fragment = new YourFragment();
And in my case i should call viewpager in onBackPressed():
HomeFragment fragment1 = new HomeFragment();
if (fragment1.getViewPager().getCurrentItem() == 1 || fragment1.getViewPager().getCurrentItem() == 2) {
fragment1.getViewPager().setCurrentItem(0);
} else {
super.onBackPressed();
}
I'm trying to create an Android application which contains a single activity with a container and a navigation drawer. The initialy empty container loads fragments which has a ViewPager inside a tab layout in which I load a frgment with a FragmentTransaction:
public static void replaceFragmentInContainer(FragmentManager fragmentManager, Fragment fragmentToShow,
boolean addToBackStack)
{
FragmentTransaction transaction = fragmentManager.beginTransaction();
if (addToBackStack)
{
transaction.addToBackStack(null);
}
transaction.replace(R.id.container, fragmentToShow);
transaction.commit();
}
I'm using v4 fragments with a v7 ActionBar in a v7 ActionBarActivity.
Every loaded fragment is a fragment which only loads tabs with other fragments which they hold the actual usability. An example of such tab loading fragment:
public class MainFragment extends TabsFragment
{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
super.onCreateView(inflater, container, savedInstanceState);
View contentView = inflater.inflate(R.layout.fragment_main, container, false);
initTabsLayout(savedInstanceState, contentView, R.id.pager);
addTab("tabspectag1", "", R.drawable.draw1, Fragment1.class, null);
addTab("tabspectag2", "", R.drawable.draw2, Fragment2.class, null);
addTab("tabspectag3", "", R.drawable.draw3, Fragment3.class, null);
return contentView;
}
The problem I'm facing is with the backstack. When a fragment is added to the backstack and I press the back button, the app does go back to the previous fragment like I want to and I see the tabs layout itself, but the content of the tabs is empty like there was nothing loaded to that tab. When it happens, I manage to reload the tab's content only when choosing that screen again with the navigational drawer.
I've tried overriding the onBackPressed in the activity:
#Override
public void onBackPressed()
{
if (getFragmentManager().getBackStackEntryCount() > 0)
{
getFragmentManager().popBackStack();
} else
{
super.onBackPressed();
}
}
but that like I said, it's like I'm getting back to the previous fragment but the tab inside that fragment is not repainting the fragment it had.
What can be done to solve this issue?
Since I DO see the tabs layout of the original fragment in the backstack but not the fragment inside the tab, is it possible I just need to somehow refresh the tab content meaning repaint it? If I can do such a thing then how can I do it?
You didn't post the entire code but, bear in mind that when using fragments inside fragments, the outer fragment should use the childfragmentmanager instead of the regular fragment manager.
If you have an Activity, then you have a fragment that has a Viewpager and inside that viewpager the views are fragments, those outer fragments must use their own childfragmentmanager instead of the activities fragmentmanager.
Activity uses getFragmentManager() to instantiate and show new fragments. Fragments use getChildFragmentManager() to instantiate and show new inner fragments. (fragments inside fragments).
If you always use the same fragmentmanager to handle the transactions the behaviour will be unpredictable.
Your Viewpager should have an TabsAdapter associated that extends from FragmentStatePagerAdapter to show new fragments(and uses the getChildFragmentManager from the fragment instead of the activity).
I want to access a parent Fragment views in a child fragment which is attached with a View Pager. Means Parent Fragment contains a View Pager and View Pager then have a Fragment, and I want to use Parent Fragment Views in current Fragment of Pager.
Parent Fragment---->(Contains)View Pager------>(Contains)Child Fragment. Child Fragment wants to use Parent Fragment multiple views. Please suggest any solution regarding the same.
Thanks in advance.
in your child fragment use:
ParentFragment frag = ((ParentFragment)this.getParentFragment());
and in your parent fragment you can store the references of your required views and use getter setter to access them, another solution is creating a listener interface. follow below link to find out how to implement:
http://developer.android.com/training/basics/fragments/communicating.html
Inside Parent Fragment
ViewPagerAdapter adapter = new ViewPagerAdapter(getChildFragmentManager())
make sure it is getChildFragmentManager()
and inside the child fragment, to access anything from parent fragment
((ParentFragment)this.getParentFragment()).any_thing_inside_parent_fragment;
You can use the below code.
FloatingActionButton fab = getParentFragment().getView().findViewById(R.id.menu_item);
I was trying to get a sibling Fragment using the parent so I tried to use getParentFragment() from the child Fragment and it was always returning null. So instead I just got the fragment from the viewpagerAdapter here's what I did to access a sibling Fragment:
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
mViewPager = (ViewPager) container;
BasePagerAdapter bpa = (BasePagerAdapter) mViewPager.getAdapter();
MySiblingFragment f = (MySiblingFragment) bpa.getItem(1); //I know the position of the fragment so I hardcoded it
}
hopes this will help someone.
I get the variable and view from activity using this
YourActivity activity = (YourActivity) getActivity();
activity.mVar = 1;
activity.textView.setText("Number "+activity.mVar);
I got a xml layout for main activity with some buttons on top of the screens. Below them is placed ViewPager:
<ViewPager android:id="#+id/viewpager">
I also got two fragments in mainactivity.class, each with it's own layout:
frag1 = new Fragment1(); frag2 = new Fragment2(); and viewpager = (ViewPager) findViewById(R.id.viewpager);
Now whats the simplest way to add these two fragments to ViewPager (but without using ActionBar TABS)? I also need to run some code according to which fragment is selected by user, for example make Toast with text "Fragment 2 is selected" when swiped to frag2.
Ok, now I have extended FragmentPagerAdapter: Public class frAdapter extend FragmentPagerAdapter {
public Fragment getItem(int i) { ... }
What I'm supposed to do in getItem() method to add these fragments to viewpager?