Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ViewPagerIndicator Tabs: Icons above Text

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.

like image 680
Pabloku Avatar asked Feb 06 '13 17:02

Pabloku


2 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);
like image 72
A--C Avatar answered Nov 05 '22 13:11

A--C


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.

like image 32
Robert Estivill Avatar answered Nov 05 '22 13:11

Robert Estivill