I am using PagerSlidingTabStrip with a ViewPager.
Is there a way I can change the Tab icons dynamically, depending on some actions. Like when a notification is received, I want to change the icon on notifications tab to show how many notifications are unread.
Or any other library which would support that without much tweaking.
You can do it by implementing PagerSlidingTabStrip.CustomTabProvider
interface. I made example project for your case, so let's explore it step by step.
Firstly, create a layout for our tab called tab_layout
, for example. It will contain 2 TextView
's for title and badge. In my case it looks like:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/tab_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center"
android:textColor="@android:color/white"
android:textStyle="bold"
android:textSize="16sp"
android:singleLine="true" />
<TextView
android:id="@+id/badge"
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_toRightOf="@+id/tab_title"
android:textSize="12sp"
android:gravity="center"
android:layout_marginLeft="8dp"
android:layout_centerVertical="true"
android:textColor="@android:color/white"
android:background="@drawable/badge_background" />
</RelativeLayout>
Secondly, create a simple model for Tab, that will containt a tab title and number of notifications. I've called it ViewPagerTab
:
public class ViewPagerTab {
public String title;
public int notifications;
public ViewPagerTab(String title, int notifications) {
this.title = title;
this.notifications = notifications;
}
}
Thirdly, implement PagerSlidingTabStrip.CustomTabProvider
interface on your FragmentPagerAdapter
. Here we will inflate tab layout and initialize the tab views, also we will define fragments for positions:
public class MainAdapter extends FragmentPagerAdapter
implements PagerSlidingTabStrip.CustomTabProvider {
ArrayList<ViewPagerTab> tabs;
public MainAdapter(FragmentManager fm, ArrayList<ViewPagerTab> tabs) {
super(fm);
this.tabs = tabs;
}
@Override
public View getCustomTabView(ViewGroup viewGroup, int i) {
RelativeLayout tabLayout = (RelativeLayout)
LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.tab_layout, null);
TextView tabTitle = (TextView) tabLayout.findViewById(R.id.tab_title);
TextView badge = (TextView) tabLayout.findViewById(R.id.badge);
ViewPagerTab tab = tabs.get(i);
tabTitle.setText(tab.title.toUpperCase());
if (tab.notifications > 0) {
badge.setVisibility(View.VISIBLE);
badge.setText(String.valueOf(tab.notifications));
} else {
badge.setVisibility(View.GONE);
}
return tabLayout;
}
@Override
public void tabSelected(View view) {
//if you don't want badges disappear when you select tab comment next lines
RelativeLayout tabLayout = (RelativeLayout) view;
TextView badge = (TextView) tabLayout.findViewById(R.id.badge);
badge.setVisibility(View.GONE);
}
@Override
public void tabUnselected(View view) {
}
@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new OneFragment();
case 1:
return new TwoFragment();
case 2:
return new ThreeFragment();
}
return new OneFragment();
}
@Override
public int getCount() {
return tabs.size();
}
}
Fourthly, initialize tabs and pager in MainActivity
's onCreate
method:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tabs = (PagerSlidingTabStrip) findViewById(R.id.tabs);
pager = (ViewPager) findViewById(R.id.pager);
ArrayList<ViewPagerTab> tabsList = new ArrayList<>();
tabsList.add(new ViewPagerTab("One", 0));
tabsList.add(new ViewPagerTab("Two", 1));
tabsList.add(new ViewPagerTab("Three", 2));
adapter = new MainAdapter(getSupportFragmentManager(), tabsList);
pager.setAdapter(adapter);
tabs.setViewPager(pager);
pager.setOffscreenPageLimit(3);
getSupportActionBar().hide();
}
You will get something like this:
And finally, to get and change tab views in runtime, you can simply call getChildAt
function of PagerSlidingTabStrip
object in your Activity
or Fragment
, and do what you want:
private void notifyTabStripChanged(int position, int notificationsCount) {
LinearLayout tabHost = (LinearLayout) tabs.getChildAt(0);
RelativeLayout tabLayout = (RelativeLayout) tabHost.getChildAt(position);
TextView badge = (TextView) tabLayout.findViewById(R.id.badge);
if (notificationsCount > 0) {
badge.setVisibility(View.VISIBLE);
badge.setText(String.valueOf(notificationsCount));
} else {
badge.setVisibility(View.GONE);
}
}
Don't forget, that child views count is starting from 0. If you want to use images, just replace ImageView
with TextView
badge and change it's image resource instead of text. Enjoy!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With