ViewPagerIndicator Tabs: Icons above Text
Asked Answered
M

3

8

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.

Musil answered 6/2, 2013 at 17:34 Comment(1)
Hi, Any solution for this issue?Doggoned
A
13

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);
Acrogen answered 28/5, 2013 at 22:20 Comment(6)
Thanks for your answer and the working copy on Github, much appreciated! I was afraid of it not being possible through the library itself. Ah well, perhaps I'll sens a pull request (unless you're going to do it :)). Again, thanks.Jernigan
I just realized I cannot assign bounty points yet (can only do that after 24 hrs): I will divide them between you and Robert when I am able to.Jernigan
@BartKiers No problem :-) I made some small changes to the code, and once I verify that it is working, properly, I'll send a pull request.Acrogen
nice, I saw the pull request: github.com/JakeWharton/Android-ViewPagerIndicator/pull/232 Note that I saw you made the pull against the master branch, which should probably be the dev branch instead.Jernigan
@BartKiers seems everyone's pull requests are against master, so I think I'll keep the pull request as it is :-)Acrogen
ah, didn't look at that. I seem to remember Jake Wharton asking someone to make the pull against dev, but that must have been another repo then.Jernigan
V
8

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.

Vizor answered 28/5, 2013 at 22:19 Comment(1)
Robert, I just awarded all points to A--C. I thought I could split the point over multiple answers, but apparently not the way I created the bounty. Sorry! Your answer is appreciated, nevertheless!Jernigan
C
0

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.

Carman answered 9/1, 2014 at 16:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.