Home » Android » android – ViewPagerIndicator Tabs: Icons above Text

android – ViewPagerIndicator Tabs: Icons above Text

Posted by: admin June 15, 2020 Leave a comment

Questions:

I’m using the ViewPagerIndicator
and I would like to change the tab style so I could get icons above text, instead of the default, which places the icon on the left side, and the title to the right.

How to&Answers:

The reason why the icons always appear on the left is because of this piece of code:

if (iconResId != 0) {
     tabView.setCompoundDrawablesWithIntrinsicBounds(iconResId, 0, 0, 0);
}

found in TabPageIndicator.java

This is part of a private method (addTab()), and so, cannot be changed without modifying the library itself.

Luckily, this isn’t too hard to do. Make sure that you have the ViewPagerIndicator source code downloaded, then open up TabPageIndicator.java

If you want to change the location permanently (as permanent as you can get with a source code change), change the location of iconResId in the setCompoundDrawablesWithIntrinsicBounds() method. For example, placing the icons at the top needs iconResId to be the second argument to the method.

tabView.setCompoundDrawablesWithIntrinsicBounds(0, iconResId, 0, 0);

If you need something a little more flexible, I came up with these changes (still in TabPageIndicator.java) that should work. These changes have been mirrored on my GitHub, so there is a working example.

Member variables:

/**
* Constants to improve readability - no magic numbers.
*/
public final static int LOCATION_LEFT =0;
public final static int LOCATION_UP = 1;
public final static int LOCATION_RIGHT = 2;
public final static int LOCATION_BOTTOM =3;

/**
* Stores the location of the tab icon
*/
private int location = LOCATION_LEFT;

/**
* Used to store the icon.
*/
private int [] drawables = new int [4];

/**
 * Holds the value used by setCompoundDrawablesWithIntrinsicBounds used to denote no icon.
 */
private static int NO_ICON = 0;

Add this method:

public void setTabIconLocation (int newLocation){
    if (location > LOCATION_BOTTOM || location < LOCATION_LEFT)
        throw new IllegalArgumentException ("Invalid location");
    this.location = newLocation;
    for (int x = 0; x < drawables.length;x++){
        drawables [x] = NO_ICON;
    }
}

In addTab(), change

if (iconResId != 0) {
     tabView.setCompoundDrawablesWithIntrinsicBounds(iconResId, 0, 0, 0);
}

to

if (iconResId != 0) {
    drawables [location] = iconResId;
    tabView.setCompoundDrawablesWithIntrinsicBounds(drawables[0], drawables[1], drawables[2], drawables[3]);
}

Non-library implementation (taken from the sample code provided)

TabPageIndicator indicator = (TabPageIndicator)findViewById(R.id.indicator);
indicator.setTabIconLocation (TabPageIndicator.LOCATION_UP);
indicator.setViewPager(pager);

Answer:

You can achieve this effect by modifying only 1 line in the source code of ViewPageIndicator library.

The line to be modified is in the number 180 in the TabPageIndicator class inside the addTab method ( at least on today’s version of the code 28/05/2013 )

The original file is

180        tabView.setCompoundDrawablesWithIntrinsicBounds( iconResId, 0, 0, 0 );

And you should modify it to the following if you want the icon to go on top of text.

180        tabView.setCompoundDrawablesWithIntrinsicBounds( 0, iconResId, 0, 0 );

Here’s an screenshot of the change

enter image description here

As you probably guessed by now, you can put the icon anywhere around the text by playing with the iconResId within the different arguments of the setCompoundDrawablesWithIntrinsicBounds method.

Answer:

There is a cleaner way to do that without modifying the library. Just copy and paste the class TabPageIndicator to your project and modify the lines pointed out in the other answers. Then rename the class to whatever you like and use it as if it was a TabPageIndicator.