Android Tablayout tabs with notification badge like whatsApp
I would suggest you look at this website:
https://guides.codepath.com/android/Google-Play-Style-Tabs-using-TabLayout#design-support-library
You can iterate through the different tabs using this method and set the custom views to whatever you want:
// Iterate over all tabs and set the custom view
for (int i = 0; i < tabLayout.getTabCount(); i++) {
TabLayout.Tab tab = tabLayout.getTabAt(i);
tab.setCustomView(pagerAdapter.getTabView(i));
}
public View getTabView(int position) {
// Given you have a custom layout in `res/layout/custom_tab.xml` with a TextView and ImageView
View v = LayoutInflater.from(context).inflate(R.layout.custom_tab, null);
TextView tv = (TextView) v.findViewById(R.id.textView);
tv.setText(tabTitles[position]);
ImageView img = (ImageView) v.findViewById(R.id.imgView);
img.setImageResource(imageResId[position]);
return v;
}
}
EDIT: UPDATE
With the newest release of the Material Components
, the Android team now offers an official BadgeDrawable
to be used on the TabLayout
to achieve the asked result. It is part of the v1.1.0-alpha07 update. https://github.com/material-components/material-components-android/releases/tag/1.1.0-alpha07
The usage is very simple and can be done as following:
tabLayout.getTabAt(0).showBadge().setNumber(1);
See the integration in the material components demo app: https://github.com/material-components/material-components-android/commit/111cd001f5302bd6899f181ab7ccea2fd4002f63#diff-bf3e9a8a208f0ecab05088823fba99c4R239
OLD ANSWER
I tried some of the above mentioned solutions, but they did not deliver proper results. If you take a closer look in the TabLayout
implementation you will realize that the TabView
will try to get the textView and iconView from the CustomView
if applied.
So instead of doing some hacky implementations I rather came up with a layout equal to the one from the original TabView
but an additional view which can have a badge.
So you will need the badged_tab.xml layout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="4dp"
android:layout_marginTop="4dp">
<ImageView
android:id="@android:id/icon"
android:layout_width="24dp"
android:layout_height="24dp"
android:scaleType="centerInside" />
<TextView
android:id="@android:id/text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:gravity="center"
android:maxLines="2" />
</LinearLayout>
<LinearLayout
android:id="@+id/badgeCotainer"
android:layout_width="wrap_content"
android:layout_height="16dp"
android:layout_marginStart="12dp"
android:background="@drawable/notifications_background"
android:gravity="center"
android:minWidth="16dp"
android:visibility="gone">
<TextView
android:id="@+id/badge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAlignment="center"
android:textColor="#fff"
android:textSize="10sp" />
</LinearLayout>
</RelativeLayout>
And some sort of notification background:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="@color/red" />
</shape>
When adding your tab programatically just call
tab.setCustomView(R.layout.badged_tab);
And then you can show / hide / set a badge cound at any time via:
if(tab != null && tab.getCustomView() != null) {
TextView b = (TextView) tab.getCustomView().findViewById(R.id.badge);
if(b != null) {
b.setText(notifications + "");
}
View v = tab.getCustomView().findViewById(R.id.badgeCotainer);
if(v != null) {
v.setVisibility(View.VISIBLE);
}
}
My solution to this was using https://github.com/jgilfelt/android-viewbadger and setting a custom view to each tab:
My tabs have only icons so I used ImageView, but I believe you can use any other view, check https://github.com/jgilfelt/android-viewbadger/blob/master/README.markdown:
private BadgeView badge;
Tab tab = tabLayout.getTabAt(position);
ImageView imageView = new ImageView(context);
tab.setCustomView(imageView);
badge = new BadgeView(context, imageView);
This is an old cuestion, but Its much more simple these days. Im using Kotlin, AndroidX, using the next widget as TabLayout:
com.google.android.material.tabs.TabLayout
and inside my gradel app file:
implementation 'com.google.android.material:material:1.1.0-alpha09'
For setting a simple badge, just write..
yourTabLayout?.getTabAt(currentTabPosition)?.apply{
orCreateBadge
badge?.isVisible = true
}
Then just set isVisible = false to hide, like this:
private fun changeYourTabMethod(newTabPosition : Int) {
// do some stuff and then hide the badge...
yourTabLayout?.getTabAt(newTabPosition)?.apply{
badge?.isVisible = false
}
}