In my previous two posts, I explained how you would implement Tabs using Fragments and then how to implement page swiping using ViewPager. In this post, I’ll bring those two nuggets together and show you how to implement Swipe-able Tabs (i.e switch between tabs using the swipe gesture).
* Caveat Alert * At the time of this posting, there is no way of implementing MapView as a fragment, which may put a spanner in the works if you’re thinking about using this UI pattern with a MapView.
Requirements
To implement a Tabs & ViewPager, using fragments on devices running Android 2.1 or higher, you’ll need to include the Android Compatibility library. In my example, I’m using Compatibility library v4.
Step-by-step
- Define the Tab ViewPager layout
- Define the PagerAdapter
- Define the Tab FragmentActivity
The Code
The Tab ViewPager layout
The Tab ViewPager layout (tabs_viewpager_layout.xml) declares a TabHost and child TabWidget views as per normal. For this implementation, instead of having the dummy FrameLayout to hold the content, we define the ViewPager (android.support.v4.view.ViewPager)
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <TabHost android:id="@android:id/tabhost" android:layout_width="fill_parent" android:layout_height="fill_parent" > <LinearLayout android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TabWidget android:id="@android:id/tabs" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="0" /> <FrameLayout android:id="@android:id/tabcontent" android:layout_width="0dp" android:layout_height="0dp" android:layout_weight="0"/> <android.support.v4.view.ViewPager android:id="@+id/viewpager" android:layout_width="fill_parent" android:layout_height="0dp" android:layout_weight="1" /> </LinearLayout> </TabHost> </LinearLayout>
Define the PagerAdapter
As explained in the previous post, Page Swiping using ViewPager, the PagerAdapter is responsible for creating/returning the appropriate Fragment to the ViewPager. The declaration of PageAdapter is unchanged from the previous post.
/** * */ package com.andy.fragments.viewpager; import java.util.List; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentPagerAdapter; /** * The <code>PagerAdapter</code> serves the fragments when paging. * @author mwho */ public class PagerAdapter extends FragmentPagerAdapter { private List<Fragment> fragments; /** * @param fm * @param fragments */ public PagerAdapter(FragmentManager fm, List<Fragment> fragments) { super(fm); this.fragments = fragments; } /* (non-Javadoc) * @see android.support.v4.app.FragmentPagerAdapter#getItem(int) */ @Override public Fragment getItem(int position) { return this.fragments.get(position); } /* (non-Javadoc) * @see android.support.v4.view.PagerAdapter#getCount() */ @Override public int getCount() { return this.fragments.size(); } }
Define the Tab FragmentActivity
The Tab FragmentActivity is a modified version Tab FragmentActivity I posted about in, Tabs, The Fragment Way. Thankfully, using ViewPager requires less code =)
*Disclaimer: The redundant lines of code are there to illustrate the minimal amount of changes required to implement view paging from the stock Tab implementation*
Change 1: As per the normal initialisation of Tabs, we create Tahhost.TabSpec instances for each tab. In this implementation, we simple just add it to the TabHost (line 139) without having to detach fragments.
Change 2: Initialise the ViewPager. From line 099, we instantiate the Fragments and pass them to the ViewPager via the PagerAdapter. The order that the Fragments are supplied in the List will determine their tab order.
Change 3: Tab FragmentActivity to implement ViewPager.OnPageChangeListener interface. In order to handle page “swipe” events, our Tab FragmentActivity needs to implement the ViewPager.OnPageChangeListener interface. For our purpose we only really need to implement the onPageSelect() method (Line 168). Simply, when the page is selected (paged), it’s associated Tab is selected.
Change 4: Modify the onTabChanged() method. Similarly to Change 3, when a tab is select (and therefore becomes selected), we set the appropriate Fragment via the ViewPager mViewPager (Line 148).
package com.andy.fragments.tabs; import java.util.HashMap; import java.util.List; import java.util.Vector; import android.content.Context; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentActivity; import android.support.v4.view.ViewPager; import android.view.View; import android.widget.TabHost; import android.widget.TabHost.TabContentFactory; import com.andy.R; import com.andy.fragments.viewpager.PagerAdapter; /** * The <code>TabsViewPagerFragmentActivity</code> class implements the Fragment activity that maintains a TabHost using a ViewPager. * @author mwho */ public class TabsViewPagerFragmentActivity extends FragmentActivity implements TabHost.OnTabChangeListener, ViewPager.OnPageChangeListener { private TabHost mTabHost; private ViewPager mViewPager; private HashMap<String, TabInfo> mapTabInfo = new HashMap<String, TabsViewPagerFragmentActivity.TabInfo>(); private PagerAdapter mPagerAdapter; /** * * @author mwho * Maintains extrinsic info of a tab's construct */ private class TabInfo { private String tag; private Class<?> clss; private Bundle args; private Fragment fragment; TabInfo(String tag, Class<?> clazz, Bundle args) { this.tag = tag; this.clss = clazz; this.args = args; } } /** * A simple factory that returns dummy views to the Tabhost * @author mwho */ class TabFactory implements TabContentFactory { private final Context mContext; /** * @param context */ public TabFactory(Context context) { mContext = context; } /** (non-Javadoc) * @see android.widget.TabHost.TabContentFactory#createTabContent(java.lang.String) */ public View createTabContent(String tag) { View v = new View(mContext); v.setMinimumWidth(0); v.setMinimumHeight(0); return v; } } /** (non-Javadoc) * @see android.support.v4.app.FragmentActivity#onCreate(android.os.Bundle) */ protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Inflate the layout setContentView(R.layout.tabs_viewpager_layout); // Initialise the TabHost this.initialiseTabHost(savedInstanceState); if (savedInstanceState != null) { mTabHost.setCurrentTabByTag(savedInstanceState.getString("tab")); //set the tab as per the saved state } // Intialise ViewPager this.intialiseViewPager(); } /** (non-Javadoc) * @see android.support.v4.app.FragmentActivity#onSaveInstanceState(android.os.Bundle) */ protected void onSaveInstanceState(Bundle outState) { outState.putString("tab", mTabHost.getCurrentTabTag()); //save the tab selected super.onSaveInstanceState(outState); } /** * Initialise ViewPager */ private void intialiseViewPager() { List<Fragment> fragments = new Vector<Fragment>(); fragments.add(Fragment.instantiate(this, Tab1Fragment.class.getName())); fragments.add(Fragment.instantiate(this, Tab2Fragment.class.getName())); fragments.add(Fragment.instantiate(this, Tab3Fragment.class.getName())); this.mPagerAdapter = new PagerAdapter(super.getSupportFragmentManager(), fragments); // this.mViewPager = (ViewPager)super.findViewById(R.id.viewpager); this.mViewPager.setAdapter(this.mPagerAdapter); this.mViewPager.setOnPageChangeListener(this); } /** * Initialise the Tab Host */ private void initialiseTabHost(Bundle args) { mTabHost = (TabHost)findViewById(android.R.id.tabhost); mTabHost.setup(); TabInfo tabInfo = null; TabsViewPagerFragmentActivity.AddTab(this, this.mTabHost, this.mTabHost.newTabSpec("Tab1").setIndicator("Tab 1"), ( tabInfo = new TabInfo("Tab1", Tab1Fragment.class, args))); this.mapTabInfo.put(tabInfo.tag, tabInfo); TabsViewPagerFragmentActivity.AddTab(this, this.mTabHost, this.mTabHost.newTabSpec("Tab2").setIndicator("Tab 2"), ( tabInfo = new TabInfo("Tab2", Tab2Fragment.class, args))); this.mapTabInfo.put(tabInfo.tag, tabInfo); TabsViewPagerFragmentActivity.AddTab(this, this.mTabHost, this.mTabHost.newTabSpec("Tab3").setIndicator("Tab 3"), ( tabInfo = new TabInfo("Tab3", Tab3Fragment.class, args))); this.mapTabInfo.put(tabInfo.tag, tabInfo); // Default to first tab //this.onTabChanged("Tab1"); // mTabHost.setOnTabChangedListener(this); } /** * Add Tab content to the Tabhost * @param activity * @param tabHost * @param tabSpec * @param clss * @param args */ private static void AddTab(TabsViewPagerFragmentActivity activity, TabHost tabHost, TabHost.TabSpec tabSpec, TabInfo tabInfo) { // Attach a Tab view factory to the spec tabSpec.setContent(activity.new TabFactory(activity)); tabHost.addTab(tabSpec); } /** (non-Javadoc) * @see android.widget.TabHost.OnTabChangeListener#onTabChanged(java.lang.String) */ public void onTabChanged(String tag) { //TabInfo newTab = this.mapTabInfo.get(tag); int pos = this.mTabHost.getCurrentTab(); this.mViewPager.setCurrentItem(pos); } /* (non-Javadoc) * @see android.support.v4.view.ViewPager.OnPageChangeListener#onPageScrolled(int, float, int) */ @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { // TODO Auto-generated method stub } /* (non-Javadoc) * @see android.support.v4.view.ViewPager.OnPageChangeListener#onPageSelected(int) */ @Override public void onPageSelected(int position) { // TODO Auto-generated method stub this.mTabHost.setCurrentTab(position); } /* (non-Javadoc) * @see android.support.v4.view.ViewPager.OnPageChangeListener#onPageScrollStateChanged(int) */ @Override public void onPageScrollStateChanged(int state) { // TODO Auto-generated method stub } }
Jeff Linwood (@jefflinwood)
October 15, 2011 at 09:38
It looks like there’s a workaround for using MapView within a Fragment – https://github.com/petedoyle/android-support-v4-googlemaps
I’ll probably try this out a little later. Thanks for the great series of blog posts about Fragments and View Pager!
mitchwongho
October 15, 2011 at 14:22
Hi Jeff.
Thanks for visiting. I’m glad you found the posts useful =)
Also, thanks for the project reference. I do hope that the Google Android team consider giving the MapView the Fragment treatment
Akinsete Sunday
June 26, 2012 at 08:34
I tried this but am getting some errors. Please help..Maybe you need to paste codes for Tab1Fragment.class,Tab2Fragment.class as well
Jeff Linwood (@jefflinwood)
October 15, 2011 at 16:02
I actually ran into some really strange class loader issues with Dalvik when I used the precompiled lib from that page last night. Replacing it with the stock compatibility library made the issues go away, so I think I may need to try building it from source.
Yes, your posts are the best I’ve seen on fragments and View Pager!
Mike Stone
October 17, 2011 at 21:48
Thanks a lot. This helped me get to where I am…multiple tabs with swipe support!
I have a quick question though. The transition or scrolling while swiping isn’t the smoothest. Do you know of a way I can make this better?
Thanks
Mike
mitchwongho
October 18, 2011 at 00:38
Hi Mike,
Thanks for visiting. I’m glad you’ve found the posts helpful.
Are you testing on an HTC by any chance? I suspect that the Sense UI has something to do with it as I’ve heard similar concerns in the past.
I’m running this demo on a Huewei 858 Android 2.2 phone (a real low end device) and the transitions are smooth. In other words, I don’t have a solution for you 🙂
Please let us know if you do resolve the issue.
Mike Stone
October 18, 2011 at 00:43
Thanks for the response.
I am running on a Nexus S. currently running 2.3.1.
I will keep you up to date with my findings!
Thanks again.
Mike
Alex
November 8, 2011 at 12:16
Hi,
thanks alot for that post helped me alot.
I have one Question.
I have build an app with 3 Tabs like in your tutorial.
On tab1 there is a listview filled by async task.
On tab2 is an streight forward linearlayout some images an so on and
on the 3rd tab there is an expandableListview. All works fine together.
My App starts on tab2 causing tab1 and 3 to call onviewcreate. But when I swipe from tab2 to tab1, tab 3 calls onviewdestroy. When I swipe back to tab2, tab3 calls onviewcreate again. The same with tab1 when i swipe to tab3.
So every time the data gets downladed by that async task.
My Question is there a way to once load the tabs for the runtime of the app. And dont recreate every time?
Sure I could use database to store the data but even then the tabs gets recreated over and over again. I want that to disable. Is that even posible?
Appriciate your answer.
Thanks
Alex
Mike Stone
November 9, 2011 at 18:24
ViewPager.setOffscreenPageLimit using the compatilibty library v4
See: http://developer.android.com/sdk/compatibility-library.html
Look under ViewPager
“Added support to control how many pages are kept to either side of the current page.”
mitchwongho
November 10, 2011 at 09:27
Thanks for the reference, Mike.
At some point, you’ll need to save the state of the Fragment (either for orientation changes or when your app gets moved to the background).
Consider using FragmentStatePagerAdapter instead.
Alex
November 10, 2011 at 10:53
Thanks for your reply Mike.
The expirience of using the app is much better now.
Thanks.
aimango
January 25, 2012 at 03:05
Hey, for some reason I’m not able to use setOffscreenPageLimit with my ViewPager. I have revision 6 for the support package, though. Do you know how to fix this problem?
Thanks!
aimango
January 25, 2012 at 03:12
Ignore my last comment – I figured it out!
Fahad
August 5, 2014 at 06:31
Hie Alex,
I also want to include expandable list on tabs, can you please help me in this regard, I am badly stuck.
pop
November 9, 2011 at 13:48
Can you upload source code ?
I tried but i always showed “force close”.
Many thanks to you 🙂
mitchwongho
November 10, 2011 at 10:12
I’ve just put the project onto GitHub
https://mitchwongho@github.com/mitchwongho/Andy.git
pop
November 12, 2011 at 13:13
Thank you so much !
It worked 😀
deepikalalra Lalra
October 11, 2012 at 12:33
* should have a dot before class name(IndexActivity) in menifest file.
* best approch is to include library file(android-support-v4) in libs folder of application.
Chan
November 13, 2011 at 17:02
@mitchwongho: Could you upload the source again? The link was broken. And thanks for a great tut.
syrine
November 14, 2011 at 16:35
hey
awesome tutorial it helped me a lot , but i’ve noticed that on orientation changed it provoke an NPE it can’t find the current tab
11-14 15:27:10.231: E/AndroidRuntime(13788): Caused by: java.lang.NullPointerException
11-14 15:27:10.231: E/AndroidRuntime(13788): at com.some.Thing.other.Activities.onTabChanged(MyTabActivity.java:153)
11-14 15:27:10.231: E/AndroidRuntime(13788): at android.widget.TabHost.invokeOnTabChangeListener(TabHost.java:378)
11-14 15:27:10.231: E/AndroidRuntime(13788): at android.widget.TabHost.setCurrentTab(TabHost.java:363)
11-14 15:27:10.231: E/AndroidRuntime(13788): at android.widget.TabHost.setCurrentTabByTag(TabHost.java:285)
11-14 15:27:10.231: E/AndroidRuntime(13788): at com.some.Thing.other.Activities.MyTabActivity.onCreate(MyTabActivity.java:84)
i’m i the only one who have this problem?
syrine
November 14, 2011 at 17:04
the problem was this couple of lines
081 if (savedInstanceState != null) {
082 mTabHost.setCurrentTabByTag(savedInstanceState.getString(“tab”)); //set the tab as per the saved state
083
}
i’ve commented it and it’s ok now ..i don’t know if it’s a good idea to ignore this lines (you can tell me) but it solved my problem 😉
mitchwongho
November 15, 2011 at 10:57
Hi,
Thanks for visiting. One thing I haven’t implemented in the examples is saving state. This is what is causing the Exception. What you’ll need to do, is save the active Fragment in the bundle, and then read it back to switch to the appropriate Fragment
blubberheld
June 25, 2012 at 16:12
Hi,
i know it’s been a while.
But i don’t get it to fix the rotation problem.
could you please help me
AKeyWeb
November 15, 2011 at 10:33
What would be the easiest way to remove a tab, add new ones and replace the fragment within a tab both at the end and at a specific position?
mitchwongho
November 15, 2011 at 11:24
Hi,
Thanks for visiting.
That is a great questions! I don’t believe there is a simple way. As a follow up from another reader asking how to implement a Carousel-style of ViewPager, I discovered that the FragmentManager tags each Fragment with it’s position in the deck, so manipulating the order and behaviour of the FragmentManager is not a simple task.
One option is manage different views based on the Activity’s context (i.e inflate a different layout based on state or context). Changing the Tab’s label should be straight forward)
Let us know how if you find another way.
Newby1
November 23, 2011 at 16:03
Mitch,
I am just learning writing for android with Eclipse. I have your example running in the emulator at this time. My question is this: If I want to add a ListView into the Tab1Fragment is it done within a Tab1Fragment class event or should a ListFragment class be created and then called from the Tab1Fragment class?
Great tutorial.
mitchwongho
November 23, 2011 at 16:33
Hi,
You’d create layout that declares a ListView (e.g res/layout/mylist_layout.xml with id=mylist_layout) and then inflate that layout in the onCreate() method of Tab1Fragment i,e
View view = inflater.inflate(R.layout.mylist_layout, container, false);
CuriousCursor
November 25, 2011 at 03:05
https://github.com/JakeWharton/Android-ViewPagerIndicator
doctor
December 20, 2011 at 18:22
hello, i test Force close. this my logcat :
12-20 23:19:58.020: E/AndroidRuntime(25176): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.tab.pager/com.tab.pager.TabFragment}: java.lang.ClassCastException: com.tab.pager.Tab1Fragment
12-20 23:19:58.020: E/AndroidRuntime(25176): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1768)
12-20 23:19:58.020: E/AndroidRuntime(25176): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1784)
12-20 23:19:58.020: E/AndroidRuntime(25176): at android.app.ActivityThread.access$1500(ActivityThread.java:123)
12-20 23:19:58.020: E/AndroidRuntime(25176): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:939)
12-20 23:19:58.020: E/AndroidRuntime(25176): at android.os.Handler.dispatchMessage(Handler.java:99)
12-20 23:19:58.020: E/AndroidRuntime(25176): at android.os.Looper.loop(Looper.java:130)
12-20 23:19:58.020: E/AndroidRuntime(25176): at android.app.ActivityThread.main(ActivityThread.java:3835)
12-20 23:19:58.020: E/AndroidRuntime(25176): at java.lang.reflect.Method.invokeNative(Native Method)
12-20 23:19:58.020: E/AndroidRuntime(25176): at java.lang.reflect.Method.invoke(Method.java:507)
12-20 23:19:58.020: E/AndroidRuntime(25176): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
12-20 23:19:58.020: E/AndroidRuntime(25176): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
12-20 23:19:58.020: E/AndroidRuntime(25176): at dalvik.system.NativeStart.main(Native Method)
12-20 23:19:58.020: E/AndroidRuntime(25176): Caused by: java.lang.ClassCastException: com.tab.pager.Tab1Fragment
12-20 23:19:58.020: E/AndroidRuntime(25176): at android.support.v4.app.Fragment.instantiate(Fragment.java:377)
12-20 23:19:58.020: E/AndroidRuntime(25176): at android.support.v4.app.Fragment.instantiate(Fragment.java:352)
12-20 23:19:58.020: E/AndroidRuntime(25176): at com.tab.pager.TabFragment.intialiseViewPager(TabFragment.java:102)
12-20 23:19:58.020: E/AndroidRuntime(25176): at com.tab.pager.TabFragment.onCreate(TabFragment.java:85)
12-20 23:19:58.020: E/AndroidRuntime(25176): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
12-20 23:19:58.020: E/AndroidRuntime(25176): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1722)
thanks before. 😀
mitchwongho
December 20, 2011 at 21:48
Hi,
Are you getting this when you run the reference code? Else, you can post your code and we can have a look to see where the error is originating from.
Stalski
December 31, 2011 at 22:38
This post is really awesome as well (I read the previous ones too, and tried them out). This swipe behavior is just what I was looking for. I don’t know if this is advanced or not, but I can assure your that this is clear to a non-java programmer who tries to create his first android app.
Great you shared this with us.
Madhav Palshikar
January 2, 2012 at 10:49
Nice tutorial…
how to add button onclick method in viewpager…? plz help
Thank you for tutorial.
mitchwongho
January 3, 2012 at 08:45
Hi Madhav,
There are two ways to handle Button onClick events wrt Fragments:
1. Events are received by the FragmentActivity, so you’ll need to implement the event handler in the FragmentActivity implementation and then delegate it back to the active Fragment, or
2. in the Fragment that contains the Button, find the Button component (using findViewById()) and register your event handler using the Button.onClick() method.
frontine
January 18, 2012 at 06:46
hi mitchwongho
i’m implemented listview data from json in this tutorial. i make 4 tabs, listview i put in first tab, then i choose third tab and then back to first tab, listview reload again but if i choose beside first tab, firsttab (listview not reload).
can you help me how to solved?
if can i send my project to your email.
sorry for my bad english,
i’m from Indonesia.hehe
angie2312
January 25, 2012 at 13:26
you have to add mViewPager.setOffscreenPageLimit(4); (http://developer.android.com/reference/android/support/v4/view/ViewPager.html#setOffscreenPageLimit(int))
Sohayb
January 18, 2012 at 14:35
Hi; this is rly nice. But i need help; how to replace the fragments by FragmentActivities and maintain the work of the viewPager? whenever i try to replace fragments by FragmentActivities the tabs display nothing at all!!
Sushil
February 3, 2012 at 12:51
Hi Mitchwongho,
Thank you for your very impressive tutorial. I downloaded your code from git and tried to run it on my Nexus S and Galaxy S2. In both the phones I am not able to see the tabs. It is just working as your page viewer tutorial where I can only swipe among 3 pages. The tabs are not at all visible. Can you please help.
Thanks,
Sushil
Sushil
February 3, 2012 at 13:38
Hi,
I got the reason why tab was not coming for me. I had to change the AndroidManifest file to launch correct activity. Thanks anyway.
Cheers,
Sushil
pankajchunchun
February 14, 2012 at 13:18
Hi mitchwongho I have implemented the same code as it is. I am getting NPE when orientation change and when onpouse method called. Any thing wrong?
tadinesh
February 15, 2012 at 11:19
Hi,
If I rotate this app it force close 😦 what to do?
ZonedCode Media
February 23, 2012 at 01:35
Wow! Thank you so much! I spent some three days trying to get my tabs to swipe. I tried everything, including recreating the sample code in my own project. Nothing worked, until this! I spent five minutes just dancing around my house when it worked because I was so happy/relieved (thank goodness I was alone).
Thank you, again!
Paulo Ricardo
March 16, 2012 at 14:12
Hello Mitchwongho,
Could you tell me if there is any way to change fragment within each tab? I tried to do with your example, but the fragment does not appear.
FragmentTransaction getFragmentManager ft = (). BeginTransaction ();
ft.replace (R.id.viewpager, new TabFragmen1t ());
ft.setTransition (FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.addToBackStack (null);
ft.commit ();
Andy
March 19, 2012 at 14:49
i copied ur code as it is i m new android developer i m getting error in tab1Fragment.class i m not understanding what this class means is it extended to activity
Vinc3nt
March 29, 2012 at 17:02
Thank u for this post. I have 5 Tabs and when i swipe very fast, the tabs skips for example from tab 2 to tab 4. Do you know how to solve this problem?
Ammon R.
March 31, 2012 at 23:32
Hey!
First off great tutorial!! I’m new to programming and this may be a stupid question but I’ve been searching for the solution everywhere with no luck. i’m getting this error
The constructor MyPageAdapter(FragmentManager, List) is undefined
Here is my code
List fragments = new Vector();
fragments.add(Fragment.instantiate(this, article1.class.getName()));
fragments.add(Fragment.instantiate(this, article2.class.getName()));
fragments.add(Fragment.instantiate(this, article3.class.getName()));
this.mPagerAdapter = new MyPageAdapter(getSupportFragmentManager(), fragments);
any ideas on how to fix this error i would very much appreciate!!
Thanks again!
stevemuss
April 16, 2012 at 14:07
How do I replace one of the fragments?
stevemuss
April 16, 2012 at 14:09
How do I replace a fragment?
Glenn
April 18, 2012 at 10:03
hi there mitchwongho,
A very nice tutorial.. been reading a lot about fragments.. I have a few questions though
1. how to include a drawable/picture on top of the tab names/items
2. how to implement an two activity with a tab, somewhat look like this:
tab1 / tab2 / tab3
/ /
act1 / act2/act4 / act3
* like for instance, there’s two activity (act3 & act4) inside tab2.. by showing the (act4) you put/push a button2 and put/push button1 to show act3.
hope you can give me some insights on this. thank you
Glenn
April 18, 2012 at 10:12
sorry.. what i mean is.. ** two activity within a tab act2/act4**
then show act4 by pressing button2—-
and show act2 by pressing button1—–
i happened to observed this on TED 1.0.5 app..
thanks once again…
fullbugz
May 2, 2012 at 09:08
@mitchwongho
this is usefull tutorial. thanks
I have a question?
If i have 10 tab in the tab control? how do i page those tabs too? i mean we can slice left or right on the tab control to select this tab? it look like the listview, but oriented to horizontal
thanks
slippyboy
May 3, 2012 at 05:13
Reblogged this on Slippyboy's Blog.
newjay08
May 10, 2012 at 11:00
Hi, I got a “NullPointerException” here:
mTabHost = (TabHost)findViewById(android.R.id.tabhost);
mTabHost.setup();
newjay08
May 10, 2012 at 11:02
Hi! I got a “NullPointerException” here:
mTabHost = (TabHost)findViewById(android.R.id.tabhost);
mTabHost.setup();
newjay08
May 10, 2012 at 11:06
I solved it. Nice tutorial.
newjay08
May 11, 2012 at 05:06
Hi, can you help me with this one. I only one Fragment class instead of three. The problem is I can’t set programmatically the content of my fragment class. Here’s my changes from your code.
***TabsViewPagerFragmentActivity****
Bundle bundle1 = new Bundle();
Bundle bundle2 = new Bundle();
Bundle bundle3 = new Bundle();
bundle1.putInt(“id”, 1);
bundle2.putInt(“id”, 2);
bundle3.putInt(“id”, 3);
FragmentTabsPagerActivity.addTab(this, this.mTabHost, this.mTabHost.newTabSpec(“Tab1”).setIndicator(“Tab 1”), (tabInfo = new TabInfo(“Tab1”, TabsFragment.class, bundle1)));
FragmentTabsPagerActivity.addTab(this, this.mTabHost, this.mTabHost.newTabSpec(“Tab2”).setIndicator(“Tab 2”), (tabInfo = new TabInfo(“Tab2”, TabsFragment.class, bundle2)));
FragmentTabsPagerActivity.addTab(this, this.mTabHost, this.mTabHost.newTabSpec(“Tab3”).setIndicator(“Tab 3”), (tabInfo = new TabInfo(“Tab3”, TabsFragment.class, bundle3)));
I want a different contents of each tab. How do I dynamically set the content of each tab.
Here my question at stackoverflow: http://stackoverflow.com/questions/10544602/set-webview-loadurl-programmatically-that-is-in-fragment-class
newjay08
May 11, 2012 at 05:08
Hi, can you help me with this one? I only have one Fragment class instead of three. The problem is I can’t set programmatically the content of my fragment class. Here’s my changes from your code.
***TabsViewPagerFragmentActivity****
Bundle bundle1 = new Bundle();
Bundle bundle2 = new Bundle();
Bundle bundle3 = new Bundle();
bundle1.putInt(“id”, 1);
bundle2.putInt(“id”, 2);
bundle3.putInt(“id”, 3);
FragmentTabsPagerActivity.addTab(this, this.mTabHost, this.mTabHost.newTabSpec(“Tab1”).setIndicator(“Tab 1”), (tabInfo = new TabInfo(“Tab1”, TabsFragment.class, bundle1)));
FragmentTabsPagerActivity.addTab(this, this.mTabHost, this.mTabHost.newTabSpec(“Tab2”).setIndicator(“Tab 2”), (tabInfo = new TabInfo(“Tab2”, TabsFragment.class, bundle2)));
FragmentTabsPagerActivity.addTab(this, this.mTabHost, this.mTabHost.newTabSpec(“Tab3”).setIndicator(“Tab 3”), (tabInfo = new TabInfo(“Tab3”, TabsFragment.class, bundle3)));
I want a different contents of each tab. How do I dynamically set the content of each tab.
Here my question at stackoverflow: http://stackoverflow.com/questions/10544602/set-webview-loadurl-programmatically-that-is-in-fragment-class
Ryan
June 20, 2012 at 16:32
Great tutorial!!! 1 problem is when having a ListView on a fragment. The ListView intercepts the touch events and I can no longer swipe left and right (probably because the ListView blocks the swipes and is trying to use the touch events for itself). Any solution to this?????
mitchwongho
June 21, 2012 at 00:26
Odd. ListView would catch vertical swipes while paging would handle horizontal swipes. Are you using a ListView Fragment?
shahzadrocks
July 5, 2012 at 08:08
Reblogged this on AndroidForAll and commented:
Slide Tabs With ViewPager
shahzadrocks
July 5, 2012 at 08:11
Nice one…I downloaded the zip file but its showing error….though i have included compatibilty library ….+1 to u Reblogged it
Renato Canha Ambrosio
July 7, 2012 at 19:08
Hello,
Your code is exactly what I was looking for. I copy all .java and .xml code to Eclipse. No erros but does not worked. Probably I need to modify the AndroidManifest to declare the Activities. I thing PagerAdapter and TabsViewPagerFragmentActivity are not Activities to declate on AndroidManifest, right?
Could you help me with some tips to solve this problem?
I am not a programming, I am a Chemistry professor.
Eddie
July 8, 2012 at 21:20
Love this tutorial. I’d like to see a fourth continuation in the series. Where and how do we insert elements/data/actions/lists etc? In the above example, the body is blank — except for the color defined in the layout. I’d love to see where do put the “meat” of the content in relation to the above. Buttons, Lists, AsyncTasks, etc…
Mal Clarke
July 10, 2012 at 16:07
ROTATE PROBLEM FIX
I had headaches over this one. But managed to fix it.
Add to each of your TabXFragment.java classes
@Override
public void onSaveInstanceState(Bundle outState) {
outState.putString(“tab”, “Tab1”); //save the tab selected
super.onSaveInstanceState(outState);
}
changing the Tab1 for TabX. Solved it for me.
Happy coding 🙂
Renato Canha Ambrosio
July 13, 2012 at 14:17
Hello
I included several buttons on xml fragments. I would like to know how to adapt the java code in these fragments to suport buttons.
Ivan
July 15, 2012 at 11:08
Great article!
Is it possible to move actionBar to bottom?
mitchwongho
July 17, 2012 at 15:48
Checkout : http://stackoverflow.com/questions/5014002/how-to-set-tab-bar-at-the-bottom
Oattoreto
July 30, 2012 at 04:22
Hi
First , Thanks for Tutor, useful
But i have a question ..
Can i set CurrentTab ?
and how?
thk alot
Abhinov
August 10, 2012 at 11:56
Hello
I am completely new to android and even i am not good in programming i liked ur tutorial a lot its really nice i have a small doudt u said to add the Android Compatibility library i didnt get u where do we need to add the compatibility file so we import it and add that file going into properties and add libraries.and when we give the .apk file to the user we will not give the compatability file right then how will it run.should we keep both the files in different packages in the same project what should i do exactly plz “mitchwongho” help me and i dont find any supporting libraries at android developers to download plz rly me fast…
Thanks A lot In Advance
ismarslomic
August 15, 2012 at 22:04
Hi! Great blog!
I have re-used most of your code in my app, but I’m experiencing very strange behavior. One of my fragments is a LisftFragment which is initiated and added to the list of fragments at intialiseViewPager() as in your example. The ListFragment is setting the ListAdapter at its onActivityCreated() method.
Now, here comes the strange behaviour. When I debug the application and I hold the mobile vertically one ListFragment is created and the ListAdapter is set at onActivityCreated method correctly. When I rotate the mobile horizontally two ListFragments are created, but the onActivityCreated() is called only once (for only one of the ListFragment instances).
The first instance of ListFragment is calling the onActivityCreated() and setting the ListAdapter. It seems like the super.onCreate(savedInstanceState) in FragmentActivity.onCreate(Bundle savedInstanceState) method is creating this instance (WHY??). This ListFragment is not added to the mPagerAdapter.
The second instance of ListFragment is created from intialiseViewPager() as in your tutorial, it is also added to the mPagerAdapter but the onActivityCreated() is never called and therefor ListAdapter is also empty.
Now, the second strange thing is that I can still see all the data in ListView horizontally as vertically mode.
So I could just ignore this issue since the user doesn’t see it, but the thing is that I want to get the ListAdapter of current fragment (tab) in FragmentActivity and line 4 below will be null when i switch to horizontal mode.
1. int pos = this.mTabHost.getCurrentTab();
2. PagerAdapter pa = (PagerAdapter)this.mViewPager.getAdapter();
3. MyListFragment f = (MyListFragment)pa.getItem(pos);
4. ListAdapter la = f.getListAdapter()
I’m very confused and I have spent lot of time debugging this. I understand if my explanation is very bad and that you might need some clarifications. Just let me know!
Thanks for your time!
Ismar
willem
August 23, 2012 at 22:50
Hi,
Great tutorial.
Do you know the best way to remove the “padding” above the text?
I have tried to set padding to 0dp in the xml in various places, but that doesn’t seem to work.
I dislike to big empty space on top of the text, makes it eat more space than required.
Thanks.
willem
August 24, 2012 at 22:30
Maybe interesting for other people here. I like the following approach better:
http://developer.android.com/reference/android/support/v4/view/PagerTabStrip.html
This will give you a similar swipeable tabs as in the Play Store.
David Greenfield (@energyAlchemist)
August 31, 2012 at 10:33
Awesome post, thanks
Magnus
October 1, 2012 at 16:01
Hi
Awesome Tutorial and everything was really helpful, I’ve got one problem though.
My FragmentActivity-extended class (ActivityMain) is having some issues regarding it’s superclass.
Logcat:
10-01 15:48:58.695: D/dalvikvm(28280): Late-enabling CheckJNI
10-01 15:48:58.780: W/dalvikvm(28280): Unable to resolve superclass of Lcom/plingnote/ActivityMain; (20)
10-01 15:48:58.780: W/dalvikvm(28280): Link of class ‘Lcom/plingnote/ActivityMain;’ failed
10-01 15:48:58.780: D/AndroidRuntime(28280): Shutting down VM
10-01 15:48:58.780: W/dalvikvm(28280): threadid=1: thread exiting with uncaught exception (group=0x40c5d1f8)
10-01 15:48:58.790: E/AndroidRuntime(28280): FATAL EXCEPTION: main
10-01 15:48:58.790: E/AndroidRuntime(28280): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.plingnote/com.plingnote.ActivityMain}: java.lang.ClassNotFoundException: com.plingnote.ActivityMain
10-01 15:48:58.790: E/AndroidRuntime(28280): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1894)
10-01 15:48:58.790: E/AndroidRuntime(28280): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1995)
10-01 15:48:58.790: E/AndroidRuntime(28280): at android.app.ActivityThread.access$600(ActivityThread.java:128)
10-01 15:48:58.790: E/AndroidRuntime(28280): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1161)
10-01 15:48:58.790: E/AndroidRuntime(28280): at android.os.Handler.dispatchMessage(Handler.java:99)
10-01 15:48:58.790: E/AndroidRuntime(28280): at android.os.Looper.loop(Looper.java:137)
10-01 15:48:58.790: E/AndroidRuntime(28280): at android.app.ActivityThread.main(ActivityThread.java:4517)
10-01 15:48:58.790: E/AndroidRuntime(28280): at java.lang.reflect.Method.invokeNative(Native Method)
10-01 15:48:58.790: E/AndroidRuntime(28280): at java.lang.reflect.Method.invoke(Method.java:511)
10-01 15:48:58.790: E/AndroidRuntime(28280): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:993)
10-01 15:48:58.790: E/AndroidRuntime(28280): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:760)
10-01 15:48:58.790: E/AndroidRuntime(28280): at dalvik.system.NativeStart.main(Native Method)
10-01 15:48:58.790: E/AndroidRuntime(28280): Caused by: java.lang.ClassNotFoundException: com.plingnote.ActivityMain
10-01 15:48:58.790: E/AndroidRuntime(28280): at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:61)
10-01 15:48:58.790: E/AndroidRuntime(28280): at java.lang.ClassLoader.loadClass(ClassLoader.java:501)
10-01 15:48:58.790: E/AndroidRuntime(28280): at java.lang.ClassLoader.loadClass(ClassLoader.java:461)
10-01 15:48:58.790: E/AndroidRuntime(28280): at android.app.Instrumentation.newActivity(Instrumentation.java:1027)
10-01 15:48:58.790: E/AndroidRuntime(28280): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1885)
10-01 15:48:58.790: E/AndroidRuntime(28280): … 11 more
Any help is appreciated :)!
amit
October 13, 2012 at 11:30
ERROR/AndroidRuntime(1264): Caused by: java.lang.ClassCastException:
help me
import java.util.HashMap;
import java.util.List;
import java.util.Vector;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.ViewPager;
import android.view.View;
import android.widget.TabHost;
import android.widget.TabHost.TabContentFactory;
/**
* The
TabsViewPagerFragmentActivity
class implements the Fragment activity that maintains a TabHost using a ViewPager.* @author mwho
*/
public class TabsViewPagerFragmentActivity extends FragmentActivity implements TabHost.OnTabChangeListener, ViewPager.OnPageChangeListener {
private TabHost mTabHost;
private ViewPager mViewPager;
private HashMap mapTabInfo = new HashMap();
private PagerAdapter mPagerAdapter;
/**
*
* @author mwho
* Maintains extrinsic info of a tab’s construct
*/
private class TabInfo {
private String tag;
private Class clss;
private Bundle args;
private Fragment fragment;
TabInfo(String tag, Class clazz, Bundle args) {
this.tag = tag;
this.clss = clazz;
this.args = args;
}
}
/**
* A simple factory that returns dummy views to the Tabhost
* @author mwho
*/
class TabFactory implements TabContentFactory {
private final Context mContext;
/**
* @param context
*/
public TabFactory(Context context) {
mContext = context;
}
/** (non-Javadoc)
* @see android.widget.TabHost.TabContentFactory#createTabContent(java.lang.String)
*/
public View createTabContent(String tag) {
View v = new View(mContext);
v.setMinimumWidth(0);
v.setMinimumHeight(0);
return v;
}
}
/** (non-Javadoc)
* @see android.support.v4.app.FragmentActivity#onCreate(android.os.Bundle)
*/
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Inflate the layout
setContentView(R.layout.tabs_viewpager_layout);
// Initialise the TabHost
this.initialiseTabHost(savedInstanceState);
if (savedInstanceState != null) {
mTabHost.setCurrentTabByTag(savedInstanceState.getString(“tab”)); //set the tab as per the saved state
}
// Intialise ViewPager
this.intialiseViewPager();
}
/** (non-Javadoc)
* @see android.support.v4.app.FragmentActivity#onSaveInstanceState(android.os.Bundle)
*/
protected void onSaveInstanceState(Bundle outState) {
outState.putString(“tab”, mTabHost.getCurrentTabTag()); //save the tab selected
super.onSaveInstanceState(outState);
}
/**
* Initialise ViewPager
*/
private void intialiseViewPager() {
List fragments = new Vector();
fragments.add(Fragment.instantiate(this, Next.class.getName()));
fragments.add(Fragment.instantiate(this, Latest.class.getName()));
fragments.add(Fragment.instantiate(this, Metrics.class.getName()));
this.mPagerAdapter = new PagerAdapter(super.getSupportFragmentManager(), fragments);
//
this.mViewPager = (ViewPager)super.findViewById(R.id.viewpager);
this.mViewPager.setAdapter(this.mPagerAdapter);
this.mViewPager.setOnPageChangeListener(this);
}
// ERROR/AndroidRuntime(1066): Caused by: java.lang.ClassCastException
/**
* Initialise the Tab Host
*/
private void initialiseTabHost(Bundle args) {
mTabHost = (TabHost)findViewById(android.R.id.tabhost);
mTabHost.setup();
TabInfo tabInfo = null;
TabsViewPagerFragmentActivity.AddTab(this, this.mTabHost, this.mTabHost.newTabSpec(“Tab1”).setIndicator(“Tab 1”), ( tabInfo = new TabInfo(“Tab1”, Next.class, args)));
this.mapTabInfo.put(tabInfo.tag, tabInfo);
TabsViewPagerFragmentActivity.AddTab(this, this.mTabHost, this.mTabHost.newTabSpec(“Tab2”).setIndicator(“Tab 2”), ( tabInfo = new TabInfo(“Tab2”, Latest.class, args)));
this.mapTabInfo.put(tabInfo.tag, tabInfo);
TabsViewPagerFragmentActivity.AddTab(this, this.mTabHost, this.mTabHost.newTabSpec(“Tab3”).setIndicator(“Tab 3”), ( tabInfo = new TabInfo(“Tab3”, Metrics.class, args)));
this.mapTabInfo.put(tabInfo.tag, tabInfo);
// Default to first tab
//this.onTabChanged(“Tab1”);
//
mTabHost.setOnTabChangedListener(this);
}
/**
* Add Tab content to the Tabhost
* @param activity
* @param tabHost
* @param tabSpec
* @param clss
* @param args
*/
private static void AddTab(TabsViewPagerFragmentActivity activity, TabHost tabHost, TabHost.TabSpec tabSpec, TabInfo tabInfo) {
// Attach a Tab view factory to the spec
tabSpec.setContent(activity.new TabFactory(activity));
tabHost.addTab(tabSpec);
}
/** (non-Javadoc)
* @see android.widget.TabHost.OnTabChangeListener#onTabChanged(java.lang.String)
*/
public void onTabChanged(String tag) {
//TabInfo newTab = this.mapTabInfo.get(tag);
int pos = this.mTabHost.getCurrentTab();
this.mViewPager.setCurrentItem(pos);
}
/* (non-Javadoc)
* @see android.support.v4.view.ViewPager.OnPageChangeListener#onPageScrolled(int, float, int)
*/
@Override
public void onPageScrolled(int position, float positionOffset,
int positionOffsetPixels) {
// TODO Auto-generated method stub
}
/* (non-Javadoc)
* @see android.support.v4.view.ViewPager.OnPageChangeListener#onPageSelected(int)
*/
@Override
public void onPageSelected(int position) {
// TODO Auto-generated method stub
this.mTabHost.setCurrentTab(position);
}
/* (non-Javadoc)
* @see android.support.v4.view.ViewPager.OnPageChangeListener#onPageScrollStateChanged(int)
*/
@Override
public void onPageScrollStateChanged(int state) {
// TODO Auto-generated method stub
}
}
Adit Lal
October 17, 2012 at 21:21
I get the following error in logcat , pls help
FATAL EXCEPTION: main
10-18 00:44:33.649: E/AndroidRuntime(4524): java.lang.NullPointerException
10-18 00:44:33.649: E/AndroidRuntime(4524): at android.support.v4.app.BackStackRecord.doAddOp(BackStackRecord.java:352)
10-18 00:44:33.649: E/AndroidRuntime(4524): at android.support.v4.app.BackStackRecord.add(BackStackRecord.java:347)
10-18 00:44:33.649: E/AndroidRuntime(4524): at android.support.v4.app.FragmentPagerAdapter.instantiateItem(FragmentPagerAdapter.java:99)
10-18 00:44:33.649: E/AndroidRuntime(4524): at android.support.v4.view.ViewPager.addNewItem(ViewPager.java:692)
10-18 00:44:33.649: E/AndroidRuntime(4524): at android.support.v4.view.ViewPager.populate(ViewPager.java:821)
10-18 00:44:33.649: E/AndroidRuntime(4524): at android.support.v4.view.ViewPager.populate(ViewPager.java:772)
10-18 00:44:33.649: E/AndroidRuntime(4524): at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1234)
10-18 00:44:33.649: E/AndroidRuntime(4524): at android.view.View.measure(View.java:15172)
10-18 00:44:33.649: E/AndroidRuntime(4524): at android.widget.LinearLayout.measureVertical(LinearLayout.java:833)
10-18 00:44:33.649: E/AndroidRuntime(4524): at android.widget.LinearLayout.onMeasure(LinearLayout.java:574)
10-18 00:44:33.649: E/AndroidRuntime(4524): at android.view.View.measure(View.java:15172)
10-18 00:44:33.649: E/AndroidRuntime(4524): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4816)
10-18 00:44:33.649: E/AndroidRuntime(4524): at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
10-18 00:44:33.649: E/AndroidRuntime(4524): at android.view.View.measure(View.java:15172)
10-18 00:44:33.649: E/AndroidRuntime(4524): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4816)
10-18 00:44:33.649: E/AndroidRuntime(4524): at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1390)
10-18 00:44:33.649: E/AndroidRuntime(4524): at android.widget.LinearLayout.measureVertical(LinearLayout.java:681)
10-18 00:44:33.649: E/AndroidRuntime(4524): at android.widget.LinearLayout.onMeasure(LinearLayout.java:574)
10-18 00:44:33.649: E/AndroidRuntime(4524): at android.view.View.measure(View.java:15172)
10-18 00:44:33.649: E/AndroidRuntime(4524): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4816)
10-18 00:44:33.649: E/AndroidRuntime(4524): at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
10-18 00:44:33.649: E/AndroidRuntime(4524): at android.view.View.measure(View.java:15172)
10-18 00:44:33.649: E/AndroidRuntime(4524): at android.widget.LinearLayout.measureVertical(LinearLayout.java:833)
10-18 00:44:33.649: E/AndroidRuntime(4524): at android.widget.LinearLayout.onMeasure(LinearLayout.java:574)
10-18 00:44:33.649: E/AndroidRuntime(4524): at android.view.View.measure(View.java:15172)
10-18 00:44:33.649: E/AndroidRuntime(4524): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4816)
10-18 00:44:33.649: E/AndroidRuntime(4524): at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
10-18 00:44:33.649: E/AndroidRuntime(4524): at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2148)
10-18 00:44:33.649: E/AndroidRuntime(4524): at android.view.View.measure(View.java:15172)
10-18 00:44:33.649: E/AndroidRuntime(4524): at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:1850)
10-18 00:44:33.649: E/AndroidRuntime(4524): at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1102)
10-18 00:44:33.649: E/AndroidRuntime(4524): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1275)
10-18 00:44:33.649: E/AndroidRuntime(4524): at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1000)
10-18 00:44:33.649: E/AndroidRuntime(4524): at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4214)
10-18 00:44:33.649: E/AndroidRuntime(4524): at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725)
10-18 00:44:33.649: E/AndroidRuntime(4524): at android.view.Choreographer.doCallbacks(Choreographer.java:555)
10-18 00:44:33.649: E/AndroidRuntime(4524): at android.view.Choreographer.doFrame(Choreographer.java:525)
10-18 00:44:33.649: E/AndroidRuntime(4524): at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711)
10-18 00:44:33.649: E/AndroidRuntime(4524): at android.os.Handler.handleCallback(Handler.java:615)
10-18 00:44:33.649: E/AndroidRuntime(4524): at android.os.Handler.dispatchMessage(Handler.java:92)
10-18 00:44:33.649: E/AndroidRuntime(4524): at android.os.Looper.loop(Looper.java:137)
10-18 00:44:33.649: E/AndroidRuntime(4524): at android.app.ActivityThread.main(ActivityThread.java:4931)
10-18 00:44:33.649: E/AndroidRuntime(4524): at java.lang.reflect.Method.invokeNative(Native Method)
10-18 00:44:33.649: E/AndroidRuntime(4524): at java.lang.reflect.Method.invoke(Method.java:511)
10-18 00:44:33.649: E/AndroidRuntime(4524): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791)
10-18 00:44:33.649: E/AndroidRuntime(4524): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:558)
10-18 00:44:33.649: E/AndroidRuntime(4524): at dalvik.system.NativeStart.main(Native Method)
polo
November 11, 2012 at 16:59
A Great Big Thanks 🙂
intika
November 30, 2012 at 09:44
Hi gays, gooooood news to all 🙂
Screen Orientation Bug Is Solved !!!!!!!!!
and the solution is too too stupid ! here is the stuff,just add
android:configChanges=”orientation|keyboardHidden|screenSize”
in manifest xml under activity ! that’s all loooool
———————————————————————————
Adapt depending on the version of your android os
———————————————————————————
Full Code : for Android 3.2 (API level 13) and newer:
——————————————————————
———————————————————————————
Older version use :
————————
android:configChanges=”keyboardHidden|orientation”
———————————————————————————
I just used this code to test, i found an 100x easier way to add the swipe to a tabhost 🙂
nor ActionBarSherlock nor ViewPageIndicator … too much stuff on that library and it’s ruining my code….
The stuff is just to use a ViewPager with the tabwidget, setup the viewpager, and then replace the the tab framelayout with the viewpager or equivalent…
———————————————————————————
good luck to all it’s really not easy to manage cosmetic under java android… i’am new on it and it’s really too bad stuff you quickly loose many days just to get a f****** stuff displayed as you want… in an other hand it’s cool to get all that support and documentation…
———————————————————————————
cheeeeeeeeerrrrrrrrrsssssssssssss
intika
November 30, 2012 at 09:46
intika
November 30, 2012 at 09:47
full code wont be displayed… just add
———————————————————————————————————-
android:name=”IndexActivity”
android:theme=”@android:style/Theme.Light”
android:configChanges=”orientation|keyboardHidden|screenSize”
———————————————————————————————————-
and
———————————————————————————————————-
android:name=”.fragments.tabs.TabsViewPagerFragmentActivity”
android:configChanges=”orientation|keyboardHidden|screenSize”
———————————————————————————————————-
Cheers
intika
November 30, 2012 at 09:50
one last post … lol
explanation : when screen orientation change the activity is reseted… when the reset happen if active tab is not the first one the variables get ruined… so just disable that reset… 😉
intika
November 30, 2012 at 09:55
i think “Oattoreto” is still looking for setting active tab still july hahahahaha loool
mTabHost.setCurrentTabByTag(“Tab2”);
Amrit
December 7, 2012 at 18:55
Hi I have followed the steps and managed to create 3 slide tabs but how can I edit the 3 tabs with content and text and other programmes for it to function?
Any help will be great
thanks
joonazzz
December 28, 2012 at 15:46
Thanks a lot for sharing this. I needed tabs + swipe on android 2.2 and it works great! You saved a lot of time for me !
Hassan
January 11, 2013 at 15:01
Hi,
Looking to be a nice tutorial.I haven’t implemented yet but I want to implement horizantal pager slider like u Have done plus want to add portion of next and previous pages as implemented in “groupme” app.Any idea or help is appreciated.Thanks
rajni
January 16, 2013 at 10:54
hii,,tnx for giving nice post and now i wnn to creat an app which have a home page look a like this image so may u like to help me by some example,,, the image link is http://imgur.com/pJjFk
mitchwongho
January 17, 2013 at 01:42
Hi,
You can achieve that by using ActionBarSherlock + http://viewpagerindicator.com/
DoLpHiN
January 29, 2013 at 22:09
Hi, thx for great tutorial.
Could you tell me how to modify tabs appearance? I’m new to Android development and i don’t get it.
Athira
January 31, 2013 at 08:21
Hi,
Thank you…
very helpful for my project..:)
Ahsan
February 8, 2013 at 21:51
Hi its a usefull tutorial kindly tell me how to render a activity on each tab ?? plus at tab2 i need 2 sub tabs.. ??
Chip
February 11, 2013 at 03:31
People might still be complaining about the rotation issue so I thought to add this workaround.
In the main activity, I drop the NULL handler for the savedInstance, and just use the initializeViewPager() method directly. I also add savedInstanceState methods to the fragments and this solves it. Hope that helps other folks thought the build is on a Nexus 4, v4.2.
Deep
February 28, 2013 at 10:56
hiiii,
I want a listview with custom rows in these pagers how can we do that??
Please help me . I am new in android.
Prakash
March 1, 2013 at 22:16
Hi mitchwongho
not sure you are still here. I followed your tutorial and have run into some problem. Just wondering whether you can help me.
Prakash
click_whir
April 5, 2013 at 00:19
Why are you managing a list of fragments? I thought ViewPager was supposed to manage all that for you….
Antoni
April 5, 2013 at 01:05
Thanks a lot, great tutorial, has been very useful to me, ….but a simple question:
is there an easy way to control de color and size of tab text labels ???
Antoni
April 7, 2013 at 13:36
solved it !
replacing the view widget at every TabWidget int onTabChanged method by these sentences:
mTabHost.getTabWidget().removeViewAt(tabPosition);
mTabHost.getTabWidget().addView(button, tabPosition);
where button is the new predefined View for the TabWidget, with its own color, icon, ….
Ruben
April 18, 2013 at 02:16
Hi, I have an error in this line:
fragments.add(Fragment.instantiate(this, Home.class.getName()));
The error in LogCat:
04-18 02:10:58.601: E/AndroidRuntime(31519): FATAL EXCEPTION: main
04-18 02:10:58.601: E/AndroidRuntime(31519): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.lesson_planner/com.example.lesson_planner.MainActivity}: java.lang.ClassCastException: com.example.lesson_planner.Home cannot be cast to android.support.v4.app.Fragment
Anybody can help me?
mitchwongho
April 20, 2013 at 10:37
Have you included the compatibility library? Are you extending the correct Fragment class (android.support.v4.app.Fragment)
Giovanni
April 23, 2013 at 15:17
Hi,
Thanks for the useful article. I’ve got a question about 2 lines of code:
1) tabSpec.setContent(activity.new TabFactory(activity));, specially the part inside the brackets
2) List fragments = new Vector();, I know it’s pure java, but I can’t figure it out anyway. How can I do this in another way? Possibly more simple.
Thanks a lot.. I’m beginning to learn Android from a few days.
Bye.
Andres Añez
May 23, 2013 at 00:58
Hi
Well i tried to folow the code with an app doing exactly the same but when i make it run it stops, here´s all i got with LogCat, hope u can help me, thanks
05-22 18:23:11.821: D/dalvikvm(581): Not late-enabling CheckJNI (already on)
05-22 18:23:14.531: D/AndroidRuntime(581): Shutting down VM
05-22 18:23:14.531: W/dalvikvm(581): threadid=1: thread exiting with uncaught exception (group=0x409961f8)
05-22 18:23:14.571: E/AndroidRuntime(581): FATAL EXCEPTION: main
05-22 18:23:14.571: E/AndroidRuntime(581): java.lang.ClassCastException: android.widget.RelativeLayout cannot be cast to android.widget.LinearLayout
05-22 18:23:14.571: E/AndroidRuntime(581): at com.tabsviewpager.Tab1Fragment.onCreateView(Tab1Fragment.java:26)
05-22 18:23:14.571: E/AndroidRuntime(581): at android.support.v4.app.Fragment.performCreateView(Fragment.java:1460)
05-22 18:23:14.571: E/AndroidRuntime(581): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:911)
05-22 18:23:14.571: E/AndroidRuntime(581): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1088)
05-22 18:23:14.571: E/AndroidRuntime(581): at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682)
05-22 18:23:14.571: E/AndroidRuntime(581): at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1444)
05-22 18:23:14.571: E/AndroidRuntime(581): at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:461)
05-22 18:23:14.571: E/AndroidRuntime(581): at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:141)
05-22 18:23:14.571: E/AndroidRuntime(581): at android.support.v4.view.ViewPager.populate(ViewPager.java:1064)
05-22 18:23:14.571: E/AndroidRuntime(581): at android.support.v4.view.ViewPager.populate(ViewPager.java:911)
05-22 18:23:14.571: E/AndroidRuntime(581): at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1432)
05-22 18:23:14.571: E/AndroidRuntime(581): at android.view.View.measure(View.java:12603)
05-22 18:23:14.571: E/AndroidRuntime(581): at android.widget.LinearLayout.measureVertical(LinearLayout.java:812)
05-22 18:23:14.571: E/AndroidRuntime(581): at android.widget.LinearLayout.onMeasure(LinearLayout.java:553)
05-22 18:23:14.571: E/AndroidRuntime(581): at android.view.View.measure(View.java:12603)
05-22 18:23:14.571: E/AndroidRuntime(581): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4677)
05-22 18:23:14.571: E/AndroidRuntime(581): at android.widget.FrameLayout.onMeasure(FrameLayout.java:293)
05-22 18:23:14.571: E/AndroidRuntime(581): at android.view.View.measure(View.java:12603)
05-22 18:23:14.571: E/AndroidRuntime(581): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4677)
05-22 18:23:14.571: E/AndroidRuntime(581): at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1369)
05-22 18:23:14.571: E/AndroidRuntime(581): at android.widget.LinearLayout.measureVertical(LinearLayout.java:660)
05-22 18:23:14.571: E/AndroidRuntime(581): at android.widget.LinearLayout.onMeasure(LinearLayout.java:553)
05-22 18:23:14.571: E/AndroidRuntime(581): at android.view.View.measure(View.java:12603)
05-22 18:23:14.571: E/AndroidRuntime(581): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4677)
05-22 18:23:14.571: E/AndroidRuntime(581): at android.widget.FrameLayout.onMeasure(FrameLayout.java:293)
05-22 18:23:14.571: E/AndroidRuntime(581): at android.view.View.measure(View.java:12603)
05-22 18:23:14.571: E/AndroidRuntime(581): at android.widget.LinearLayout.measureVertical(LinearLayout.java:812)
05-22 18:23:14.571: E/AndroidRuntime(581): at android.widget.LinearLayout.onMeasure(LinearLayout.java:553)
05-22 18:23:14.571: E/AndroidRuntime(581): at android.view.View.measure(View.java:12603)
05-22 18:23:14.571: E/AndroidRuntime(581): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4677)
05-22 18:23:14.571: E/AndroidRuntime(581): at android.widget.FrameLayout.onMeasure(FrameLayout.java:293)
05-22 18:23:14.571: E/AndroidRuntime(581): at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2072)
05-22 18:23:14.571: E/AndroidRuntime(581): at android.view.View.measure(View.java:12603)
05-22 18:23:14.571: E/AndroidRuntime(581): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1044)
05-22 18:23:14.571: E/AndroidRuntime(581): at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2418)
05-22 18:23:14.571: E/AndroidRuntime(581): at android.os.Handler.dispatchMessage(Handler.java:99)
05-22 18:23:14.571: E/AndroidRuntime(581): at android.os.Looper.loop(Looper.java:137)
05-22 18:23:14.571: E/AndroidRuntime(581): at android.app.ActivityThread.main(ActivityThread.java:4340)
05-22 18:23:14.571: E/AndroidRuntime(581): at java.lang.reflect.Method.invokeNative(Native Method)
05-22 18:23:14.571: E/AndroidRuntime(581): at java.lang.reflect.Method.invoke(Method.java:511)
05-22 18:23:14.571: E/AndroidRuntime(581): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
05-22 18:23:14.571: E/AndroidRuntime(581): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
05-22 18:23:14.571: E/AndroidRuntime(581): at dalvik.system.NativeStart.main(Native Method)
05-22 18:23:23.042: I/Process(581): Sending signal. PID: 581 SIG: 9
Alexandre
June 27, 2013 at 15:47
Thank you. Really great set of postings.
Mambo
July 2, 2013 at 03:00
Hi mitchwongho
Great your tutorial!
I have a problem with an idea that I have,,, but i dont know if this is possible..
i tell you:
i wanna make a app that has this application:
http://developer.android.com/training/implementing-navigation/nav-drawer.html
and the selectItem(int position) method call a Fragment class that have the TabHost…
Something like:
1. The Navigation drawer is same
2. Pressing an one option of Navigation drawer menu .. this show a Fragment with a TabHost with various Tabs…
Is this possible?
Thx for advance!
Mohammad
July 22, 2013 at 13:52
Hello,
thank you very mush for this great tutorial.
I have a annoying problem. I follow all of the steps but after running it my first tab is empty. I’m sure the problem isn’t about layout.
I post a question in stackoverflow too:http://stackoverflow.com/questions/17786445/first-page-of-viewpager-is-not-loading-at-all
help me plz
neelam
August 13, 2013 at 11:24
hi
i want to develope an app like skout.not all the features but few of them like swipe on click on image buttons on header.pls see this link as i want to make it
like https://play.google.com/store/apps/details?id=com.skout.android&hl=en
Himanshu
September 26, 2013 at 14:42
hey can you write the OnTabChanged Method for this code.So that the Fragments are not created every time.It should just load
Vinicios
October 11, 2013 at 15:53
Men i hava five fragments, if the name is very long, the name break the line, i need what the TabWidget follow fragment
Vinicios
October 11, 2013 at 15:54
don’t break line in tab
Mal Clarke
October 23, 2013 at 09:42
Hold the line
Love isn’t always on time
Innkuan Thute
November 19, 2013 at 16:13
I would like to apply custom design on TabHost. How can I design?
Enrique
November 22, 2013 at 23:56
Good tutorial. I tried to download the code from Github, but I have no access.
BB
November 26, 2013 at 16:36
thank you . Its a good code.
Lê Đình Thanh Hải
December 2, 2013 at 05:44
good! it helpful for me! thank you so much! 🙂
gabby
January 24, 2014 at 09:20
HOW CAN I ADD ACTIVE SVG IMAGES ON THE SWIPING TAB
Omar Espinoza
January 27, 2014 at 22:42
I read your tutorial, I have an application that has a FragmenActivity (menu), open a fragment and this uses the Tab + ViewPager, works great.
I press the back button and enter again the fragment (Tab + ViewPager), the information does not appear in the tabs.
What am I doing wrong.
Wilb
March 3, 2014 at 07:14
How do this with ActionBarCopat? … with FragMent Activity the Action Bar is not compatible with all devices.
eugeniusz
March 22, 2014 at 13:55
Great example, thank you!
uttami
April 7, 2014 at 11:44
how can i align tabs at the other sides of the page?? or can i give desired position to these tabs??
Hari Krishna G
August 13, 2014 at 12:39
Can we get the same code for Tabs at the screen below
Supost Java Cdcn
October 9, 2014 at 04:04
Hello !Thank you! I learned a lot from your article.
If I want to show vertical tabs, then how can I do?
Kareem
February 9, 2015 at 19:36
Thank you very much for this tutorial!!
shriduttkothari
February 13, 2015 at 19:30
Thanks awesome work mate..