Due to limitation of Android Tab component I created a custom TabWidget that I am using in couple different projects already. The widget allows us to add custom background and use custom icons, tabs  can be Top/Bottom aligned.
Currently tabs can launch new Activity and Dialog , when starting new Activity we can use “startActivityForResult” so our tab will get a notification when other activity have finished.
This is not a perfect solution as there are some drawbacks to it but it suits me well so I will stick to it till something better comes along; Hint Android gurus we need to be able to start new activities inside existing tab with more customization.
Creating a Tab
There a two thing that a tab needs
- Icon: either R.drawable.id or Drawable Object
- An Activity set via Intent or Dialog
Tab homeTab=new Tab(context, "HOME"); homeTab.setIcon(R.drawable.home); homeTab.setIconSelected(R.drawable.home_selected); homeTab.setIntent(new Intent(context, CarmeLauncher.class)); |
What is a TabHost ?
TabHost host tabs and specify how they will be rendered , TabViewConfig is used to configure the TabHost
TabHost tabHost=new TabHost( new TabViewConfig() .context(context) .headerResourceId(R.drawable.tab_background_55) .separatorId(R.drawable.separator) .orientation(TabHost.Orientation.BOTTOM) ); |
I use fluent interfaces or as some call it Builder pattern for configuring TabHost I think its straight forward and intuitive.
Binding tabs to Activity
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //Our Tab provider TabHostProvider tabProvider=new CarmeTabProvider(this); TabHost tabHost=tabProvider.getTabHost("main"); //This is the content of the tab tabHost.setCurrentView(R.layout.main); setContentView(tabHost.render()); } |
To make tab selected we need to retrieve it using tab assigned TAG name in this case “HOME” before setContentView(tabHost.render())
is called.
Tab home=tabHost.getTab("HOME"); home.setSelected(true); setContentView(tabHost.render()); |
Download/View Demo Project
Carme Project using tabs bottom aligned
[nggallery id=2]
Cool! Is the source code of you project available?
Yes, I will make this a opensource project. Right now I am switching from Activity to using ActivityGroup for better performance. It will be hosted here.
Hi, great work! Any news on the release of your project’s code?
Hello guys,
There is still more work to do on it but it is usable it will be mostly an implementation/performance fixes.
Project is hosted on googlecode
http://code.google.com/p/androidtabs/
source will be uploaded sometimes today.
Hello
Thanks for sharing code. but while running i had faced lot of problems.
i have added all resources and done respective changes,now program is running.
but its not showing any tab.
please help me.
Thanks
Makrand
Hi, Greg, I really like how your tab design looks! Great job.
I also looked up the code on google code but couldnt find it. Any chance you can share it with me? Regards Christian
Hey Greg,
I would also be very glad if you could (re-)publish your code since I’m really interested
in the custom Tabs…
Rgds
Coyle L. McGuire
Hey Greg,
Your code looks great! Could you possibly do an export of a working project that uses your code and make it available for download on your google code site?
Thanks for all your work! This looks very promising!
Yes, I should do that this weekend. But if you like here is a link to a working demo project
Hey,
I have this problem when running the code for first time:
09-17 23:09:33.552: ERROR/AndroidRuntime(781): Caused by: java.lang.NullPointerException
09-17 23:09:33.552: ERROR/AndroidRuntime(781): at com.gregbugaj.tabwidget.TabWidgedLauncher.onCreate(TabWidgedLauncher.java:54)
09-17 23:09:33.552: ERROR/AndroidRuntime(781): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1123)
09-17 23:09:33.552: ERROR/AndroidRuntime(781): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2364)
And line 54 is: Tab home=tabHost.getTab(“HOME”);
Can anyone help me?
Make sure that you defined
homeTab = new Tab(context, "HOME");
homeTab.setIcon(R.drawable.home);
//t1.setIconSelected(R.drawable.home_selected);
homeTab.setIntent(new Intent(context, TabWidgetDemoLauncher.class));
tabHost.addTab(homeTab);
Also here is a complete Demo project http://www.gregbugaj.com/?p=117
Hi,
I’m trying to run your TabWidgetDemo in v1.6 of the SDK. Getting the following:
D/AndroidRuntime( 824): Shutting down VM
W/dalvikvm( 824): threadid=3: thread exiting with uncaught exception (group=0x4001aa28)
E/AndroidRuntime( 824): Uncaught handler: thread main exiting due to uncaught exception
E/AndroidRuntime( 824): java.lang.VerifyError: com.gregbugaj.tabwidgetdemo.TabWidgetDemoLauncher
E/AndroidRuntime( 824): at java.lang.Class.newInstanceImpl(Native Method)
E/AndroidRuntime( 824): at java.lang.Class.newInstance(Class.java:1472)
E/AndroidRuntime( 824): at android.app.Instrumentation.newActivity(Instrumentation.java:1097)
E/AndroidRuntime( 824): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2316)
E/AndroidRuntime( 824): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2417)
E/AndroidRuntime( 824): at android.app.ActivityThread.access$2100(ActivityThread.java:116)
E/AndroidRuntime( 824): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1794)
E/AndroidRuntime( 824): at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime( 824): at android.os.Looper.loop(Looper.java:123)
E/AndroidRuntime( 824): at android.app.ActivityThread.main(ActivityThread.java:4203)
E/AndroidRuntime( 824): at java.lang.reflect.Method.invokeNative(NativeMethod)
E/AndroidRuntime( 824): at java.lang.reflect.Method.invoke(Method.java:521)
E/AndroidRuntime( 824): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791)
E/AndroidRuntime( 824): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:549)
E/AndroidRuntime( 824): at dalvik.system.NativeStart.main(Native Method)
same as Derek
I have the sae with 1.5 :/
I will take a look at it this weekend
Hello,
I’m really trying to get this to work but I’m having some problems. Originally after finally getting the two projects imported together and what I thought was properly defining the tabs like mentioned above, I tried it on my phone and got a force close error. When looking at the log it said the same error as Wouter Goossens’s posted above. I’m not sure what I’m doing wrong as I got that error after defining homeTab etc etc.
I would really like to get this to work but am not sure what exactly am I doing wrong. I’ve followed every instruction I’ve found and still nothing. Is there a more precise step-by-step guide? or any other tips?
Hello! Is there any way to get the PSD files for those icons included in the project? Thanks! Please email them!
I don’t think that I have the psd for this files, I have found them on one of the icon websites.
Hi I’m trying to make my own custom tabwidget but its not working. I downloaded the code and run it but when try to make it work in my application it doesn’t work at all. It breaks on TabViewConfig and such. I’m getting errors telling me that they can’t be resolved. Am I missing a reference or something this is very strange
I see people running into some problems with setting up the widget, so I have decided to make a screen cast asap.
Hi, I cannot find the actual tabwidget library with the demo. Is it published elsewhere?
Nevermind, I found it! 🙂 It is under http://code.google.com/p/androidtabs/source/checkout
For anyone looking for the code under ‘downloads’, click the ‘source’ tab.
Hi Greg,
I tried to implement this code using the demo you supplied and I get the same error as everyone else. A screencast would be fantastic. I recommend using Jing for your screencast. Its quick, simple, and free. I use it for documentation all the time. I think your component sounds like just what I need, I just need to see if I happen to be missing anything.
1. I imported both projects
2. added the TabWidgedLauncher as a required project on the build path
3. Corrected the project name in the TabWidgedLauncher .project file.
I had to remove some overrides the compiler was complaining about but after that, it compiled but fails with the same error everyone else has.
Please help!!!!
Thanks in advance
Same exception here…frustrating.
Hi Greg,
I wanted to start by saying you have done great job with those tabs.
I’m just starting with java and android so doing something like this is beyond my abilities.
I want to use your tabwidget solution in my app I’m writing and I was wondering if it is possible for me to use. I wouldent fill right using it without asking first.
Thank you for you comment, also you can use in any project you like.
I’ve just found a solution, that allows the same, with androids native tabhost, going to post an “tutorial” soon 🙂
here is a Preview: http://images.sourceway.eu/android/betterTabs.jpg (its even possible without the Text below the icon, or just text… or whatever u want <3)
http://www.sourceway.eu/ <- there you can find the tutorial =D
its not nice but well, dont have a CMS or Blog setup there =D
here is a new link, i’ve just installed wordpress and made a nice tutorial 😀
http://sourceway.eu/wp/2010/06/android-tutorial-1-custom-tabs/
(you may delete the post from June 7th, 2010 at 12:43 pm ^^)
Very nice tutorial.
But had one problom:if you have three Activity,then you will onCreat() init the “View v=tabHost.render();setContentView(v)”,there have a flash…
Thanks for tutorial.. very usefull..
I’ve created a Tabbar with 2 tab. In tab1 there is a button, click this button will open a new widow. I see when this window opened, tabbar will be hidden. But I want tabbar visible. How can I do it?
Wow… really. That’s a so good looking tab setup I had to download the source and the images for safekeeping incase this site goes down at some point.
REALLY good work.
Unable to read D:\Android\android-sdk-windows\AndroidManifest.xml: java.io.FileNotFoundException: D:\Android\android-sdk-windows\AndroidManifest.xml (The system cannot find the file specified)
com.android.sdklib.io.StreamException: java.io.FileNotFoundException: D:\Android\android-sdk-windows\AndroidManifest.xml (The system cannot find the file specified)
at com.android.sdklib.io.FileWrapper.getContents(FileWrapper.java:92)
at com.android.sdklib.xml.AndroidManifestParser.parse(AndroidManifestParser.java:608)
at com.android.ide.eclipse.adt.internal.project.AndroidManifestHelper.parse(AndroidManifestHelper.java:71)
at com.android.ide.eclipse.adt.internal.project.AndroidManifestHelper.parseForData(AndroidManifestHelper.java:171)
at com.android.ide.eclipse.adt.internal.wizards.newproject.NewProjectCreationPage.extractNamesFromAndroidManifest(NewProjectCreationPage.java:997)
at com.android.ide.eclipse.adt.internal.wizards.newproject.NewProjectCreationPage.access$16(NewProjectCreationPage.java:983)
at com.android.ide.eclipse.adt.internal.wizards.newproject.NewProjectCreationPage$3.widgetSelected(NewProjectCreationPage.java:461)
at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:228)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1003)
at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:3880)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3473)
at org.eclipse.jface.window.Window.runEventLoop(Window.java:825)
at org.eclipse.jface.window.Window.open(Window.java:801)
at org.eclipse.ui.internal.actions.NewWizardShortcutAction.run(NewWizardShortcutAction.java:135)
at org.eclipse.jface.action.Action.runWithEvent(Action.java:498)
at org.eclipse.jface.action.ActionContributionItem.handleWidgetSelection(ActionContributionItem.java:584)
at org.eclipse.jface.action.ActionContributionItem.access$2(ActionContributionItem.java:501)
at org.eclipse.jface.action.ActionContributionItem$5.handleEvent(ActionContributionItem.java:411)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1003)
at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:3880)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3473)
at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2405)
at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2369)
at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2221)
at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:500)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:493)
at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:113)
at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:194)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:368)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:559)
at org.eclipse.equinox.launcher.Main.basicRun(Main.java:514)
at org.eclipse.equinox.launcher.Main.run(Main.java:1311)
Caused by: java.io.FileNotFoundException: D:\Android\android-sdk-windows\AndroidManifest.xml (The system cannot find the file specified)
at java.io.FileInputStream.open(Native Method)
at java.io.FileInputStream.(Unknown Source)
at com.android.sdklib.io.FileWrapper.getContents(FileWrapper.java:90)
… 42 more
Pingback: How to Highlight a particular tab in Android so that other tabs were made partially visible in Android - DexPage