Custom Android TabWidget with Badges
For an android app I’m working on I needed to present badges for tabs much like on the iPhone. I looked around for a bit but could not find any good solution for this. It seems the android SDK does not provide this feature out of the box. At least I could not find it. So I had a go at writing a custom TabWidget for this nifty feature.
I’m sure it can be made to look even better with some work. The icon is not the most pretty image and should probably be replaced. Called badge.png in the source files.
I used a singleton class BadgeTabManager to manage the tabs and get access to them from anywhere in the app. I guess this approach could be changed if several tabwidgets need to be used at the same time.
The badges are set by a simple call:
BadgeTabManager.getInstance().setBadgeAtIndex(5, 2);
The BadgeTabWidget looks like this:
/*
* Copyright (C) 2011 Nilisoft
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nilisoft.examples.badgetabs;
import java.util.HashMap;
import com.nilisoft.examples.R;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.view.View;
import android.widget.TabWidget;
public class BadgeTabWidget extends TabWidget{
HashMap map;
public BadgeTabWidget(Context context) {
super(context);
map = new HashMap();
}
public BadgeTabWidget(Context c, AttributeSet set){
super(c, set);
map = new HashMap();
}
public int getBadgeNumAtIndex(int index){
Badge b = map.get(index);
if (b == null){
return 0;
}
else{
return b.getNum();
}
}
public void setBadgeAtIndex(int num, int index){
Badge b = map.get(index);
if (b == null){
b = new Badge();
map.put(index, b);
}
b.setNum(num);
public void setBadgeAtIndex(int num, int index){
Badge b = map.get(index);
if (b == null){
b = new Badge();
map.put(index, b);
}
b.setNum(num);
// should probably use some other way to update the view (repaint the tabs) but this works...
this.getChildAt(index).setVisibility(View.INVISIBLE);
this.getChildAt(index).setVisibility(View.VISIBLE);
}
}
@Override
protected boolean drawChild (Canvas canvas, View child, long drawingTime){
boolean b = super.drawChild(canvas, child, drawingTime);
// figure out our index in the tabs, need it for the badge number
int index = 0;
for(int i=0; i < this.getTabCount(); i++){
if (this.getChildAt(i) == child){
index = i;
break;
}
}
int num = this.getBadgeNumAtIndex(index);
if (num > 0){
Bitmap src = BitmapFactory.decodeResource(this.getResources(),R.drawable.badge);
Bitmap badge = Bitmap.createScaledBitmap(src, 24, 19, true);
int x = child.getRight()-badge.getWidth()-5;
canvas.drawBitmap(badge, x, 0, new Paint());
Typeface face = Typeface.create("Verdana", Typeface.BOLD);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setTypeface(face);
paint.setTextSize(12);
paint.setARGB(255, 255, 255, 255);
String text = ""+num;
Rect bounds = new Rect();
paint.getTextBounds(text, 0, text.length(), bounds);
canvas.drawText(
text,
(x+badge.getWidth()/2)-bounds.width()/2,
// -1 here because the badge icon is looking as it does with some
// more space at the bottom for shadows, might need change if the
// size of the icon is changed
(badge.getHeight()/2)+bounds.height()/2 -2,
paint);
}
return b;
}
private class Badge {
int num;
public Badge(){
num = 0;
}
public void setNum(int num){
this.num = num;
}
public int getNum(){
return num;
}
}
}
And the full source code the for example project can be downloaded here: BadgeTabs
Enjoy! And please let me know if you find this useful in any of your apps.


Ganesh
August 19, 2011 • 8:35 am
Great Work. It is very useful for my shopping cart application, where on cart icon in tab bar I am showing no of items added. You saved my day. Thanks a tons.
NBS
August 21, 2011 • 10:36 pm
Nice work. Thanks for the source. It was really help to my project
Vivek
September 14, 2011 • 8:07 am
Great Work….its useful for me as well. But i am facing one problem. i want to show badges in two line(eg: Item then below item amount should be shown) I am passing the string with \n but its not showing in 2 line.
Nilisoft
September 14, 2011 • 8:12 am
Hmm, the draw text method on the canvas probably do not take newlines into consideration. You will have to actually draw two separate lines yourself, and increase the y coordinate on the second line. (And use a badge icon that actually fits two lines or the text will be drawn outside it).
So simply add another drawText call for your second line should work…
Vivek
September 14, 2011 • 10:00 am
Hi Nilisoft ,
Thanks you are really awosme.
wangpeng
September 19, 2011 • 12:19 am
cool,thank you very much
Rao Venu
November 25, 2011 • 8:08 pm
Thanks for this example. It worked straight out of the box.
Balu....
December 24, 2011 • 8:42 am
I love you man……….
Thank you very much.
ky
December 29, 2011 • 2:23 am
good,nick work
mount
March 1, 2012 • 6:19 pm
Disconnected full source code download link
Please revert download link…
plz…!
Nilisoft
March 1, 2012 • 7:47 pm
The download link should now work again. When moving sites the old links did not work very good. Should be better now!
Search
Custom Android TabWidget with Badges
“Android Developers Who Charge for their App Can Say Goodbye to Revenue”
Parallels Desktop 6
Injecting Javascript in UIWebView
New website
New App: Ljushults HBF
Reset your password for the My Calendar App
Skatteverket tvärvänder – appar slipper dubbelmoms
My Advent Calendar HD for iPad
My Advent App
Nilisoft: The download link should now work again. When moving sites the old lin...
mount: Disconnected full source code download link Please revert downloa...
ky: good,nick work...
Balu....: I love you man.......... Thank you very much....
Rao Venu: Thanks for this example. It worked straight out of the box....
Recent News
Latest apps | Projects
© 2011 App 7H | Nilisoft