I have a Viewpager with two fragments.
I want to replace each of the fragment with 3 different fragments.
How can I do this?
Also, can I change whole ArrayList with the new list of fragments after button click in the current fragment?
Here is what I've done.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_healthy_mode, container, false);
swipeLeft = v.findViewById(R.id.leftSlide);
swipeRight = v.findViewById(R.id.rightSlide);
pageArray = new ArrayList<Fragment>();
pageArray.add(new Female());
pageArray.add(new Male());
healthyModeAdapter = new HealthyModeAdapter(getFragmentManager(), pageArray);
viewPager = (ViewPager) v.findViewById(R.id.healthyModeViewPager);
viewPager.setAdapter(healthyModeAdapter);
// I want to replace female n male fragment with
pageArray.add(new EctoBodyFemale());
pageArray.add(new EndoBodyFemale());
pageArray.add(new MesoBodyFemale());
pageArray.add(new EctoBodyMale());
pageArray.add(new EndoBodyMale());
pageArray.add(new MesoBodyMale());
ViewPager supports operation with Views or Fragments if I understand correctly you want each page each 3 sub components that are static, in such case you have 2 options:
Using nested fragments, create a Fragment for each page that will contain your sub-fragments. and use these parent fragments as the fragments your provide to the pager view
Note that nested fragments are not recommended, they have been proven to be buggy and might affect performances. So I suggest you to take the View approach, create an xml that defines the fragments, and after you inflate it provide it directly to the ViewPager.
Related
I am trying to do something similar as https://stackoverflow.com/a/24437224/2277631. I am even using the same layout:
I am following this approach because I am using a NavigationView (each option is a fragment) that has the first option as a fragment with Tabs (so a ViewPager with more fragments).
I found a problem when using:
viewPager.setAdapter(new AdapterView(getChildFragmentManager()));
Basically, using the ViewPager as nested fragment, it only loads 1 page (from the 3 tabs), and it only loads the other pages when I swipe to them (each tab is a fragment with its ContentLoader). I found that using setOffscreenPageLimitgets ignored in this case. Instead, if I use:
getActivity().getSupportFragmentManager() then the ViewPager works as expected (loading by default 1 page and the next and previous pages). But then, a lot of weird stuff happen (cause I am suppose to use getChildFragmentManager when using nested fragments). So... Any ideas of using ViewPager as nested fragment and make setOffscreenPageLimit to work?
Edit 1 (30 Dec 15)
Tracking the bug down, I checked that all the fragments are been created. The problem is that the three fragments have they own LoaderCallback but only the first one calls onLoadFinished. Trying to figure out why the other fragments only call onLoadFinished when navigating to it (was working without the nested approach).
I ran into the same problem. This is how I do and this is working for me, it has the same architetcure as what you expect to have.
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
view = inflater.inflate(R.layout.communitylayout, container, false);
Bundle data = getArguments();
TabLayout tabLayout = (TabLayout) view.findViewById(R.id.comtabs);
tabLayout.setTabMode(TabLayout.MODE_FIXED);
// add tabs
tabLayout.addTab(tabLayout.newTab());
tabLayout.addTab(tabLayout.newTab());
tabLayout.addTab(tabLayout.newTab());
RelativeLayout layout1 = (RelativeLayout) inflater.inflate(R.layout.communitytablayoutleft, container, false);
RelativeLayout layout2 = (RelativeLayout) inflater.inflate(R.layout.communitytablayout, container, false);
RelativeLayout layout3 = (RelativeLayout) inflater.inflate(R.layout.communitytablayoutright, container, false);
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
pager = (ViewPager) view.findViewById(R.id.compager);
CommunityPagerFragment adapter = new CommunityPagerFragment(getChildFragmentManager());
pager.setAdapter(adapter);
tabLayout.setupWithViewPager(pager);
pager.setCurrentItem(0);
tabLayout.setOnTabSelectedListener(this);
// KEEP FRAGMENT STATE INSIDE OF THE TAB
pager.setOffscreenPageLimit(2);
((TextView)layout1.findViewById(R.id.tabtext)).setText(tabs[0]);
((TextView)layout2.findViewById(R.id.tabtext)).setText(tabs[1]);
((TextView)layout3.findViewById(R.id.tabtext)).setText(tabs[2]);
//tabLayout.set
tabLayout.getTabAt(0).setCustomView(layout1);
tabLayout.getTabAt(1).setCustomView(layout2);
tabLayout.getTabAt(2).setCustomView(layout3);
onTabSelected(tabLayout.getTabAt(1));
//tabLayout.set
return view;
And if you want to get the Tabs working by click in addition of the swipe, add the following:
#Override
public void onTabSelected(TabLayout.Tab tab) {
pager.setCurrentItem(tab.getPosition());
}
I am currently working on an application with ActionBar tabs inside one of its fragments (main navigation is NavigationDrawer). The fragment's onCreate():
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
actionBar = activity.getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
Resources r = getResources();
//(…) tabNames initialization
adapter = new CustomTabAdapter(getFragmentManager());
}
and onCreateView():
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment, container, false);
viewPager = (ViewPager) rootView.findViewById(R.id.pager);
viewPager.setAdapter(adapter);
viewPager.addOnPageChangeListener(this);
for (String tabName : tabNames) {
actionBar.addTab(actionBar.newTab()
.setText(tabName)
.setTabListener(this));
}
return rootView;
}
There are 4 tabs, each of them with its own Fragment and layout. CustomTabAdapter returns new instance of proper fragment in its getItem(int). There are 4 tabs.
And now my problem is:
I start the application.
I choose this tab fragment from NavigationDrawer list. Everything is working just fine.
I choose another fragment from NavigationDrawer list which means that tab fragment is replaced with it.
I choose tab fragment again. And fragment related to tab that was selected before choosing another fragment from NavigationDrawer list, and one's adjacent to it are not recreated (blank screen under ActionBar tabs). I checked and onCreateView(…) methods of those fragment are not called. So after changing device orientation, or choosing tab not adjacent and this one again proper layout is shown.
How can I make it work as it should (showing proper layout on reentering tab fragment from NavigationDrawer list instead of blank space)? I run out of ideas.
Finally, I found a solution. My CustomTabAdapter was extension of FragmentPagerAdapter. I changed it to be extension of FragmentStatePageAdapter, and now fragments are recreated.
More details in this answer by #Louth.
It takes fragments from cache without recreation
I have created a application. Following is scenario before I explain problem.
I have Activity A which has multiple fragments such as F1,F2,F3 etc.
Now for F1 fragment I have implemented FragmentTabHost with three Fragments F11,F12,F13 fragment views. On tab is working fine for this.
But today i noticed one problem.
Say I am inside F1 I show three fragment tabs F11,F12,F13. User can switch between tabs and it works fine.
Problem is say i goto Fragment F13 from F11 by pressing tab. It shows F13 fragment successfully.
However when I click Back Button on menu it goes back F11 fragment but empty screen is shown means F11 view is not shown..
This is my F1 fragment code implementing FragmentTabHost:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.home_fragment, container,
false);
setHasOptionsMenu(true);
// realtabcontent = (FrameLayout) rootView
// .findViewById(R.id.realtabcontent);
mTabHost = (FragmentTabHost) rootView
.findViewById(android.R.id.tabhost);
mTabHost.setup(getActivity(), getChildFragmentManager(),
R.layout.home_fragment);
mTabHost.setOnTabChangedListener(this);
View tabView = createTabView(getActivity(), "Featured");
spec = mTabHost.newTabSpec("featured").setIndicator(tabView);
mTabHost.addTab(spec, FeaturedHomeTab.class, null);
tabView = createTabView(getActivity(), "Top");
spec = mTabHost.newTabSpec("top").setIndicator(tabView);
mTabHost.addTab(spec, TopHomeTab.class, null);
tabView = createTabView(getActivity(), "New");
spec = mTabHost.newTabSpec("new").setIndicator(tabView);
mTabHost.addTab(spec, NewHomeTab.class, null);
onTabChanged("featured");
return rootView;
}
So this is main code with three fragments and when i back from one fragment to previous fragment in tabhost view disappears.
What can be problem. Please help.
Tabs aren't meant to participate in temporal navigation (which is what back nav is for) because they represent content at same level of hierarchy.
In case of fragments, the back nav usually pops the back stack. There is a caveat that back nav doesn't pops sub (child) fragments first. So, the fragments added to Activity are removed on back, this includes the entire tabs fragment (along with its child fragments).
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);
This question already has answers here:
Fragment Inside Fragment
(13 answers)
Closed 9 years ago.
Is there any help, resources, example or a tutorial available for putting fragments inside a fragment?
I have two tabs put up using Action Bar Navigation tabs, which essentially are fragments. What I want to do is, put in a ListFragment and a DialogFragment (to display a view with details) in one of those Action Bar Navigation tabs fragment.
Possible?? Please help. Thanks
Here's what I have done till now:
Followed Android's article on implementing navigation tabs on Action Bar and implemented a two tab action bar, this is running fine and I am able to show two different layouts.
In one of these tabs, I want to show a Fragmented view, for this I have created a FragmentList class with custom ArrayAdapter and data items, the data detail layout and class.
I am now stuck on how to display the fragments inside the tab. Following is the code which shows the content of first tab, how can I modify it to initialize the list fragment properly?
.
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View viewer = (View) inflater.inflate(R.layout.doodle_list, container,false);
return viewer;
}
Is there any help, resources, example or a tutorial available for putting fragments inside a fragment?
Fragments inside of fragments is not supported.
Fragments inside of fragments is supported on Android 4.2+ and via the Android Support package's backport of fragments. I'd still look to avoid it where possible.
I have two tabs put up using Action Bar Navigation tabs, which essentially are fragments.
You chose to do that. There is nothing about action bar tabs that requires the use of fragments.
I solved this problem. You can use Support library and ViewPager. If you don't need swiping by gesture you can disable swiping. So here is some code to improve my solution:
public class TestFragment extends Fragment{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.frag, container, false);
final ArrayList<Fragment> list = new ArrayList<Fragment>();
list.add(new TrFrag());
list.add(new TrFrag());
list.add(new TrFrag());
ViewPager pager = (ViewPager) v.findViewById(R.id.pager);
pager.setAdapter(new FragmentPagerAdapter(getActivity().getSupportFragmentManager()) {
#Override
public Fragment getItem(int i) {
return list.get(i);
}
#Override
public int getCount() {
return list.size();
}
});
return v;
}
}
P.S.It is ugly code for test, but it improves that it is possible.