I'm using TabLayout from Android Design Support Library in my app.
I setup tabs using viewPager in activity's onCreate and they work well.
viewPager.setAdapter(
new TabsAdapter(getSupportFragmentManager(),
new TabInfo("Test1", Fragment1.newInstance()),
new TabInfo("Test2", Fragment2.newInstance()),
new TabInfo("Test3", Fragment3.newInstance())
));
tabs.setupWithViewPager(viewPager);
But sometimes, randomly when screen goes to sleep and I unlock the phone (tested on Moto G 2014, Android Lollipop) tabs just disappear.
It's bad, because I can't reproduce it on purpose.
try using tabhost. It's a lot more stable. The code shown below is an example of a tabhost in a fragment with three child fragments. I use this kind of code myself and works perfectly
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mTabHost = new FragmentTabHost(getActivity());
mTabHost.setup(getActivity(), getChildFragmentManager(), R.id.container);
mTabHost.addTab(mTabHost.newTabSpec("tab1").setIndicator("tab1"),
Tab1Fragment.class, null);
mTabHost.addTab(mTabHost.newTabSpec("tab2").setIndicator("tab2"),
Tab2Fragment.class, null);
mTabHost.addTab(mTabHost.newTabSpec("tab3").setIndicator("tab3"),
Tab3Fragment.class, null);
return mTabHost;
}
Related
I am using a tabhost to hold and navigate multiple fragments. I am not sure what I am doing wrong but the tab is only showing the text but not the icon (I really only need the icon and no text). Fragment 1 and 2 tabs are setup to only show text but on the third fragment tab I try to add in the icon with getDrawable. There is no error everything compiles fine but it just doesn't show the icon.
Thanks for your help.
This is the start of my oncreateView method where I set the tabs up:
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_my_discovered_songs, container, false);
mTabHost = (FragmentTabHost) rootView.findViewById(android.R.id.tabhost);
mTabHost.setup(getActivity(), getChildFragmentManager(), R.id.realtabcontent);
mTabHost.addTab(mTabHost.newTabSpec("fragment1").setIndicator("Fragment 1"),
OneFragment.class, null);
mTabHost.addTab(mTabHost.newTabSpec("fragment2").setIndicator("Fragment 2"),
TwoFragment.class, null);
mTabHost.addTab(mTabHost.newTabSpec("fragment3").setIndicator("Fragment 3", getResources().getDrawable(R.drawable.com_facebook_button_icon)),
ThreeFragment.class, null);
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());
}
How can I create a Fragment with tabs on the top, hosting other Fragments?
I previously used android.support.v4.app.Fragment but switched to android.app.Fragment because of the PreferenceFragment class. My code was:
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_tabs,container, false);
mTabHost = (FragmentTabHost)rootView.findViewById(android.R.id.tabhost);
mTabHost.setup(getActivity(), getChildFragmentManager(), R.id.realtabcontent);
mTabHost.addTab(mTabHost.newTabSpec("fragmentb").setIndicator("Fragment B"),
FragmentB.class, null);
return rootView;
}
But this don't work anymore because setup require a v4-FragmentManager.
Any suggestion how to solve this problem?
Thanks in advance!
As #SubinSebastian answered here :
Add the following project as a library project to your application.
https://github.com/kolavar/android-support-v4-preferencefragment
This solution is better than all other solutions. Add this project as a library project to your workspace. You can keep everything including your fragment transaction as it is and when importing the PreferenceFragment do it like the following.
import android.support.v4.preference.PreferenceFragment;
instead of
import android.preference.PreferenceFragment;
I want to create a layout in which upper half is just some area with normal views and lower half is a tab layout .
I've seen some examples but they're all how to create tabs at activity level i.e by extending TabHostActivity which covers all the activity area.
So i decided to create 2 fragments in the activity ,in which lower fragment will have the tablayout.
But the problem is i cant make this fragment class extend Fragment as well as TabHostActivity...
So any help how could i implement this ?
Here's the lower fragment's code -
public class PFrag extends Fragment {
View mRoot;
TabHost tabHost;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mRoot = inflater.inflate(R.layout.payfrag, container, false);
try {
Resources resources = getResources();
tabHost = (TabHost)mRoot.findViewById(R.id.tabHost);
Intent netbintent = new Intent(getActivity().getApplicationContext(), NB.class);
TabHost.TabSpec tabSpecNB = tabHost.newTabSpec("NB");
tabSpecNB.setIndicator("", resources.getDrawable(R.drawable.netb));
tabSpecNB.setContent(netbintent);
Intent ccardintent = new Intent(getActivity().getApplicationContext(), Cc.class);
TabHost.TabSpec tabSpecCc = tabHost.newTabSpec("CC");
tabSpecCc.setIndicator("", resources.getDrawable(R.drawable.cc));
tabSpecCc.setContent(ccardintent);
tabHost.addTab(tabSpecNB);
tabHost.addTab(tabSpecCc);
} catch(Exception e) {
AlertDialog.Builder ad = new AlertDialog.Builder(getActivity().getApplicationContext());
ad.setMessage(e.toString());
ad.show();
}
return mRoot;
}
}
Sounds like you need to use FragmentTabHost inside your "bottom" fragment.
Another link that could help you out here.
Also, it seems on only work in API 17 and above, so be sure to keep that in mind!
I will not recommend FragmentTabHost its somehow difficult to use and don't have swipe Left-Right. TabHostActivity is also deprecated, use SlidingTabLayout its open source and easily to use and update and have swipe.
SlidingTabLayout
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).