ActionBar tabs set dynamic width according to screen width - android

I have 5 tabs in all. This is how I am adding them :
for (int i = 0; i < tabs.length; i++) {
if (i == 0) {
actionBar.addTab(
actionBar.newTab()
.setText(null)
.setIcon(R.drawable.activity)
.setTabListener(this));
} else if (i == 1) {
actionBar.addTab(
actionBar.newTab()
.setText(null)
.setIcon(R.drawable.group)
.setTabListener(this));
} else if (i == 2) {
actionBar.addTab(
actionBar.newTab()
.setText(null)
.setIcon(R.drawable.message)
.setTabListener(this));
} else if(i == 3){
actionBar.addTab(
actionBar.newTab()
.setText(null)
.setIcon(R.drawable.notification)
.setTabListener(this));
}
else
{
actionBar.addTab(
actionBar.newTab()
.setText(null)
.setIcon(R.drawable.hamburger)
.setTabListener(this));
}
I tried this solution but this sets the width of the tab icon and not the tab itself.
Following are the styles I have applied :
App theme :
<style name="CustomActionBarTheme" parent="Theme.AppCompat.Light">
<item name="android:windowActionBarOverlay">true</item>
<item name="android:actionBarTabStyle">#style/actionBarTabBarStyle</item>
<item name="android:actionBarStyle">#style/MyActionBar</item>
</style>
<style name="actionBarTabBarStyle" parent="#style/Widget.AppCompat.ActionBar.TabView">
<item name="android:paddingLeft">1dp</item>
<item name="android:paddingRight">1dp</item>
<item name="android:minWidth">10dp</item>
<item name="android:maxWidth">15dp</item>
<item name="android:showDividers">none</item>
</style>
I also tried using customView for the tab but it didn't work.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/tabItemLayout"
android:gravity="center"
android:layout_width="wrap_content" android:layout_height="match_parent">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:id="#+id/imageViewTab" />
</LinearLayout>
The tabs are too wide and the tabBar is sliding. How can I make the tabs take dynamic width as per the screen width without the sliding effect. i.e. all tabs should fit in the screen width and should be of equal width.
There are 4 tabs visible here. The tabBar is scrollable so the fifth tab appears on scrolling which I don't want.

Tab view width is based on content/yourImage size, so to make tab view width smaller, we have to control the content/Image size. You can do this by putting ImageView inside FrameLayout, for example your customView can be:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/tabItemLayout"
android:gravity="center"
android:layout_width="wrap_content" android:layout_height="match_parent">
<FrameLayout
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_centerInParent="true"
>
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:adjustViewBounds="true"
android:layout_gravity="center"
android:gravity="center"
android:id="#+id/imageViewTab" />
</FrameLayout>
</RelativeLayout>
and custom style for tab:
<style name="AppTheme" parent="#style/Theme.AppCompat.Light">
... ...
<item name="actionBarTabStyle">#style/ActionBarTabStyle</item>
</style>
<style name="ActionBarTabStyle" parent="#style/Widget.AppCompat.Base.ActionBar.TabView">
<item name="android:paddingLeft">0dp</item>
<item name="android:paddingRight">0dp</item>
<item name="android:paddingTop">0dp</item>
<item name="android:paddingBottom">0dp</item>
</style>
[SCREENSHOT]
For FrameLayout size with 24dp:
For FrameLayout size with 40dp

As you're trying to achieve tabs on Actionbar which fits to width of device, one can use PagerSlidingTabStrip or SlidingTabLayout which gives you more flexibility in achieving tabs and its related Fragment with ViewPager which gives your Uix more efficient and user friendly touch.
Here I'm showing how to achieve it using PagerSlidingTabStrip
PagerSlidingTabStrip.java : Your Custom Tab View
public class PagerSlidingTabStrip extends HorizontalScrollView {
public interface IconTabProvider {
public int getPageIconResId(int position);
}
// #formatter:off
private static final int[] ATTRS = new int[] { android.R.attr.textSize,
android.R.attr.textColor };
// #formatter:on
private LinearLayout.LayoutParams defaultTabLayoutParams;
private LinearLayout.LayoutParams expandedTabLayoutParams;
private final PageListener pageListener = new PageListener();
public OnPageChangeListener delegatePageListener;
private LinearLayout tabsContainer;
private ViewPager pager;
private int tabCount;
private int currentPosition = 0;
private float currentPositionOffset = 0f;
private Paint rectPaint;
private Paint dividerPaint;
private int currentPageSelected = 0; // Fix : ICON SELECTOR
private int indicatorColor = 0xFF666666;
private int underlineColor = 0x1A000000;
private int dividerColor = 0x1A000000;
private boolean shouldExpand = false;
private boolean textAllCaps = true;
private int scrollOffset = 52;
private int indicatorHeight = 8;
private int underlineHeight = 2;
private int dividerPadding = 12;
private int tabPadding = 24;
private int dividerWidth = 1;
private int tabTextSize = 12;
private int tabTextColor = 0xFF666666;
private Typeface tabTypeface = null;
private int tabTypefaceStyle = Typeface.BOLD;
private int lastScrollX = 0;
private int tabBackgroundResId = R.drawable.background_tab;
private Locale locale;
public PagerSlidingTabStrip(Context context) {
this(context, null);
}
public PagerSlidingTabStrip(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public PagerSlidingTabStrip(Context context, AttributeSet attrs,
int defStyle) {
super(context, attrs, defStyle);
setFillViewport(true);
setWillNotDraw(false);
tabsContainer = new LinearLayout(context);
tabsContainer.setOrientation(LinearLayout.HORIZONTAL);
tabsContainer.setLayoutParams(new LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
addView(tabsContainer);
DisplayMetrics dm = getResources().getDisplayMetrics();
scrollOffset = (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, scrollOffset, dm);
indicatorHeight = (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, indicatorHeight, dm);
underlineHeight = (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, underlineHeight, dm);
dividerPadding = (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, dividerPadding, dm);
tabPadding = (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, tabPadding, dm);
dividerWidth = (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, dividerWidth, dm);
tabTextSize = (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_SP, tabTextSize, dm);
// get system attrs (android:textSize and android:textColor)
TypedArray a = context.obtainStyledAttributes(attrs, ATTRS);
tabTextSize = a.getDimensionPixelSize(0, tabTextSize);
tabTextColor = a.getColor(1, tabTextColor);
a.recycle();
// get custom attrs
a = context.obtainStyledAttributes(attrs,
R.styleable.PagerSlidingTabStrip);
indicatorColor = a.getColor(
R.styleable.PagerSlidingTabStrip_pstsIndicatorColor,
indicatorColor);
underlineColor = a.getColor(
R.styleable.PagerSlidingTabStrip_pstsUnderlineColor,
underlineColor);
dividerColor = a
.getColor(R.styleable.PagerSlidingTabStrip_pstsDividerColor,
dividerColor);
indicatorHeight = a.getDimensionPixelSize(
R.styleable.PagerSlidingTabStrip_pstsIndicatorHeight,
indicatorHeight);
underlineHeight = a.getDimensionPixelSize(
R.styleable.PagerSlidingTabStrip_pstsUnderlineHeight,
underlineHeight);
dividerPadding = a.getDimensionPixelSize(
R.styleable.PagerSlidingTabStrip_pstsDividerPadding,
dividerPadding);
tabPadding = a.getDimensionPixelSize(
R.styleable.PagerSlidingTabStrip_pstsTabPaddingLeftRight,
tabPadding);
tabBackgroundResId = a.getResourceId(
R.styleable.PagerSlidingTabStrip_pstsTabBackground,
tabBackgroundResId);
shouldExpand = a
.getBoolean(R.styleable.PagerSlidingTabStrip_pstsShouldExpand,
shouldExpand);
scrollOffset = a
.getDimensionPixelSize(
R.styleable.PagerSlidingTabStrip_pstsScrollOffset,
scrollOffset);
textAllCaps = a.getBoolean(
R.styleable.PagerSlidingTabStrip_pstsTextAllCaps, textAllCaps);
a.recycle();
rectPaint = new Paint();
rectPaint.setAntiAlias(true);
rectPaint.setStyle(Style.FILL);
dividerPaint = new Paint();
dividerPaint.setAntiAlias(true);
dividerPaint.setStrokeWidth(dividerWidth);
defaultTabLayoutParams = new LinearLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
expandedTabLayoutParams = new LinearLayout.LayoutParams(0,
LayoutParams.MATCH_PARENT, 1.0f);
if (locale == null) {
locale = getResources().getConfiguration().locale;
}
}
public void setViewPager(ViewPager pager) {
this.pager = pager;
if (pager.getAdapter() == null) {
throw new IllegalStateException(
"ViewPager does not have adapter instance.");
}
pager.setOnPageChangeListener(pageListener);
notifyDataSetChanged();
}
public void setOnPageChangeListener(OnPageChangeListener listener) {
this.delegatePageListener = listener;
}
public void notifyDataSetChanged() {
tabsContainer.removeAllViews();
tabCount = pager.getAdapter().getCount();
for (int i = 0; i < tabCount; i++) {
if (pager.getAdapter() instanceof IconTabProvider) {
addIconTab(i,
((IconTabProvider) pager.getAdapter())
.getPageIconResId(i));
} else {
addTextTab(i, pager.getAdapter().getPageTitle(i).toString());
}
}
updateTabStyles();
getViewTreeObserver().addOnGlobalLayoutListener(
new OnGlobalLayoutListener() {
#SuppressWarnings("deprecation")
#SuppressLint("NewApi")
#Override
public void onGlobalLayout() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
getViewTreeObserver().removeGlobalOnLayoutListener(
this);
} else {
getViewTreeObserver().removeOnGlobalLayoutListener(
this);
}
currentPosition = pager.getCurrentItem();
tabsContainer.getChildAt(currentPosition).setSelected(
true);// Fix : ICON SELECTOR
scrollToChild(currentPosition, 0);
}
});
}
private void addTextTab(final int position, String title) {
TextView tab = new TextView(getContext());
tab.setText(title);
tab.setGravity(Gravity.CENTER);
tab.setSingleLine();
addTab(position, tab);
}
private void addIconTab(final int position, int resId) {
ImageButton tab = new ImageButton(getContext());
tab.setImageResource(resId);
addTab(position, tab);
}
private void addTab(final int position, View tab) {
tab.setFocusable(true);
tab.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
pager.setCurrentItem(position);
}
});
tab.setPadding(tabPadding, 0, tabPadding, 0);
tabsContainer
.addView(tab, position, shouldExpand ? expandedTabLayoutParams
: defaultTabLayoutParams);
}
private void updateTabStyles() {
for (int i = 0; i < tabCount; i++) {
View v = tabsContainer.getChildAt(i);
v.setBackgroundResource(tabBackgroundResId);
if (v instanceof TextView) {
TextView tab = (TextView) v;
tab.setTextSize(TypedValue.COMPLEX_UNIT_PX, tabTextSize);
tab.setTypeface(tabTypeface, tabTypefaceStyle);
tab.setTextColor(tabTextColor);
// setAllCaps() is only available from API 14, so the upper case
// is made manually if we are on a
// pre-ICS-build
if (textAllCaps) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
tab.setAllCaps(true);
} else {
tab.setText(tab.getText().toString()
.toUpperCase(locale));
}
}
}
}
}
private void scrollToChild(int position, int offset) {
if (tabCount == 0) {
return;
}
int newScrollX = tabsContainer.getChildAt(position).getLeft() + offset;
if (position > 0 || offset > 0) {
newScrollX -= scrollOffset;
}
if (newScrollX != lastScrollX) {
lastScrollX = newScrollX;
scrollTo(newScrollX, 0);
}
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (isInEditMode() || tabCount == 0) {
return;
}
final int height = getHeight();
// draw indicator line
rectPaint.setColor(indicatorColor);
// default: line below current tab
View currentTab = tabsContainer.getChildAt(currentPosition);
float lineLeft = currentTab.getLeft();
float lineRight = currentTab.getRight();
// if there is an offset, start interpolating left and right coordinates
// between current and next tab
if (currentPositionOffset > 0f && currentPosition < tabCount - 1) {
View nextTab = tabsContainer.getChildAt(currentPosition + 1);
final float nextTabLeft = nextTab.getLeft();
final float nextTabRight = nextTab.getRight();
lineLeft = (currentPositionOffset * nextTabLeft + (1f - currentPositionOffset)
* lineLeft);
lineRight = (currentPositionOffset * nextTabRight + (1f - currentPositionOffset)
* lineRight);
}
//SU TU002
canvas.drawRect(lineLeft, height - indicatorHeight, lineRight,height,
rectPaint);
// canvas.drawRect(lineLeft, 0, lineRight, indicatorHeight, rectPaint);
// EU TU002
// draw underline
rectPaint.setColor(underlineColor);
//SU TU002
canvas.drawRect(0, height - underlineHeight,tabsContainer.getWidth(),
height, rectPaint);
// canvas.drawRect(0, 0, tabsContainer.getWidth(), underlineHeight,
// rectPaint);
// EU TU002
// draw divider
dividerPaint.setColor(dividerColor);
for (int i = 0; i < tabCount - 1; i++) {
View tab = tabsContainer.getChildAt(i);
canvas.drawLine(tab.getRight(), dividerPadding, tab.getRight(),
height - dividerPadding, dividerPaint);
}
}
private class PageListener implements OnPageChangeListener {
#Override
public void onPageScrolled(int position, float positionOffset,
int positionOffsetPixels) {
currentPosition = position;
currentPositionOffset = positionOffset;
scrollToChild(position, (int) (positionOffset * tabsContainer
.getChildAt(position).getWidth()));
invalidate();
if (delegatePageListener != null) {
delegatePageListener.onPageScrolled(position, positionOffset,
positionOffsetPixels);
}
}
#Override
public void onPageScrollStateChanged(int state) {
if (state == ViewPager.SCROLL_STATE_IDLE) {
scrollToChild(pager.getCurrentItem(), 0);
}
if (delegatePageListener != null) {
delegatePageListener.onPageScrollStateChanged(state);
}
}
#Override
public void onPageSelected(int position) {
/**
* Fix : ICON SELECTOR
*/
tabsContainer.getChildAt(currentPageSelected).setSelected(false);
currentPageSelected = position;
tabsContainer.getChildAt(position).setSelected(true);
/**
* Fix : ICON SELECTOR
*/
if (delegatePageListener != null) {
delegatePageListener.onPageSelected(position);
}
}
}
public void setIndicatorColor(int indicatorColor) {
this.indicatorColor = indicatorColor;
invalidate();
}
public void setIndicatorColorResource(int resId) {
this.indicatorColor = getResources().getColor(resId);
invalidate();
}
public int getIndicatorColor() {
return this.indicatorColor;
}
public void setIndicatorHeight(int indicatorLineHeightPx) {
this.indicatorHeight = indicatorLineHeightPx;
invalidate();
}
public int getIndicatorHeight() {
return indicatorHeight;
}
public void setUnderlineColor(int underlineColor) {
this.underlineColor = underlineColor;
invalidate();
}
public void setUnderlineColorResource(int resId) {
this.underlineColor = getResources().getColor(resId);
invalidate();
}
public int getUnderlineColor() {
return underlineColor;
}
public void setDividerColor(int dividerColor) {
this.dividerColor = dividerColor;
invalidate();
}
public void setDividerColorResource(int resId) {
this.dividerColor = getResources().getColor(resId);
invalidate();
}
public int getDividerColor() {
return dividerColor;
}
public void setUnderlineHeight(int underlineHeightPx) {
this.underlineHeight = underlineHeightPx;
invalidate();
}
public int getUnderlineHeight() {
return underlineHeight;
}
public void setDividerPadding(int dividerPaddingPx) {
this.dividerPadding = dividerPaddingPx;
invalidate();
}
public int getDividerPadding() {
return dividerPadding;
}
public void setScrollOffset(int scrollOffsetPx) {
this.scrollOffset = scrollOffsetPx;
invalidate();
}
public int getScrollOffset() {
return scrollOffset;
}
public void setShouldExpand(boolean shouldExpand) {
this.shouldExpand = shouldExpand;
requestLayout();
}
public boolean getShouldExpand() {
return shouldExpand;
}
public boolean isTextAllCaps() {
return textAllCaps;
}
public void setAllCaps(boolean textAllCaps) {
this.textAllCaps = textAllCaps;
}
public void setTextSize(int textSizePx) {
this.tabTextSize = textSizePx;
updateTabStyles();
}
public int getTextSize() {
return tabTextSize;
}
public void setTextColor(int textColor) {
this.tabTextColor = textColor;
updateTabStyles();
}
public void setTextColorResource(int resId) {
this.tabTextColor = getResources().getColor(resId);
updateTabStyles();
}
public int getTextColor() {
return tabTextColor;
}
public void setTypeface(Typeface typeface, int style) {
this.tabTypeface = typeface;
this.tabTypefaceStyle = style;
updateTabStyles();
}
public void setTabBackground(int resId) {
this.tabBackgroundResId = resId;
}
public int getTabBackground() {
return tabBackgroundResId;
}
public void setTabPaddingLeftRight(int paddingPx) {
this.tabPadding = paddingPx;
updateTabStyles();
}
public int getTabPaddingLeftRight() {
return tabPadding;
}
#Override
public void onRestoreInstanceState(Parcelable state) {
SavedState savedState = (SavedState) state;
super.onRestoreInstanceState(savedState.getSuperState());
currentPosition = savedState.currentPosition;
requestLayout();
}
#Override
public Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState();
SavedState savedState = new SavedState(superState);
savedState.currentPosition = currentPosition;
return savedState;
}
static class SavedState extends BaseSavedState {
int currentPosition;
public SavedState(Parcelable superState) {
super(superState);
}
private SavedState(Parcel in) {
super(in);
currentPosition = in.readInt();
}
#Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeInt(currentPosition);
}
public static final Parcelable.Creator<SavedState> CREATOR = new Parcelable.Creator<SavedState>() {
#Override
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
#Override
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}
}
Your Activity Layout :
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<com.application.ui.view.PagerSlidingTabStrip
android:id="#+id/pager_sliding_tab_strip"
android:layout_width="fill_parent"
android:layout_height="48dip"
android:layout_alignParentTop="true"
android:background="#drawable/background_tabs"
app:pstsIndicatorColor="#color/background_actionbar"
app:pstsTabPaddingLeftRight="14dip" />
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
</android.support.v4.view.ViewPager>
</RelativeLayout>
</RelativeLayout>
Your Activity :
public class MotherActivity extends ActionBarActivity {
public static final String TAG = MotherActivity.class.getSimpleName();
private ViewPager mPager;
private PagerSlidingTabStrip mPagerSlidingTabStrp;
private ViewPager.SimpleOnPageChangeListener ViewPagerListener;
private ActionBar mActionBar;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mother);
initUi();
setPagerSlidingTabStrip();
}
private void initUi() {
mPager = (ViewPager) findViewById(R.id.pager);
mPagerSlidingTabStrp = (PagerSlidingTabStrip) findViewById(R.id.pager_sliding_tab_strip);
}
private void setPagerSlidingTabStrip() {
ViewPagerAdapter viewpageradapter = new ViewPagerAdapter(
getSupportFragmentManager());
mPager.setOffscreenPageLimit(5);
mPager.setAdapter(viewpageradapter);
mPagerSlidingTabStrp.setShouldExpand(true);
mPagerSlidingTabStrp.setViewPager(mPager);
}
}
ViewPagerAdapter : which passes fragment on tab selection or swiping it. Pass on Fragment and drawables in here.
public class ViewPagerAdapter extends FragmentPagerAdapter implements
IconTabProvider {
final int PAGE_COUNT = 5;
private final int[] ICONS = { R.drawable.tab_icon_feed_home_selector,
R.drawable.tab_icon_feed_friends_selector, R.drawable.tab_icon_feed_popular_selector,
R.drawable.tab_icon_feed_report_selector, R.drawable.tab_icon_feed_report_selector };
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int item) {
switch (item) {
case 0:
FragmentAttendance fragmentAttendance = new FragmentAttendance();
return fragmentAttendance;
case 1:
FragmentPremium fragmentPremium = new FragmentPremium();
return fragmentPremium;
case 2:
FragmentLead fragmentLead = new FragmentLead();
return fragmentLead;
case 3:
FragmentLead fragmentLead = new FragmentLead();
return fragmentLead;
case 4:
FragmentLead fragmentLead = new FragmentLead();
return fragmentLead;
}
return null;
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return PAGE_COUNT;
}
#Override
public int getPageIconResId(int position) {
// TODO Auto-generated method stub
return ICONS[position];
}
}

Use the following code for changing the size of tab and making tabs fit within the screenwidth. Make sure your are using the Custom View
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int screenWidth = displaymetrics.widthPixels;
final View tabView = actionBar.getTabAt(0).getCustomView();
final View tabContainerView = (View) tabView.getParent();
final int tabPadding = tabContainerView.getPaddingLeft() + tabContainerView.getPaddingRight();
final int tabs = actionBar.getTabCount();
for(int i=0 ; i < tabs ; i++) {
View tab = actionBar.getTabAt(i).getCustomView();
LinearLayout tabItemLayout = (LinearLayout) tab.findViewById(R.id.tabItemLayout);
tabItemLayout.setLayoutParams(new LayoutParams(screenWidth/tabs-tabPadding-1, LayoutParams.WRAP_CONTENT));
}

Related

Customize Paging SlideTabStrip Android

I am working on customizing Paging Slide Strip, the Page Strip takes only Title in the heading. My requirement is a bit different, I need to have a Title as well as a Sub-Title kind of thing.
For that I have passed the getPageTitle in this way, and it is working ok.
public CharSequence getPageTitle(int position) {
return (TITLES[position]+"\n"+SUBTITLE[position]);
}
But along with that, I need to display different Color and Font-size for my Title and Sub-Title, for that I have used SpannableString inside my custom PagingStrip class, but it does not seem to work.
Please check what I have achieved,
What I want is
Please check my code for Custom Paging Strip Class.
package com.astuetz;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Typeface;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.text.SpannableString;
import android.text.style.ForegroundColorSpan;
import android.text.style.UnderlineSpan;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.widget.HorizontalScrollView;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.example.sujit.pagestrip.R;
import java.util.Locale;
public class PagerSlidingTabStrip extends HorizontalScrollView {
public interface IconTabProvider {
public int getPageIconResId(int position);
}
// #formatter:off
private static final int[] ATTRS = new int[] {
android.R.attr.textSize,
};
// #formatter:on
private LinearLayout.LayoutParams defaultTabLayoutParams;
private LinearLayout.LayoutParams expandedTabLayoutParams;
private final PageListener pageListener = new PageListener();
public OnPageChangeListener delegatePageListener;
private LinearLayout tabsContainer;
private ViewPager pager;
private int tabCount;
private int currentPosition = 0;
private float currentPositionOffset = 0f;
private Paint rectPaint;
private Paint dividerPaint;
private int indicatorColor = 0xFF666666;
private int underlineColor = 0x1A000000;
private int dividerColor = 0x1A000000;
private boolean shouldExpand = false;
private boolean textAllCaps = true;
private int scrollOffset = 52;
private int indicatorHeight = 1;
private int underlineHeight = 2;
private int dividerPadding = 12;
private int tabPadding = 24;
private int dividerWidth = 0;
// private int tabTextSize = 12;
// private int tabTextColor = 0xFF0000FF;
// private int tabTypefaceStyle = Typeface.BOLD;
private int lastScrollX = 0;
private int tabBackgroundResId = R.drawable.background_tab;
private Locale locale;
public PagerSlidingTabStrip(Context context) {
this(context, null);
}
public PagerSlidingTabStrip(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public PagerSlidingTabStrip(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setFillViewport(true);
setWillNotDraw(false);
tabsContainer = new LinearLayout(context);
tabsContainer.setOrientation(LinearLayout.HORIZONTAL);
tabsContainer.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
addView(tabsContainer);
DisplayMetrics dm = getResources().getDisplayMetrics();
scrollOffset = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, scrollOffset, dm);
indicatorHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, indicatorHeight, dm);
underlineHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, underlineHeight, dm);
dividerPadding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dividerPadding, dm);
tabPadding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, tabPadding, dm);
dividerWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dividerWidth, dm);
// tabTextSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, tabTextSize, dm);
// get system attrs (android:textSize and android:textColor)
TypedArray a = context.obtainStyledAttributes(attrs, ATTRS);
// tabTextSize = a.getDimensionPixelSize(0, tabTextSize);
//tabTextColor = a.getColor(1, tabTextColor);
a.recycle();
// get custom attrs
a = context.obtainStyledAttributes(attrs, R.styleable.PagerSlidingTabStrip);
indicatorColor = a.getColor(R.styleable.PagerSlidingTabStrip_pstsIndicatorColor, indicatorColor);
underlineColor = a.getColor(R.styleable.PagerSlidingTabStrip_pstsUnderlineColor, underlineColor);
dividerColor = a.getColor(R.styleable.PagerSlidingTabStrip_pstsDividerColor, dividerColor);
indicatorHeight = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsIndicatorHeight, indicatorHeight);
underlineHeight = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsUnderlineHeight, underlineHeight);
dividerPadding = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsDividerPadding, dividerPadding);
tabPadding = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsTabPaddingLeftRight, tabPadding);
tabBackgroundResId = a.getResourceId(R.styleable.PagerSlidingTabStrip_pstsTabBackground, tabBackgroundResId);
shouldExpand = a.getBoolean(R.styleable.PagerSlidingTabStrip_pstsShouldExpand, shouldExpand);
scrollOffset = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsScrollOffset, scrollOffset);
textAllCaps = a.getBoolean(R.styleable.PagerSlidingTabStrip_pstsTextAllCaps, textAllCaps);
a.recycle();
rectPaint = new Paint();
rectPaint.setAntiAlias(true);
rectPaint.setStyle(Style.FILL);
dividerPaint = new Paint();
dividerPaint.setAntiAlias(true);
dividerPaint.setStrokeWidth(dividerWidth);
defaultTabLayoutParams = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
expandedTabLayoutParams = new LinearLayout.LayoutParams(0, LayoutParams.MATCH_PARENT, 1.0f);
if (locale == null) {
locale = getResources().getConfiguration().locale;
}
}
public void setViewPager(ViewPager pager) {
this.pager = pager;
if (pager.getAdapter() == null) {
throw new IllegalStateException("ViewPager does not have adapter instance.");
}
pager.setOnPageChangeListener(pageListener);
notifyDataSetChanged();
}
public void setOnPageChangeListener(OnPageChangeListener listener) {
this.delegatePageListener = listener;
}
public void notifyDataSetChanged() {
tabsContainer.removeAllViews();
tabCount = pager.getAdapter().getCount();
for (int i = 0; i < tabCount; i++) {
if (pager.getAdapter() instanceof IconTabProvider) {
addIconTab(i, ((IconTabProvider) pager.getAdapter()).getPageIconResId(i));
} else {
addTextTab(i, pager.getAdapter().getPageTitle(i).toString());
}
}
updateTabStyles();
getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#SuppressWarnings("deprecation")
#SuppressLint("NewApi")
#Override
public void onGlobalLayout() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
getViewTreeObserver().removeGlobalOnLayoutListener(this);
} else {
getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
currentPosition = pager.getCurrentItem();
scrollToChild(currentPosition, 0);
}
});
}
private void addTextTab(final int position, String title) {
TextView tab = new TextView(getContext());
int j=0,k=0;
for(int i=0;i<title.length();i++){
if(title.charAt(i)=='\n'){
k=title.length();
break;
}
j=i;
}
SpannableString str = new SpannableString(title);
str.setSpan(new ForegroundColorSpan(Color.GREEN),0,j+1,0);
str.setSpan(new ForegroundColorSpan(Color.BLUE),j+1,k,0);
// tab.setTextColor(Color.GREEN);
tab.setText(str);
tab.setGravity(Gravity.CENTER);
//tab.setSingleLine();
addTab(position, tab);
}
private void addIconTab(final int position, int resId) {
ImageButton tab = new ImageButton(getContext());
tab.setImageResource(resId);
addTab(position, tab);
}
private void addTab(final int position, View tab) {
tab.setFocusable(true);
tab.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
pager.setCurrentItem(position);
}
});
tab.setPadding(tabPadding, 0, tabPadding, 0);
tabsContainer.addView(tab, position, shouldExpand ? expandedTabLayoutParams : defaultTabLayoutParams);
}
private void updateTabStyles() {
for (int i = 0; i < tabCount; i++) {
View v = tabsContainer.getChildAt(i);
v.setBackgroundResource(tabBackgroundResId);
if (v instanceof TextView) {
TextView tab = (TextView) v;
// tab.setTextSize(TypedValue.COMPLEX_UNIT_PX, tabTextSize);
// tab.setTypeface(tabTypeface, tabTypefaceStyle);
// tab.setTextColor(tabTextColor);
// setAllCaps() is only available from API 14, so the upper case is made manually if we are on a
// pre-ICS-build
if (textAllCaps) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
tab.setAllCaps(true);
} else {
// tab.setText(tab.getText().toString().toUpperCase(locale));
}
}
}
}
}
private void scrollToChild(int position, int offset) {
if (tabCount == 0) {
return;
}
int newScrollX = tabsContainer.getChildAt(position).getLeft() + offset;
if (position > 0 || offset > 0) {
newScrollX -= scrollOffset;
}
if (newScrollX != lastScrollX) {
lastScrollX = newScrollX;
scrollTo(newScrollX, 0);
}
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (isInEditMode() || tabCount == 0) {
return;
}
final int height = getHeight();
// draw indicator line
rectPaint.setColor(indicatorColor);
// default: line below current tab
View currentTab = tabsContainer.getChildAt(currentPosition);
float lineLeft = currentTab.getLeft();
float lineRight = currentTab.getRight();
// if there is an offset, start interpolating left and right coordinates between current and next tab
if (currentPositionOffset > 0f && currentPosition < tabCount - 1) {
View nextTab = tabsContainer.getChildAt(currentPosition + 1);
final float nextTabLeft = nextTab.getLeft();
final float nextTabRight = nextTab.getRight();
lineLeft = (currentPositionOffset * nextTabLeft + (1f - currentPositionOffset) * lineLeft);
lineRight = (currentPositionOffset * nextTabRight + (1f - currentPositionOffset) * lineRight);
}
canvas.drawRect(lineLeft, height - indicatorHeight, lineRight, height, rectPaint);
// draw underline
rectPaint.setColor(underlineColor);
canvas.drawRect(0, height - underlineHeight, tabsContainer.getWidth(), height, rectPaint);
// draw divider
dividerPaint.setColor(dividerColor);
for (int i = 0; i < tabCount - 1; i++) {
View tab = tabsContainer.getChildAt(i);
canvas.drawLine(tab.getRight(), dividerPadding, tab.getRight(), height - dividerPadding, dividerPaint);
}
}
private class PageListener implements OnPageChangeListener {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
currentPosition = position;
currentPositionOffset = positionOffset;
scrollToChild(position, (int) (positionOffset * tabsContainer.getChildAt(position).getWidth()));
invalidate();
if (delegatePageListener != null) {
delegatePageListener.onPageScrolled(position, positionOffset, positionOffsetPixels);
}
}
#Override
public void onPageScrollStateChanged(int state) {
if (state == ViewPager.SCROLL_STATE_IDLE) {
scrollToChild(pager.getCurrentItem(), 0);
}
if (delegatePageListener != null) {
delegatePageListener.onPageScrollStateChanged(state);
}
}
#Override
public void onPageSelected(int position) {
if (delegatePageListener != null) {
delegatePageListener.onPageSelected(position);
}
}
}
public void setIndicatorColor(int indicatorColor) {
this.indicatorColor = indicatorColor;
invalidate();
}
public void setIndicatorColorResource(int resId) {
this.indicatorColor = getResources().getColor(resId);
invalidate();
}
public int getIndicatorColor() {
return this.indicatorColor;
}
public void setIndicatorHeight(int indicatorLineHeightPx) {
this.indicatorHeight = indicatorLineHeightPx;
invalidate();
}
public int getIndicatorHeight() {
return indicatorHeight;
}
public void setUnderlineColor(int underlineColor) {
this.underlineColor = underlineColor;
invalidate();
}
public void setUnderlineColorResource(int resId) {
this.underlineColor = getResources().getColor(resId);
invalidate();
}
public int getUnderlineColor() {
return underlineColor;
}
public void setDividerColor(int dividerColor) {
this.dividerColor = dividerColor;
invalidate();
}
public void setDividerColorResource(int resId) {
this.dividerColor = getResources().getColor(resId);
invalidate();
}
public int getDividerColor() {
return dividerColor;
}
public void setUnderlineHeight(int underlineHeightPx) {
this.underlineHeight = underlineHeightPx;
invalidate();
}
public int getUnderlineHeight() {
return underlineHeight;
}
public void setDividerPadding(int dividerPaddingPx) {
this.dividerPadding = dividerPaddingPx;
invalidate();
}
public int getDividerPadding() {
return dividerPadding;
}
public void setScrollOffset(int scrollOffsetPx) {
this.scrollOffset = scrollOffsetPx;
invalidate();
}
public int getScrollOffset() {
return scrollOffset;
}
public void setShouldExpand(boolean shouldExpand) {
this.shouldExpand = shouldExpand;
requestLayout();
}
public boolean getShouldExpand() {
return shouldExpand;
}
public boolean isTextAllCaps() {
return textAllCaps;
}
public void setAllCaps(boolean textAllCaps) {
this.textAllCaps = textAllCaps;
}
/*public void setTextSize(int textSizePx) {
this.tabTextSize = textSizePx;
updateTabStyles();
}*/
/*public int getTextSize() {
return tabTextSize;
}*/
/*public void setTextColor(int textColor) {
// this.tabTextColor = textColor;
updateTabStyles();
}*/
/*public void setTextColorResource(int resId) {
// this.tabTextColor = getResources().getColor(resId);
updateTabStyles();
}*/
/*public int getTextColor() {
return tabTextColor;
}*/
/*public void setTypeface(Typeface typeface, int style) {
this.tabTypeface = typeface;
this.tabTypefaceStyle = style;
updateTabStyles();
}*/
public void setTabBackground(int resId) {
this.tabBackgroundResId = resId;
}
public int getTabBackground() {
return tabBackgroundResId;
}
public void setTabPaddingLeftRight(int paddingPx) {
this.tabPadding = paddingPx;
updateTabStyles();
}
public int getTabPaddingLeftRight() {
return tabPadding;
}
#Override
public void onRestoreInstanceState(Parcelable state) {
SavedState savedState = (SavedState) state;
super.onRestoreInstanceState(savedState.getSuperState());
currentPosition = savedState.currentPosition;
requestLayout();
}
#Override
public Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState();
SavedState savedState = new SavedState(superState);
savedState.currentPosition = currentPosition;
return savedState;
}
static class SavedState extends BaseSavedState {
int currentPosition;
public SavedState(Parcelable superState) {
super(superState);
}
private SavedState(Parcel in) {
super(in);
currentPosition = in.readInt();
}
#Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeInt(currentPosition);
}
public static final Creator<SavedState> CREATOR = new Creator<SavedState>() {
#Override
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
#Override
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}
}
Am I doing something wrong?
Please check the addTextTab(final int position, String title),
that is where I have added the SpannableString logic.
So, from your question and requirements, it seems your problem is that you want to display more than just a single String per tab, but are limited because the default implementation uses CharSequence getPageTitle(int position). Instead of using a spannable to force a line break, you can use a custom tab.
PagerSlidingTabStrip has an interface called PagerSlidingTabStrip.CustomTabProvider which you can implement on your PagerAdapter. If your PagerAdapter implements this interface, then the PagerSlidingTabStrip will not use the default tab view, nor will it try to bind data to the tab using getPageTitle(int position).
Instead it delegates this responsibility to your PagerAdapter - this lets you inflate the view you want to use as a tab, and bind data to it, no restrictions:
Above you can see I have a two level custom tab - this is a LinearLayout with two TextViews - where I bind data from the following enum:
private enum MyData {
HELLO,
WORLD,
WHAT,
IS,
THE,
HAPS;
String getFirstLine() {
return name();
}
String getSecondLine() {
return "2_" + name() + "_2";
}
}
My PagerAdapter is just a naive implementation of PagerAdapter, but the important addition is the implements clause:
private static class MyAdapter extends PagerAdapter
implements PagerSlidingTabStrip.CustomTabProvider {
...
#Override
public View getCustomTabView(ViewGroup viewGroup, int position) {
LayoutInflater layoutInflater = LayoutInflater.from(viewGroup.getContext());
MyCustomTabView tabView = (MyCustomTabView) layoutInflater.inflate(R.layout.view_custom_tab, viewGroup, false);
tabView.setFirstLineText(MyData.values()[position].getFirstLine());
tabView.setSecondLineTextView(MyData.values()[position].getSecondLine());
return tabView;
}
}
In this case, you don't need to rely on the single CharSequence returned by getPageTitle(int position) because you're being explicit in your binding of data. You can see the full adapter here.
Your suggesstion was a great way out, however I have used the getPageTitle to return the split string and added the string to two different textview with different styles and added the same to a linear la}yout.
Please see my code
public CharSequence getPageTitle(int position) {
return (TITLES[position]+"\n"+cardNoList.get(position));
}
And my
private void addTextTab(final int position, String title) {
LayoutParams titleLayout = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT );
LinearLayout linLayout = new LinearLayout(getContext());
linLayout.setOrientation(LinearLayout.VERTICAL);
linLayout.setLayoutParams(titleLayout);
TextView titleText = new TextView(getContext());
titleText.setText(title.split("\n")[0]);
titleText.setGravity(Gravity.CENTER);
TextView subTitle = new TextView(getContext());
subTitle.setText(title.split("\n")[1]);
subTitle.setGravity(Gravity.CENTER);
imvArrow = new ImageView(getContext());
imvArrow.setImageResource(R.drawable.icn_arrow_up_blue_large);
imvArrow.setVisibility(GONE);
linLayout.addView(titleText);
linLayout.addView(subTitle);
linLayout.addView(imvArrow);
addTab(position, linLayout);
}
For further customiztion you can use this code.
private class PageListener implements ViewPager.OnPageChangeListener {
public int prevPage = 0;
public int curPage = 0;
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
currentPosition = position;
currentPositionOffset = positionOffset;
scrollToChild(position, (int) (positionOffset * tabsContainer.getChildAt(position).getWidth()));
invalidate();
if (delegatePageListener != null) {
delegatePageListener.onPageScrolled(position, positionOffset, positionOffsetPixels);
}
}
#Override
public void onPageScrollStateChanged(int state) {
if (state == ViewPager.SCROLL_STATE_IDLE) {
scrollToChild(pager.getCurrentItem(), 0);
}
if (delegatePageListener != null) {
delegatePageListener.onPageScrollStateChanged(state);
}
}
#Override
public void onPageSelected(int position) {
//MYcode
prevPage = curPage;
curPage = position;
/*TextView tab = (TextView) tabsContainer.getChildAt(prevPage);
tab.setTextColor(tabTextColor);
tab = (TextView) tabsContainer.getChildAt(curPage);
tab.setTextColor(tabActiveTextColor);*/
LinearLayout ll = (LinearLayout) tabsContainer.getChildAt(prevPage);
TextView titleText = (TextView) ll.getChildAt(0);
titleText.setTextColor(getResources().getColor(R.color.accounts_darkgray_text));
imvArrow = (ImageView)ll.getChildAt(2);
imvArrow.setVisibility(GONE);
ll = (LinearLayout) tabsContainer.getChildAt(curPage);
titleText = (TextView) ll.getChildAt(0);
titleText.setTextColor(getResources().getColor(R.color.blue));
imvArrow = (ImageView)ll.getChildAt(2);
imvArrow.setVisibility(VISIBLE);
if (delegatePageListener != null) {
delegatePageListener.onPageSelected(position);
}
}
}

PagerSlidingTabStrip - Title Text in RTL not appearing

I am using this PagerSlidingTabStrip and supporting both english and arabic languages. This all works fine for english locale but i am facing problems with the title in arabic. I am able to scroll right to left as well in arabic locale.
My data in the tab title only includes the formatted date string (DD-MMM-YYYY), i cannot see the title on the UI but when i check my logs i am able to see that my titles are set correctly as i am sending this in my request.
My initial assumption was something going wrong in the styling or color but that was not the case.
How can I ensure the text is visible on the UI?
Here is the class i have customized from PagerSlidingTapStrip:
public class PagerSlidingTabStrip extends HorizontalScrollView {
public interface IconTabProvider {
public int getPageIconResId(int position);
}
// #formatter:off
private static final int[] ATTRS = new int[] {
android.R.attr.textSize,
android.R.attr.textColor
};
// #formatter:on
private LinearLayout.LayoutParams defaultTabLayoutParams;
private LinearLayout.LayoutParams expandedTabLayoutParams;
private final PageListener pageListener = new PageListener();
public OnPageChangeListener delegatePageListener;
private LinearLayout tabsContainer;
private ViewPager pager;
private int tabCount;
private int currentPosition = 0;
private float currentPositionOffset = 0f;
private Paint rectPaint;
private Paint dividerPaint;
private int indicatorColor = 0xFF666666;
private int underlineColor = 0x1A000000;
private int dividerColor = 0x1A000000;
private boolean shouldExpand = false;
private boolean textAllCaps = true;
private int scrollOffset = 52;
private int indicatorHeight = 8;
private int underlineHeight = 2;
private int dividerPadding = 12;
private int tabPadding = 24;
private int tabWidth = 60;
private int dividerWidth = 1;
private int tabTextSize = 12;
private int tabTextColor = 0xFF666666;
private Typeface tabTypeface = Typeface.SANS_SERIF;
private int tabTypefaceStyle = Typeface.BOLD;
private int lastScrollX = 0;
private int tabBackgroundResId = R.drawable.background_tab;
private Locale locale;
public PagerSlidingTabStrip(Context context) {
this(context, null);
}
public PagerSlidingTabStrip(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public PagerSlidingTabStrip(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setFillViewport(true);
setWillNotDraw(false);
tabsContainer = new LinearLayout(context);
tabsContainer.setOrientation(LinearLayout.HORIZONTAL);
tabsContainer.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
addView(tabsContainer);
DisplayMetrics dm = getResources().getDisplayMetrics();
scrollOffset = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, scrollOffset, dm);
indicatorHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, indicatorHeight, dm);
underlineHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, underlineHeight, dm);
dividerPadding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dividerPadding, dm);
tabPadding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, tabPadding, dm);
tabWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, tabWidth, dm);
dividerWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dividerWidth, dm);
tabTextSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, tabTextSize, dm);
// get system attrs (android:textSize and android:textColor)
TypedArray a = context.obtainStyledAttributes(attrs, ATTRS);
tabTextSize = a.getDimensionPixelSize(0, tabTextSize);
tabTextColor = a.getColor(1, tabTextColor);
a.recycle();
// get custom attrs
a = context.obtainStyledAttributes(attrs, R.styleable.PagerSlidingTabStrip);
indicatorColor = a.getColor(R.styleable.PagerSlidingTabStrip_pstsIndicatorColor, indicatorColor);
underlineColor = a.getColor(R.styleable.PagerSlidingTabStrip_pstsUnderlineColor, underlineColor);
dividerColor = a.getColor(R.styleable.PagerSlidingTabStrip_pstsDividerColor, dividerColor);
indicatorHeight = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsIndicatorHeight, indicatorHeight);
underlineHeight = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsUnderlineHeight, underlineHeight);
dividerPadding = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsDividerPadding, dividerPadding);
tabPadding = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsTabPaddingLeftRight, tabPadding);
tabWidth = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsTabPaddingLeftRight, tabWidth);
tabBackgroundResId = a.getResourceId(R.styleable.PagerSlidingTabStrip_pstsTabBackground, tabBackgroundResId);
shouldExpand = a.getBoolean(R.styleable.PagerSlidingTabStrip_pstsShouldExpand, shouldExpand);
scrollOffset = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsScrollOffset, scrollOffset);
textAllCaps = a.getBoolean(R.styleable.PagerSlidingTabStrip_pstsTextAllCaps, textAllCaps);
a.recycle();
rectPaint = new Paint();
rectPaint.setAntiAlias(true);
rectPaint.setStyle(Style.FILL);
dividerPaint = new Paint();
dividerPaint.setAntiAlias(true);
dividerPaint.setStrokeWidth(dividerWidth);
defaultTabLayoutParams = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
expandedTabLayoutParams = new LinearLayout.LayoutParams(0, LayoutParams.MATCH_PARENT, 1.0f);
/*if (locale == null) {
locale = getResources().getConfiguration().locale;
}*/
}
public void setViewPager(ViewPager pager) {
this.pager = pager;
if (pager.getAdapter() == null) {
throw new IllegalStateException("ViewPager does not have adapter instance.");
}
pager.setOnPageChangeListener(pageListener);
notifyDataSetChanged();
}
public void setOnPageChangeListener(OnPageChangeListener listener) {
this.delegatePageListener = listener;
}
public void notifyDataSetChanged() {
tabsContainer.removeAllViews();
tabCount = pager.getAdapter().getCount();
for (int i = 0; i < tabCount; i++) {
if (pager.getAdapter() instanceof IconTabProvider) {
addIconTab(i, ((IconTabProvider) pager.getAdapter()).getPageIconResId(i));
} else {
addTextTab(i, pager.getAdapter().getPageTitle(i).toString());
}
}
updateTabStyles();
getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#SuppressWarnings("deprecation")
#SuppressLint("NewApi")
#Override
public void onGlobalLayout() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
getViewTreeObserver().removeGlobalOnLayoutListener(this);
} else {
getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
currentPosition = pager.getCurrentItem();
scrollToChild(currentPosition, 0);
}
});
}
private void addTextTab(final int position, String title) {
TextView tab = new TextView(getContext());
tab.setText(title);
tab.setGravity(Gravity.CENTER);
tab.setSingleLine();
addTab(position, tab);
}
private void addIconTab(final int position, int resId) {
ImageButton tab = new ImageButton(getContext());
tab.setImageResource(resId);
addTab(position, tab);
}
private void addTab(final int position, View tab) {
tab.setFocusable(true);
tab.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
pager.setCurrentItem(position);
}
});
tab.setPadding(tabPadding, 0, tabPadding, 0);
tabsContainer.addView(tab, position, shouldExpand ? expandedTabLayoutParams : defaultTabLayoutParams);
}
private void updateTabStyles() {
for (int i = 0; i < tabCount; i++) {
View v = tabsContainer.getChildAt(i);
v.setBackgroundResource(tabBackgroundResId);
if (v instanceof TextView) {
TextView tab = (TextView) v;
tab.setTextSize(TypedValue.COMPLEX_UNIT_PX, tabTextSize);
tab.setTypeface(tabTypeface, tabTypefaceStyle);
tab.setTextColor(tabTextColor);
tab.setWidth(tabWidth);
tab.setEllipsize(TruncateAt.END);
// setAllCaps() is only available from API 14, so the upper case is made manually if we are on a
// pre-ICS-build
if (textAllCaps) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
//tab.setAllCaps(true);
tab.setAllCaps(false);
} else {
tab.setText(tab.getText().toString().toUpperCase(locale));
// tab.setText(tab.getText().toString());
}
}
}
}
}
private void scrollToChild(int position, int offset) {
if (tabCount == 0) {
return;
}
int newScrollX = tabsContainer.getChildAt(position).getLeft() + offset;
if (position > 0 || offset > 0) {
newScrollX -= scrollOffset;
}
if (newScrollX != lastScrollX) {
lastScrollX = newScrollX;
scrollTo(newScrollX, 0);
}
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (isInEditMode() || tabCount == 0) {
return;
}
final int height = getHeight();
// draw indicator line
rectPaint.setColor(indicatorColor);
// default: line below current tab
View currentTab = tabsContainer.getChildAt(currentPosition);
float lineLeft = currentTab.getLeft();
float lineRight = currentTab.getRight();
// if there is an offset, start interpolating left and right coordinates between current and next tab
if (currentPositionOffset > 0f && currentPosition < tabCount - 1) {
View nextTab = tabsContainer.getChildAt(currentPosition + 1);
final float nextTabLeft = nextTab.getLeft();
final float nextTabRight = nextTab.getRight();
lineLeft = (currentPositionOffset * nextTabLeft + (1f - currentPositionOffset) * lineLeft);
lineRight = (currentPositionOffset * nextTabRight + (1f - currentPositionOffset) * lineRight);
}
canvas.drawRect(lineLeft, height - indicatorHeight, lineRight, height, rectPaint);
// draw underline
rectPaint.setColor(underlineColor);
canvas.drawRect(0, height - underlineHeight, tabsContainer.getWidth(), height, rectPaint);
// draw divider
dividerPaint.setColor(dividerColor);
for (int i = 0; i < tabCount - 1; i++) {
View tab = tabsContainer.getChildAt(i);
canvas.drawLine(tab.getRight(), dividerPadding, tab.getRight(), height - dividerPadding, dividerPaint);
}
}
private class PageListener implements OnPageChangeListener {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
currentPosition = position;
currentPositionOffset = positionOffset;
scrollToChild(position, (int) (positionOffset * tabsContainer.getChildAt(position).getWidth()));
invalidate();
if (delegatePageListener != null) {
delegatePageListener.onPageScrolled(position, positionOffset, positionOffsetPixels);
}
}
#Override
public void onPageScrollStateChanged(int state) {
if (state == ViewPager.SCROLL_STATE_IDLE) {
scrollToChild(pager.getCurrentItem(), 0);
}
if (delegatePageListener != null) {
delegatePageListener.onPageScrollStateChanged(state);
}
}
#Override
public void onPageSelected(int position) {
if (delegatePageListener != null) {
delegatePageListener.onPageSelected(position);
}
}
}
public void setIndicatorColor(int indicatorColor) {
this.indicatorColor = indicatorColor;
invalidate();
}
public void setIndicatorColorResource(int resId) {
this.indicatorColor = getResources().getColor(resId);
invalidate();
}
public int getIndicatorColor() {
return this.indicatorColor;
}
public void setIndicatorHeight(int indicatorLineHeightPx) {
this.indicatorHeight = indicatorLineHeightPx;
invalidate();
}
public int getIndicatorHeight() {
return indicatorHeight;
}
public void setUnderlineColor(int underlineColor) {
this.underlineColor = underlineColor;
invalidate();
}
public void setUnderlineColorResource(int resId) {
this.underlineColor = getResources().getColor(resId);
invalidate();
}
public int getUnderlineColor() {
return underlineColor;
}
public void setDividerColor(int dividerColor) {
this.dividerColor = dividerColor;
invalidate();
}
public void setDividerColorResource(int resId) {
this.dividerColor = getResources().getColor(resId);
invalidate();
}
public int getDividerColor() {
return dividerColor;
}
public void setUnderlineHeight(int underlineHeightPx) {
this.underlineHeight = underlineHeightPx;
invalidate();
}
public int getUnderlineHeight() {
return underlineHeight;
}
public void setDividerPadding(int dividerPaddingPx) {
this.dividerPadding = dividerPaddingPx;
invalidate();
}
public int getDividerPadding() {
return dividerPadding;
}
public void setScrollOffset(int scrollOffsetPx) {
this.scrollOffset = scrollOffsetPx;
invalidate();
}
public int getScrollOffset() {
return scrollOffset;
}
public void setShouldExpand(boolean shouldExpand) {
this.shouldExpand = shouldExpand;
requestLayout();
}
public boolean getShouldExpand() {
return shouldExpand;
}
public boolean isTextAllCaps() {
return textAllCaps;
}
public void setAllCaps(boolean textAllCaps) {
this.textAllCaps = textAllCaps;
}
public void setTextSize(int textSizePx) {
this.tabTextSize = textSizePx;
updateTabStyles();
}
public int getTextSize() {
return tabTextSize;
}
public void setTextColor(int textColor) {
this.tabTextColor = textColor;
updateTabStyles();
}
public void setTextColorResource(int resId) {
this.tabTextColor = getResources().getColor(resId);
updateTabStyles();
}
public int getTextColor() {
return tabTextColor;
}
public void setTypeface(Typeface typeface, int style) {
this.tabTypeface = typeface;
this.tabTypefaceStyle = style;
updateTabStyles();
}
public void setTabBackground(int resId) {
this.tabBackgroundResId = resId;
}
public int getTabBackground() {
return tabBackgroundResId;
}
public void setTabPaddingLeftRight(int paddingPx) {
this.tabPadding = paddingPx;
updateTabStyles();
}
public int getTabPaddingLeftRight() {
return tabPadding;
}
public void setTabWidth(int widthPx){
this.tabWidth = widthPx;
updateTabStyles();
}
#Override
public void onRestoreInstanceState(Parcelable state) {
SavedState savedState = (SavedState) state;
super.onRestoreInstanceState(savedState.getSuperState());
currentPosition = savedState.currentPosition;
requestLayout();
}
#Override
public Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState();
SavedState savedState = new SavedState(superState);
savedState.currentPosition = currentPosition;
return savedState;
}
static class SavedState extends BaseSavedState {
int currentPosition;
public SavedState(Parcelable superState) {
super(superState);
}
private SavedState(Parcel in) {
super(in);
currentPosition = in.readInt();
}
#Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeInt(currentPosition);
}
public static final Creator<SavedState> CREATOR = new Creator<SavedState>() {
#Override
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
#Override
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}
}
Update: This behavior is observed on some devices only and not all devices.

PagerSlidingTabStrip , no indicator at all

I am using
https://github.com/astuetz/PagerSlidingTabStrip
and a viewpager.
I have added code to get Icons working with selectors , and now i cant seem to enable or see a indicator
, have used xml and java attributes and methods respectively for setIndicatorColor , but cant seem to make it work.
PagerSlidingTabStrip.java
public class PagerSlidingTabStrip extends HorizontalScrollView {
public interface IconTabProvider {
public int getPageIconResId(int position);
}
// #formatter:off
private static final int[] ATTRS = new int[] {
android.R.attr.textSize,
android.R.attr.textColor
};
// #formatter:on
private LinearLayout.LayoutParams defaultTabLayoutParams;
private LinearLayout.LayoutParams expandedTabLayoutParams;
private final PageListener pageListener = new PageListener();
public OnPageChangeListener delegatePageListener;
private LinearLayout tabsContainer;
private ViewPager pager;
private int currentPageSelected = 0;
private int tabCount;
private int currentPosition = 0;
private float currentPositionOffset = 0f;
private Paint rectPaint;
private Paint dividerPaint;
private int indicatorColor = 0xFF666666;
private int underlineColor = 0x1A000000;
private int dividerColor = 0x1A000000;
private boolean shouldExpand = false;
private boolean textAllCaps = true;
private int scrollOffset = 52;
private int indicatorHeight = 8;
private int underlineHeight = 2;
private int dividerPadding = 12;
private int tabPadding = 0;
private int dividerWidth = 1;
private int tabTextSize = 12;
private int tabTextColor = 0xFF666666;
private Typeface tabTypeface = null;
private int tabTypefaceStyle = Typeface.BOLD;
private int lastScrollX = 0;
private int tabBackgroundResId = R.drawable.background_tab;
private Locale locale;
public PagerSlidingTabStrip(Context context) {
this(context, null);
}
public PagerSlidingTabStrip(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public PagerSlidingTabStrip(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setFillViewport(true);
setWillNotDraw(false);
tabsContainer = new LinearLayout(context);
tabsContainer.setOrientation(LinearLayout.HORIZONTAL);
tabsContainer.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
addView(tabsContainer);
DisplayMetrics dm = getResources().getDisplayMetrics();
scrollOffset = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, scrollOffset, dm);
indicatorHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, indicatorHeight, dm);
underlineHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, underlineHeight, dm);
dividerPadding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dividerPadding, dm);
tabPadding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, tabPadding, dm);
dividerWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dividerWidth, dm);
tabTextSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, tabTextSize, dm);
// get system attrs (android:textSize and android:textColor)
TypedArray a = context.obtainStyledAttributes(attrs, ATTRS);
tabTextSize = a.getDimensionPixelSize(0, tabTextSize);
tabTextColor = a.getColor(1, tabTextColor);
a.recycle();
// get custom attrs
a = context.obtainStyledAttributes(attrs, R.styleable.PagerSlidingTabStrip);
indicatorColor = a.getColor(R.styleable.PagerSlidingTabStrip_pstsIndicatorColor, indicatorColor);
underlineColor = a.getColor(R.styleable.PagerSlidingTabStrip_pstsUnderlineColor, underlineColor);
dividerColor = a.getColor(R.styleable.PagerSlidingTabStrip_pstsDividerColor, dividerColor);
indicatorHeight = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsIndicatorHeight, indicatorHeight);
underlineHeight = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsUnderlineHeight, underlineHeight);
dividerPadding = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsDividerPadding, dividerPadding);
tabPadding = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsTabPaddingLeftRight, tabPadding);
tabBackgroundResId = a.getResourceId(R.styleable.PagerSlidingTabStrip_pstsTabBackground, tabBackgroundResId);
shouldExpand = a.getBoolean(R.styleable.PagerSlidingTabStrip_pstsShouldExpand, shouldExpand);
scrollOffset = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsScrollOffset, scrollOffset);
textAllCaps = a.getBoolean(R.styleable.PagerSlidingTabStrip_pstsTextAllCaps, textAllCaps);
a.recycle();
rectPaint = new Paint();
rectPaint.setAntiAlias(true);
rectPaint.setStyle(Style.FILL);
dividerPaint = new Paint();
dividerPaint.setAntiAlias(true);
dividerPaint.setStrokeWidth(dividerWidth);
defaultTabLayoutParams = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
expandedTabLayoutParams = new LinearLayout.LayoutParams(0, LayoutParams.MATCH_PARENT, 1.0f);
if (locale == null) {
locale = getResources().getConfiguration().locale;
}
}
public void setViewPager(ViewPager pager) {
this.pager = pager;
if (pager.getAdapter() == null) {
throw new IllegalStateException("ViewPager does not have adapter instance.");
}
pager.setOnPageChangeListener(pageListener);
notifyDataSetChanged();
}
public void setOnPageChangeListener(OnPageChangeListener listener) {
this.delegatePageListener = listener;
}
public void notifyDataSetChanged() {
tabsContainer.removeAllViews();
tabCount = pager.getAdapter().getCount();
for (int i = 0; i < tabCount; i++) {
if (pager.getAdapter() instanceof IconTabProvider) {
addIconTab(i, ((IconTabProvider) pager.getAdapter()).getPageIconResId(i));
} else {
addTextTab(i, pager.getAdapter().getPageTitle(i).toString());
}
}
updateTabStyles();
getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#SuppressWarnings("deprecation")
#SuppressLint("NewApi")
#Override
public void onGlobalLayout() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
getViewTreeObserver().removeGlobalOnLayoutListener(this);
} else {
getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
currentPosition = pager.getCurrentItem();
scrollToChild(currentPosition, 0);
}
});
currentPosition = pager.getCurrentItem();
tabsContainer.getChildAt(currentPosition).setSelected(true);
scrollToChild(currentPosition, 0);
}
private void addTextTab(final int position, String title) {
TextView tab = new TextView(getContext());
tab.setText(title);
tab.setGravity(Gravity.CENTER);
tab.setSingleLine();
addTab(position, tab);
}
private void addIconTab(final int position, int resId) {
ImageButton tab = new ImageButton(getContext());
tab.setImageResource(resId);
addTab(position, tab);
}
private void addTab(final int position, View tab) {
tab.setFocusable(true);
tab.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
pager.setCurrentItem(position);
}
});
tab.setPadding(tabPadding, 0, tabPadding, 0);
tabsContainer.addView(tab, position, shouldExpand ? expandedTabLayoutParams : defaultTabLayoutParams);
}
private void updateTabStyles() {
for (int i = 0; i < tabCount; i++) {
View v = tabsContainer.getChildAt(i);
v.setBackgroundResource(tabBackgroundResId);
if (v instanceof TextView) {
TextView tab = (TextView) v;
tab.setTextSize(TypedValue.COMPLEX_UNIT_PX, tabTextSize);
tab.setTypeface(tabTypeface, tabTypefaceStyle);
tab.setTextColor(tabTextColor);
// setAllCaps() is only available from API 14, so the upper case is made manually if we are on a
// pre-ICS-build
if (textAllCaps) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
tab.setAllCaps(true);
} else {
tab.setText(tab.getText().toString().toUpperCase(locale));
}
}
}
}
}
private void scrollToChild(int position, int offset) {
if (tabCount == 0) {
return;
}
int newScrollX = tabsContainer.getChildAt(position).getLeft() + offset;
if (position > 0 || offset > 0) {
newScrollX -= scrollOffset;
}
if (newScrollX != lastScrollX) {
lastScrollX = newScrollX;
scrollTo(newScrollX, 0);
}
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (isInEditMode() || tabCount == 0) {
return;
}
final int height = getHeight();
// draw indicator line
rectPaint.setColor(indicatorColor);
// default: line below current tab
View currentTab = tabsContainer.getChildAt(currentPosition);
float lineLeft = currentTab.getLeft();
float lineRight = currentTab.getRight();
// if there is an offset, start interpolating left and right coordinates between current and next tab
if (currentPositionOffset > 0f && currentPosition < tabCount - 1) {
View nextTab = tabsContainer.getChildAt(currentPosition + 1);
final float nextTabLeft = nextTab.getLeft();
final float nextTabRight = nextTab.getRight();
lineLeft = (currentPositionOffset * nextTabLeft + (1f - currentPositionOffset) * lineLeft);
lineRight = (currentPositionOffset * nextTabRight + (1f - currentPositionOffset) * lineRight);
}
canvas.drawRect(lineLeft, height - indicatorHeight, lineRight, height, rectPaint);
// draw underline
rectPaint.setColor(underlineColor);
canvas.drawRect(0, height - underlineHeight, tabsContainer.getWidth(), height, rectPaint);
// draw divider
dividerPaint.setColor(dividerColor);
for (int i = 0; i < tabCount - 1; i++) {
View tab = tabsContainer.getChildAt(i);
canvas.drawLine(tab.getRight(), dividerPadding, tab.getRight(), height - dividerPadding, dividerPaint);
}
}
private class PageListener implements OnPageChangeListener {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
currentPosition = position;
currentPositionOffset = positionOffset;
scrollToChild(position, (int) (positionOffset * tabsContainer.getChildAt(position).getWidth()));
invalidate();
if (delegatePageListener != null) {
delegatePageListener.onPageScrolled(position, positionOffset, positionOffsetPixels);
}
}
#Override
public void onPageScrollStateChanged(int state) {
if (state == ViewPager.SCROLL_STATE_IDLE) {
scrollToChild(pager.getCurrentItem(), 0);
}
if (delegatePageListener != null) {
delegatePageListener.onPageScrollStateChanged(state);
}
}
#Override
public void onPageSelected(int position) {
tabsContainer.getChildAt(currentPageSelected).setSelected(false);
currentPageSelected = position;
tabsContainer.getChildAt(position).setSelected(true);
if (delegatePageListener != null) {
delegatePageListener.onPageSelected(position);
}
}
}
public void setIndicatorColor(int indicatorColor) {
this.indicatorColor = indicatorColor;
invalidate();
}
public void setIndicatorColorResource(int resId) {
this.indicatorColor = getResources().getColor(resId);
invalidate();
}
public int getIndicatorColor() {
return this.indicatorColor;
}
public void setIndicatorHeight(int indicatorLineHeightPx) {
this.indicatorHeight = indicatorLineHeightPx;
invalidate();
}
public int getIndicatorHeight() {
return indicatorHeight;
}
public void setUnderlineColor(int underlineColor) {
this.underlineColor = underlineColor;
invalidate();
}
public void setUnderlineColorResource(int resId) {
this.underlineColor = getResources().getColor(resId);
invalidate();
}
public int getUnderlineColor() {
return underlineColor;
}
public void setDividerColor(int dividerColor) {
this.dividerColor = dividerColor;
invalidate();
}
public void setDividerColorResource(int resId) {
this.dividerColor = getResources().getColor(resId);
invalidate();
}
public int getDividerColor() {
return dividerColor;
}
public void setUnderlineHeight(int underlineHeightPx) {
this.underlineHeight = underlineHeightPx;
invalidate();
}
public int getUnderlineHeight() {
return underlineHeight;
}
public void setDividerPadding(int dividerPaddingPx) {
this.dividerPadding = dividerPaddingPx;
invalidate();
}
public int getDividerPadding() {
return dividerPadding;
}
public void setScrollOffset(int scrollOffsetPx) {
this.scrollOffset = scrollOffsetPx;
invalidate();
}
public int getScrollOffset() {
return scrollOffset;
}
public void setShouldExpand(boolean shouldExpand) {
this.shouldExpand = shouldExpand;
requestLayout();
}
public boolean getShouldExpand() {
return shouldExpand;
}
public boolean isTextAllCaps() {
return textAllCaps;
}
public void setAllCaps(boolean textAllCaps) {
this.textAllCaps = textAllCaps;
}
public void setTextSize(int textSizePx) {
this.tabTextSize = textSizePx;
updateTabStyles();
}
public int getTextSize() {
return tabTextSize;
}
public void setTextColor(int textColor) {
this.tabTextColor = textColor;
updateTabStyles();
}
public void setTextColorResource(int resId) {
this.tabTextColor = getResources().getColor(resId);
updateTabStyles();
}
public int getTextColor() {
return tabTextColor;
}
public void setTypeface(Typeface typeface, int style) {
this.tabTypeface = typeface;
this.tabTypefaceStyle = style;
updateTabStyles();
}
public void setTabBackground(int resId) {
this.tabBackgroundResId = resId;
}
public int getTabBackground() {
return tabBackgroundResId;
}
public void setTabPaddingLeftRight(int paddingPx) {
this.tabPadding = paddingPx;
updateTabStyles();
}
public int getTabPaddingLeftRight() {
return tabPadding;
}
#Override
public void onRestoreInstanceState(Parcelable state) {
SavedState savedState = (SavedState) state;
super.onRestoreInstanceState(savedState.getSuperState());
currentPosition = savedState.currentPosition;
requestLayout();
}
#Override
public Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState();
SavedState savedState = new SavedState(superState);
savedState.currentPosition = currentPosition;
return savedState;
}
static class SavedState extends BaseSavedState {
int currentPosition;
public SavedState(Parcelable superState) {
super(superState);
}
private SavedState(Parcel in) {
super(in);
currentPosition = in.readInt();
}
#Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeInt(currentPosition);
}
public static final Creator<SavedState> CREATOR = new Creator<SavedState>() {
#Override
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
#Override
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}
}
and my XML :
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true" >
<PagerSlidingTabStrip
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="#dimen/abs__action_bar_default_height"
app:pstsTabBackground="#color/ui_global"
app:pstsShouldExpand="true"
app:pstsIndicatorColor="#FFEFEB40"
app:pstsDividerColor="#color/ui_global"
app:pstsTabPaddingLeftRight="14dip"/>
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="fill_parent"
android:layout_below="#+id/tabs"
android:layout_height="wrap_content" >
</android.support.v4.view.ViewPager>
</RelativeLayout>
please remove pstsTabBackground.
<com.example.PagerSlidingTabStrip
android:id="#+id/tabs_strip"
android:layout_width="match_parent"
android:layout_height="48dip"
android:background="#ffffff"
app:pstsDividerColor="#00000000"
app:pstsIndicatorColor="#aa66cc"
app:pstsIndicatorHeight="5dp"
app:pstsTabPaddingLeftRight="20dp"
app:pstsTextAllCaps="false"
app:pstsUnderlineColor="#ffffff" />

Icon selector not working with PagerSlidingTabStrips

I've integrated PagerSlidingTabStrips with Icons only. But I selector on icons are not working with PagerSlidingTabStrips.
xml
<PagerSlidingTabStrip
android:id="#+id/pager_sliding_tab_strip"
android:layout_width="fill_parent"
android:layout_height="45dip"
android:background="#color/white"
app:pstsDividerColor="#FFFFA500"
app:pstsIndicatorColor="#FFFFA500"
app:pstsTabPaddingLeftRight="14dip"
app:pstsUnderlineColor="#FFFFA500" />
Added implements IconTabProvider on my ViewPager which works perfectly.
public class ViewPagerAdapter extends FragmentPagerAdapter implements IconTabProvider {
final int PAGE_COUNT = 3;
private final int[] ICONS = { R.drawable.tab_icon_zname_contacts_selector, R.drawable.tab_icon_zname_friends_selector,
R.drawable.tab_icon_zname_call_log_selector };
#Override
public int getPageIconResId(int position) {
return ICONS[position];
}
}
iconSelector
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/tab_icon_zname_call_log_selected" android:state_selected="true"/>
<item android:drawable="#drawable/tab_icon_zname_call_log" android:state_selected="false"/>
</selector>
How to make icon selector work with PagerSlidingTabStrips? I wanted icon with Orange color when that tab is selected but it's returning grey one only no matter what.
I've found fix for Icon_Selector for PagerSlidingTabStrips within it's closed issues.
Modify PagerSlidingTabStrips.java and add following code
private int currentPageSelected = 0; //Fix : ICON SELECTOR
Append on NotifyDataSetChanged method inside OnGlobalLayoutListener
currentPosition = pager.getCurrentItem();
tabsContainer.getChildAt(currentPosition).setSelected(true); //ADDED THESE
scrollToChild(currentPosition, 0);
Modified the onPageSelected():
#Override
public void onPageSelected(int position) {
tabsContainer.getChildAt(currentPageSelected).setSelected(false);
currentPageSelected = position;
tabsContainer.getChildAt(position).setSelected(true);
if (delegatePageListener != null) {
delegatePageListener.onPageSelected(position
}
}
IconSelector
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/tab_icon_zname_call_log_selected" android:state_selected="true"/>
<item android:drawable="#drawable/tab_icon_zname_call_log_selected" android:state_pressed="true"/>
<item android:drawable="#drawable/tab_icon_zname_call_log"/>
</selector>
PagerSlidingTabStrips.java
import java.util.Locale;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Typeface;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.widget.HorizontalScrollView;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.netdoers.zname.R;
public class PagerSlidingTabStrip extends HorizontalScrollView {
public interface IconTabProvider {
public int getPageIconResId(int position);
}
// #formatter:off
private static final int[] ATTRS = new int[] {
android.R.attr.textSize,
android.R.attr.textColor
};
// #formatter:on
private LinearLayout.LayoutParams defaultTabLayoutParams;
private LinearLayout.LayoutParams expandedTabLayoutParams;
private final PageListener pageListener = new PageListener();
public OnPageChangeListener delegatePageListener;
private LinearLayout tabsContainer;
private ViewPager pager;
private int tabCount;
private int currentPosition = 0;
private float currentPositionOffset = 0f;
private Paint rectPaint;
private Paint dividerPaint;
private int currentPageSelected = 0; //Fix : ICON SELECTOR
private int indicatorColor = 0xFF666666;
private int underlineColor = 0x1A000000;
private int dividerColor = 0x1A000000;
private boolean shouldExpand = false;
private boolean textAllCaps = true;
private int scrollOffset = 52;
private int indicatorHeight = 8;
private int underlineHeight = 2;
private int dividerPadding = 12;
private int tabPadding = 24;
private int dividerWidth = 1;
private int tabTextSize = 12;
private int tabTextColor = 0xFF666666;
private Typeface tabTypeface = null;
private int tabTypefaceStyle = Typeface.BOLD;
private int lastScrollX = 0;
private int tabBackgroundResId = R.drawable.background_tab;
private Locale locale;
public PagerSlidingTabStrip(Context context) {
this(context, null);
}
public PagerSlidingTabStrip(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public PagerSlidingTabStrip(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setFillViewport(true);
setWillNotDraw(false);
tabsContainer = new LinearLayout(context);
tabsContainer.setOrientation(LinearLayout.HORIZONTAL);
tabsContainer.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
addView(tabsContainer);
DisplayMetrics dm = getResources().getDisplayMetrics();
scrollOffset = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, scrollOffset, dm);
indicatorHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, indicatorHeight, dm);
underlineHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, underlineHeight, dm);
dividerPadding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dividerPadding, dm);
tabPadding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, tabPadding, dm);
dividerWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dividerWidth, dm);
tabTextSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, tabTextSize, dm);
// get system attrs (android:textSize and android:textColor)
TypedArray a = context.obtainStyledAttributes(attrs, ATTRS);
tabTextSize = a.getDimensionPixelSize(0, tabTextSize);
tabTextColor = a.getColor(1, tabTextColor);
a.recycle();
// get custom attrs
a = context.obtainStyledAttributes(attrs, R.styleable.PagerSlidingTabStrip);
indicatorColor = a.getColor(R.styleable.PagerSlidingTabStrip_pstsIndicatorColor, indicatorColor);
underlineColor = a.getColor(R.styleable.PagerSlidingTabStrip_pstsUnderlineColor, underlineColor);
dividerColor = a.getColor(R.styleable.PagerSlidingTabStrip_pstsDividerColor, dividerColor);
indicatorHeight = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsIndicatorHeight, indicatorHeight);
underlineHeight = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsUnderlineHeight, underlineHeight);
dividerPadding = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsDividerPadding, dividerPadding);
tabPadding = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsTabPaddingLeftRight, tabPadding);
tabBackgroundResId = a.getResourceId(R.styleable.PagerSlidingTabStrip_pstsTabBackground, tabBackgroundResId);
shouldExpand = a.getBoolean(R.styleable.PagerSlidingTabStrip_pstsShouldExpand, shouldExpand);
scrollOffset = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsScrollOffset, scrollOffset);
textAllCaps = a.getBoolean(R.styleable.PagerSlidingTabStrip_pstsTextAllCaps, textAllCaps);
a.recycle();
rectPaint = new Paint();
rectPaint.setAntiAlias(true);
rectPaint.setStyle(Style.FILL);
dividerPaint = new Paint();
dividerPaint.setAntiAlias(true);
dividerPaint.setStrokeWidth(dividerWidth);
defaultTabLayoutParams = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
expandedTabLayoutParams = new LinearLayout.LayoutParams(0, LayoutParams.MATCH_PARENT, 1.0f);
if (locale == null) {
locale = getResources().getConfiguration().locale;
}
}
public void setViewPager(ViewPager pager) {
this.pager = pager;
if (pager.getAdapter() == null) {
throw new IllegalStateException("ViewPager does not have adapter instance.");
}
pager.setOnPageChangeListener(pageListener);
notifyDataSetChanged();
}
public void setOnPageChangeListener(OnPageChangeListener listener) {
this.delegatePageListener = listener;
}
public void notifyDataSetChanged() {
tabsContainer.removeAllViews();
tabCount = pager.getAdapter().getCount();
for (int i = 0; i < tabCount; i++) {
if (pager.getAdapter() instanceof IconTabProvider) {
addIconTab(i, ((IconTabProvider) pager.getAdapter()).getPageIconResId(i));
} else {
addTextTab(i, pager.getAdapter().getPageTitle(i).toString());
}
}
updateTabStyles();
getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#SuppressWarnings("deprecation")
#SuppressLint("NewApi")
#Override
public void onGlobalLayout() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
getViewTreeObserver().removeGlobalOnLayoutListener(this);
} else {
getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
currentPosition = pager.getCurrentItem();
tabsContainer.getChildAt(currentPosition).setSelected(true);//Fix : ICON SELECTOR
scrollToChild(currentPosition, 0);
}
});
}
private void addTextTab(final int position, String title) {
TextView tab = new TextView(getContext());
tab.setText(title);
tab.setGravity(Gravity.CENTER);
tab.setSingleLine();
addTab(position, tab);
}
private void addIconTab(final int position, int resId) {
ImageButton tab = new ImageButton(getContext());
tab.setImageResource(resId);
addTab(position, tab);
}
private void addTab(final int position, View tab) {
tab.setFocusable(true);
tab.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
pager.setCurrentItem(position);
}
});
tab.setPadding(tabPadding, 0, tabPadding, 0);
tabsContainer.addView(tab, position, shouldExpand ? expandedTabLayoutParams : defaultTabLayoutParams);
}
private void updateTabStyles() {
for (int i = 0; i < tabCount; i++) {
View v = tabsContainer.getChildAt(i);
v.setBackgroundResource(tabBackgroundResId);
if (v instanceof TextView) {
TextView tab = (TextView) v;
tab.setTextSize(TypedValue.COMPLEX_UNIT_PX, tabTextSize);
tab.setTypeface(tabTypeface, tabTypefaceStyle);
tab.setTextColor(tabTextColor);
// setAllCaps() is only available from API 14, so the upper case is made manually if we are on a
// pre-ICS-build
if (textAllCaps) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
tab.setAllCaps(true);
} else {
tab.setText(tab.getText().toString().toUpperCase(locale));
}
}
}
}
}
private void scrollToChild(int position, int offset) {
if (tabCount == 0) {
return;
}
int newScrollX = tabsContainer.getChildAt(position).getLeft() + offset;
if (position > 0 || offset > 0) {
newScrollX -= scrollOffset;
}
if (newScrollX != lastScrollX) {
lastScrollX = newScrollX;
scrollTo(newScrollX, 0);
}
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (isInEditMode() || tabCount == 0) {
return;
}
final int height = getHeight();
// draw indicator line
rectPaint.setColor(indicatorColor);
// default: line below current tab
View currentTab = tabsContainer.getChildAt(currentPosition);
float lineLeft = currentTab.getLeft();
float lineRight = currentTab.getRight();
// if there is an offset, start interpolating left and right coordinates between current and next tab
if (currentPositionOffset > 0f && currentPosition < tabCount - 1) {
View nextTab = tabsContainer.getChildAt(currentPosition + 1);
final float nextTabLeft = nextTab.getLeft();
final float nextTabRight = nextTab.getRight();
lineLeft = (currentPositionOffset * nextTabLeft + (1f - currentPositionOffset) * lineLeft);
lineRight = (currentPositionOffset * nextTabRight + (1f - currentPositionOffset) * lineRight);
}
canvas.drawRect(lineLeft, height - indicatorHeight, lineRight, height, rectPaint);
// draw underline
rectPaint.setColor(underlineColor);
canvas.drawRect(0, height - underlineHeight, tabsContainer.getWidth(), height, rectPaint);
// draw divider
dividerPaint.setColor(dividerColor);
for (int i = 0; i < tabCount - 1; i++) {
View tab = tabsContainer.getChildAt(i);
canvas.drawLine(tab.getRight(), dividerPadding, tab.getRight(), height - dividerPadding, dividerPaint);
}
}
private class PageListener implements OnPageChangeListener {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
currentPosition = position;
currentPositionOffset = positionOffset;
scrollToChild(position, (int) (positionOffset * tabsContainer.getChildAt(position).getWidth()));
invalidate();
if (delegatePageListener != null) {
delegatePageListener.onPageScrolled(position, positionOffset, positionOffsetPixels);
}
}
#Override
public void onPageScrollStateChanged(int state) {
if (state == ViewPager.SCROLL_STATE_IDLE) {
scrollToChild(pager.getCurrentItem(), 0);
}
if (delegatePageListener != null) {
delegatePageListener.onPageScrollStateChanged(state);
}
}
#Override
public void onPageSelected(int position) {
/**
* Fix : ICON SELECTOR
*/
tabsContainer.getChildAt(currentPageSelected).setSelected(false);
currentPageSelected = position;
tabsContainer.getChildAt(position).setSelected(true);
/**
* Fix : ICON SELECTOR
*/
if (delegatePageListener != null) {
delegatePageListener.onPageSelected(position);
}
}
}
public void setIndicatorColor(int indicatorColor) {
this.indicatorColor = indicatorColor;
invalidate();
}
public void setIndicatorColorResource(int resId) {
this.indicatorColor = getResources().getColor(resId);
invalidate();
}
public int getIndicatorColor() {
return this.indicatorColor;
}
public void setIndicatorHeight(int indicatorLineHeightPx) {
this.indicatorHeight = indicatorLineHeightPx;
invalidate();
}
public int getIndicatorHeight() {
return indicatorHeight;
}
public void setUnderlineColor(int underlineColor) {
this.underlineColor = underlineColor;
invalidate();
}
public void setUnderlineColorResource(int resId) {
this.underlineColor = getResources().getColor(resId);
invalidate();
}
public int getUnderlineColor() {
return underlineColor;
}
public void setDividerColor(int dividerColor) {
this.dividerColor = dividerColor;
invalidate();
}
public void setDividerColorResource(int resId) {
this.dividerColor = getResources().getColor(resId);
invalidate();
}
public int getDividerColor() {
return dividerColor;
}
public void setUnderlineHeight(int underlineHeightPx) {
this.underlineHeight = underlineHeightPx;
invalidate();
}
public int getUnderlineHeight() {
return underlineHeight;
}
public void setDividerPadding(int dividerPaddingPx) {
this.dividerPadding = dividerPaddingPx;
invalidate();
}
public int getDividerPadding() {
return dividerPadding;
}
public void setScrollOffset(int scrollOffsetPx) {
this.scrollOffset = scrollOffsetPx;
invalidate();
}
public int getScrollOffset() {
return scrollOffset;
}
public void setShouldExpand(boolean shouldExpand) {
this.shouldExpand = shouldExpand;
requestLayout();
}
public boolean getShouldExpand() {
return shouldExpand;
}
public boolean isTextAllCaps() {
return textAllCaps;
}
public void setAllCaps(boolean textAllCaps) {
this.textAllCaps = textAllCaps;
}
public void setTextSize(int textSizePx) {
this.tabTextSize = textSizePx;
updateTabStyles();
}
public int getTextSize() {
return tabTextSize;
}
public void setTextColor(int textColor) {
this.tabTextColor = textColor;
updateTabStyles();
}
public void setTextColorResource(int resId) {
this.tabTextColor = getResources().getColor(resId);
updateTabStyles();
}
public int getTextColor() {
return tabTextColor;
}
public void setTypeface(Typeface typeface, int style) {
this.tabTypeface = typeface;
this.tabTypefaceStyle = style;
updateTabStyles();
}
public void setTabBackground(int resId) {
this.tabBackgroundResId = resId;
}
public int getTabBackground() {
return tabBackgroundResId;
}
public void setTabPaddingLeftRight(int paddingPx) {
this.tabPadding = paddingPx;
updateTabStyles();
}
public int getTabPaddingLeftRight() {
return tabPadding;
}
#Override
public void onRestoreInstanceState(Parcelable state) {
SavedState savedState = (SavedState) state;
super.onRestoreInstanceState(savedState.getSuperState());
currentPosition = savedState.currentPosition;
requestLayout();
}
#Override
public Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState();
SavedState savedState = new SavedState(superState);
savedState.currentPosition = currentPosition;
return savedState;
}
static class SavedState extends BaseSavedState {
int currentPosition;
public SavedState(Parcelable superState) {
super(superState);
}
private SavedState(Parcel in) {
super(in);
currentPosition = in.readInt();
}
#Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeInt(currentPosition);
}
public static final Parcelable.Creator<SavedState> CREATOR = new Parcelable.Creator<SavedState>() {
#Override
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
#Override
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}
}
ViewPagerAdapter.java which we need to supply to ViewPager
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import com.netdoers.zname.R;
import com.netdoers.zname.utils.PagerSlidingTabStrip.IconTabProvider;
/**
* #author Vikalp Patel (vikalppatelce#yahoo.com)
* #category Ui Helper
*
*/
public class ViewPagerAdapter extends FragmentPagerAdapter
/**
* PAGERSLIDINGTABSTIPS
*/
implements IconTabProvider
{
// Declare the number of ViewPager pages
// final int PAGE_COUNT = 5;
final int PAGE_COUNT = 3;
/**
* PAGERSLIDINGTABSTRIPS
*/
private final int[] ICONS = { R.drawable.tab_icon_zname_contact_selector, R.drawable.tab_icon_zname_friends_selector,
R.drawable.tab_icon_zname_call_log_selector };
/**
* SLIDINGTABLAYOUT
*/
/*private int[] imageResId = {
R.drawable.tab_icon_zname_contact_selector,
R.drawable.tab_icon_zname_friends_selector,
R.drawable.tab_icon_zname_call_log_selected
};
#Override
public CharSequence getPageTitle(int position) {
Drawable image = Zname.getApplication().getApplicationContext().getResources().getDrawable(imageResId[position]);
image.setBounds(0, 0, image.getIntrinsicWidth(), image.getIntrinsicHeight());
SpannableString sb = new SpannableString(" ");
ImageSpan imageSpan = new ImageSpan(image, ImageSpan.ALIGN_BOTTOM);
sb.setSpan(imageSpan, 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
return sb;
}*/
/**
* SLIDINGTABLAYOUT
*/
/**
* #param fm
*/
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
/* (non-Javadoc)
* #see android.support.v4.app.FragmentPagerAdapter#getItem(int)
*/
#Override
public Fragment getItem(int item) {
switch (item) {
// Open HomeFragment.java
case 0:
ContactsFragment homeFragment = new ContactsFragment();
return homeFragment;
// Open PlaceOrderFragment.java
case 1:
GroupsFragment groupsFragment = new GroupsFragment();
return groupsFragment;
case 2:
CallLogsFragment callLogsFragment = new CallLogsFragment();
return callLogsFragment;
}
return null;
}
/* (non-Javadoc)
* #see android.support.v4.view.PagerAdapter#getCount()
*/
#Override
public int getCount() {
// TODO Auto-generated method stub
return PAGE_COUNT;
}
/**
* PAGERSLIDINGTABSTRIPS
*/
#Override
public int getPageIconResId(int position) {
// TODO Auto-generated method stub
return ICONS[position];
}
}
My hard way to do that...
// Give the PagerSlidingTabStrip the ViewPager
tabsStrip = (PagerSlidingTabStrip) findViewById(R.id.tabs);
// Attach the view pager to the tab strip
tabsStrip.setViewPager(mViewPager);
Field field = null;
try {
field = PagerSlidingTabStrip.class.getDeclaredField("tabsContainer");
field.setAccessible(true);
LinearLayout tabsContainer = (LinearLayout) field.get(tabsStrip);
tabsContainer.getChildAt(0).setSelected(true);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
tabsStrip.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
private int currentPageSelected = 0;
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
Log.v("onPageSelected", tabsStrip.getClass().toString());
Field field = null;
try {
field = PagerSlidingTabStrip.class.getDeclaredField("tabsContainer");
field.setAccessible(true);
LinearLayout tabsContainer = (LinearLayout) field.get(tabsStrip);
tabsContainer.getChildAt(currentPageSelected).setSelected(false);
currentPageSelected = position;
tabsContainer.getChildAt(position).setSelected(true);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
Just add app:pstsTabSwitch="true" to PagerSlidingTabStrip:
<com.astuetz.PagerSlidingTabStrip
android:id="#+id/tabs"
app:pstsShouldExpand="true"
android:layout_width="150dp"
android:layout_height="match_parent"
android:textSize="28sp"
app:pstsIndicatorColor="#2F041F"
app:pstsIndicatorHeight="2dp"
app:pstsTabPaddingLeftRight="14dp"
app:pstsTabSwitch="true"/>
My adapter:
SampleFragmentPagerAdapter extends FragmentPagerAdapter implements PagerSlidingTabStrip.IconTabProvider {
private int TAB_ICONS[] = {R.drawable.io_logo, R.drawable.ic_chat_tab_unactive};
private final int[] SWITCH_ICONS = { R.drawable.tab_one, R.drawable.tab_two};
public SampleFragmentPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public int getCount() {
return TAB_ICONS.length;
}
#Override
public Fragment getItem(int position) {
if(position == 0){
return new SwipeFragment();
} else {
return new ConversationsFragment();
}
}
#Override
public int getPageIconResId(int position) {
return SWITCH_ICONS[position];
}
}
My selector
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true" android:drawable="#drawable/io_title" />
<item android:state_pressed="true" android:drawable="#drawable/io_logo"/>
<item android:state_selected="true" android:drawable="#drawable/io_logo"/>
<item android:drawable="#drawable/io_title" />
</selector>

how to prevent getChildAt(position).getWidth() returns null?

i was using this method in earlier versions of v4-support library, it was working fine, but when i changed it to latest, this method returns null whenever position and positionoffset is 0, tabsContainer is linearLayout :
positionOffset * tabsContainer.getChildAt(position).getWidth())
from method:
scrollToChild(position, (int) (positionOffset *
tabsContainer.getChildAt(position).getWidth()));
i need a little help for avoid it returning null, without using if position=0, because it prevents the tabs to be created at all when resource is null, a little help?
public class PagerSlidingTabStrip extends HorizontalScrollView {
public interface IconTabProvider {
public int getPageIconResId(int position);
}
// #formatter:off
private static final int[] ATTRS = new int[] {
android.R.attr.textSize,
android.R.attr.textColor
};
// #formatter:on
private LinearLayout.LayoutParams defaultTabLayoutParams;
private LinearLayout.LayoutParams expandedTabLayoutParams;
private final PageListener pageListener = new PageListener();
public OnPageChangeListener delegatePageListener;
private LinearLayout tabsContainer;
private ViewPager pager;
private int tabCount;
private int currentPosition = 0;
private float currentPositionOffset = 0f;
private Paint rectPaint;
private Paint dividerPaint;
private int indicatorColor = 0xFF666666;
private int underlineColor = 0x1A000000;
private int dividerColor = 0x1A000000;
private boolean shouldExpand = false;
private boolean textAllCaps = true;
private int scrollOffset = 52;
private int indicatorHeight = 8;
private int underlineHeight = 2;
private int dividerPadding = 12;
private int tabPadding = 24;
private int dividerWidth = 1;
private int tabTextSize = 12;
private int tabTextColor = 0xFF666666;
private Typeface tabTypeface = null;
private int tabTypefaceStyle = Typeface.BOLD;
private int lastScrollX = 0;
private int tabBackgroundResId = R.drawable.background_tab;
private Locale locale;
public PagerSlidingTabStrip(Context context) {
this(context, null);
}
public PagerSlidingTabStrip(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public PagerSlidingTabStrip(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setFillViewport(true);
setWillNotDraw(false);
tabsContainer = new LinearLayout(context);
tabsContainer.setOrientation(LinearLayout.HORIZONTAL);
tabsContainer.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT));
addView(tabsContainer);
DisplayMetrics dm = getResources().getDisplayMetrics();
scrollOffset = (int)
TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, scrollOffset, dm);
indicatorHeight = (int)
TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, indicatorHeight, dm);
underlineHeight = (int)
TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, underlineHeight, dm);
dividerPadding = (int)
TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dividerPadding, dm);
tabPadding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
tabPadding, dm);
dividerWidth = (int)
TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dividerWidth, dm);
tabTextSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
tabTextSize, dm);
// get system attrs (android:textSize and android:textColor)
TypedArray a = context.obtainStyledAttributes(attrs, ATTRS);
tabTextSize = a.getDimensionPixelSize(0, tabTextSize);
tabTextColor = a.getColor(1, tabTextColor);
a.recycle();
// get custom attrs
a = context.obtainStyledAttributes(attrs,
R.styleable.PagerSlidingTabStrip);
indicatorColor =
a.getColor(R.styleable.PagerSlidingTabStrip_pstsIndicatorColor, indicatorColor);
underlineColor =
a.getColor(R.styleable.PagerSlidingTabStrip_pstsUnderlineColor, underlineColor);
dividerColor =
a.getColor(R.styleable.PagerSlidingTabStrip_pstsDividerColor, dividerColor);
indicatorHeight =
a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsIndicatorHeight,
indicatorHeight);
underlineHeight =
a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsUnderlineHeight,
underlineHeight);
dividerPadding =
a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsDividerPadding,
dividerPadding);
tabPadding =
a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsTabPaddingLeftRight,
tabPadding);
tabBackgroundResId =
a.getResourceId(R.styleable.PagerSlidingTabStrip_pstsTabBackground,
tabBackgroundResId);
shouldExpand =
a.getBoolean(R.styleable.PagerSlidingTabStrip_pstsShouldExpand, shouldExpand);
scrollOffset =
a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsScrollOffset,
scrollOffset);
textAllCaps =
a.getBoolean(R.styleable.PagerSlidingTabStrip_pstsTextAllCaps, textAllCaps);
a.recycle();
rectPaint = new Paint();
rectPaint.setAntiAlias(true);
rectPaint.setStyle(Style.FILL);
dividerPaint = new Paint();
dividerPaint.setAntiAlias(true);
dividerPaint.setStrokeWidth(dividerWidth);
defaultTabLayoutParams = new
LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
expandedTabLayoutParams = new LinearLayout.LayoutParams(0,
LayoutParams.MATCH_PARENT, 1.0f);
if (locale == null) {
locale = getResources().getConfiguration().locale;
}
}
public void setViewPager(ViewPager pager) {
this.pager = pager;
if (pager.getAdapter() == null) {
throw new IllegalStateException("ViewPager does not have adapter
instance.");
}
pager.setOnPageChangeListener(pageListener);
notifyDataSetChanged();
}
public void setOnPageChangeListener(OnPageChangeListener listener) {
this.delegatePageListener = listener;
}
public void notifyDataSetChanged() {
tabsContainer.removeAllViews();
tabCount = pager.getAdapter().getCount();
for (int i = 0; i < tabCount; i++) {
if (pager.getAdapter() instanceof IconTabProvider) {
addIconTab(i, ((IconTabProvider)
pager.getAdapter()).getPageIconResId(i));
} else {
addTextTab(i,
pager.getAdapter().getPageTitle(i).toString());
}
}
updateTabStyles();
getViewTreeObserver().addOnGlobalLayoutListener(new
OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
if (Build.VERSION.SDK_INT <
Build.VERSION_CODES.JELLY_BEAN) {
getViewTreeObserver().removeOnGlobalLayoutListener(this);
} else {
getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
currentPosition = pager.getCurrentItem();
scrollToChild(currentPosition, 0);
}
});
}
private void addTextTab(final int position, String title) {
TextView tab = new TextView(getContext());
tab.setText(title);
tab.setGravity(Gravity.CENTER);
tab.setSingleLine();
addTab(position, tab);
}
private void addIconTab(final int position, int resId) {
ImageButton tab = new ImageButton(getContext());
tab.setImageResource(resId);
addTab(position, tab);
}
private void addTab(final int position, View tab) {
tab.setFocusable(true);
tab.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
pager.setCurrentItem(position);
}
});
tab.setPadding(tabPadding, 0, tabPadding, 0);
tabsContainer.addView(tab, position, shouldExpand ?
expandedTabLayoutParams : defaultTabLayoutParams);
}
private void updateTabStyles() {
for (int i = 0; i < tabCount; i++) {
View v = tabsContainer.getChildAt(i);
v.setBackgroundResource(tabBackgroundResId);
if (v instanceof TextView) {
TextView tab = (TextView) v;
tab.setTextSize(TypedValue.COMPLEX_UNIT_PX, tabTextSize);
tab.setTypeface(tabTypeface, tabTypefaceStyle);
tab.setTextColor(tabTextColor);
// setAllCaps() is only available from API 14, so the
upper case is made manually if we are on a
// pre-ICS-build
if (textAllCaps) {
if (Build.VERSION.SDK_INT >=
Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
tab.setAllCaps(true);
} else {
tab.setText(tab.getText().toString().toUpperCase(locale));
}
}
}
}
}
private void scrollToChild(int position, int offset) {
if (tabCount == 0) {
return;
}
int newScrollX = tabsContainer.getChildAt(position).getLeft() + offset;
if (position > 0 || offset > 0) {
newScrollX -= scrollOffset;
}
if (newScrollX != lastScrollX) {
lastScrollX = newScrollX;
scrollTo(newScrollX, 0);
}
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (isInEditMode() || tabCount == 0) {
return;
}
final int height = getHeight();
// draw indicator line
rectPaint.setColor(indicatorColor);
// default: line below current tab
View currentTab = tabsContainer.getChildAt(currentPosition);
float lineLeft = currentTab.getLeft();
float lineRight = currentTab.getRight();
// if there is an offset, start interpolating left and right coordinates
between current and next tab
if (currentPositionOffset > 0f && currentPosition < tabCount - 1) {
View nextTab = tabsContainer.getChildAt(currentPosition + 1);
final float nextTabLeft = nextTab.getLeft();
final float nextTabRight = nextTab.getRight();
lineLeft = (currentPositionOffset * nextTabLeft + (1f -
currentPositionOffset) * lineLeft);
lineRight = (currentPositionOffset * nextTabRight + (1f -
currentPositionOffset) * lineRight);
}
canvas.drawRect(lineLeft, height - indicatorHeight, lineRight, height,
rectPaint);
// draw underline
rectPaint.setColor(underlineColor);
canvas.drawRect(0, height - underlineHeight, tabsContainer.getWidth(),
height, rectPaint);
// draw divider
dividerPaint.setColor(dividerColor);
for (int i = 0; i < tabCount - 1; i++) {
View tab = tabsContainer.getChildAt(i);
canvas.drawLine(tab.getRight(), dividerPadding, tab.getRight(),
height - dividerPadding, dividerPaint);
}
}
private class PageListener implements OnPageChangeListener {
#Override
public void onPageScrolled(int position, float positionOffset, int
positionOffsetPixels) {
currentPosition = position;
currentPositionOffset = positionOffset;
System.out.println(position);
System.out.println(positionOffset);
System.out.println(positionOffset *
tabsContainer.getChildAt(position).getWidth());
scrollToChild(position, (int) (positionOffset *
tabsContainer.getChildAt(position).getWidth()));
invalidate();
if (delegatePageListener != null) {
delegatePageListener.onPageScrolled(position,
positionOffset, positionOffsetPixels);
}
}
#Override
public void onPageScrollStateChanged(int state) {
if (state == ViewPager.SCROLL_STATE_IDLE) {
scrollToChild(pager.getCurrentItem(), 0);
}
if (delegatePageListener != null) {
delegatePageListener.onPageScrollStateChanged(state);
}
}
#Override
public void onPageSelected(int position) {
if (delegatePageListener != null) {
delegatePageListener.onPageSelected(position);
}
}
}
public void setIndicatorColor(int indicatorColor) {
this.indicatorColor = indicatorColor;
invalidate();
}
public void setIndicatorColorResource(int resId) {
this.indicatorColor = getResources().getColor(resId);
invalidate();
}
public int getIndicatorColor() {
return this.indicatorColor;
}
public void setIndicatorHeight(int indicatorLineHeightPx) {
this.indicatorHeight = indicatorLineHeightPx;
invalidate();
}
public int getIndicatorHeight() {
return indicatorHeight;
}
public void setUnderlineColor(int underlineColor) {
this.underlineColor = underlineColor;
invalidate();
}
public void setUnderlineColorResource(int resId) {
this.underlineColor = getResources().getColor(resId);
invalidate();
}
public int getUnderlineColor() {
return underlineColor;
}
public void setDividerColor(int dividerColor) {
this.dividerColor = dividerColor;
invalidate();
}
public void setDividerColorResource(int resId) {
this.dividerColor = getResources().getColor(resId);
invalidate();
}
public int getDividerColor() {
return dividerColor;
}
public void setUnderlineHeight(int underlineHeightPx) {
this.underlineHeight = underlineHeightPx;
invalidate();
}
public int getUnderlineHeight() {
return underlineHeight;
}
public void setDividerPadding(int dividerPaddingPx) {
this.dividerPadding = dividerPaddingPx;
invalidate();
}
public int getDividerPadding() {
return dividerPadding;
}
public void setScrollOffset(int scrollOffsetPx) {
this.scrollOffset = scrollOffsetPx;
invalidate();
}
public int getScrollOffset() {
return scrollOffset;
}
public void setShouldExpand(boolean shouldExpand) {
this.shouldExpand = shouldExpand;
requestLayout();
}
public boolean getShouldExpand() {
return shouldExpand;
}
public boolean isTextAllCaps() {
return textAllCaps;
}
public void setAllCaps(boolean textAllCaps) {
this.textAllCaps = textAllCaps;
}
public void setTextSize(int textSizePx) {
this.tabTextSize = textSizePx;
updateTabStyles();
}
public int getTextSize() {
return tabTextSize;
}
public void setTextColor(int textColor) {
this.tabTextColor = textColor;
updateTabStyles();
}
public void setTextColorResource(int resId) {
this.tabTextColor = getResources().getColor(resId);
updateTabStyles();
}
public int getTextColor() {
return tabTextColor;
}
public void setTypeface(Typeface typeface, int style) {
this.tabTypeface = typeface;
this.tabTypefaceStyle = style;
updateTabStyles();
}
public void setTabBackground(int resId) {
this.tabBackgroundResId = resId;
}
public int getTabBackground() {
return tabBackgroundResId;
}
public void setTabPaddingLeftRight(int paddingPx) {
this.tabPadding = paddingPx;
updateTabStyles();
}
public int getTabPaddingLeftRight() {
return tabPadding;
}
#Override
public void onRestoreInstanceState(Parcelable state) {
SavedState savedState = (SavedState) state;
super.onRestoreInstanceState(savedState.getSuperState());
currentPosition = savedState.currentPosition;
requestLayout();
}
#Override
public Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState();
SavedState savedState = new SavedState(superState);
savedState.currentPosition = currentPosition;
return savedState;
}
static class SavedState extends BaseSavedState {
int currentPosition;
public SavedState(Parcelable superState) {
super(superState);
}
private SavedState(Parcel in) {
super(in);
currentPosition = in.readInt();
}
#Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeInt(currentPosition);
}
public static final Parcelable.Creator<SavedState> CREATOR = new
Parcelable.Creator<SavedState>() {
#Override
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
#Override
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}
}
the caller:
public class QuickContactFragment extends DialogFragment {
private PagerSlidingTabStrip tabs;
private ViewPager pager;
private ContactPagerAdapter adapter;
public static QuickContactFragment newInstance() {
QuickContactFragment f = new QuickContactFragment();
return f;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle
savedInstanceState) {
if (getDialog() != null) {
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
getDialog().getWindow().setBackgroundDrawableResource(android.R.color.transparent);
}
View root = inflater.inflate(R.layout.fragment_quick_contact, container,
false);
tabs = (PagerSlidingTabStrip) root.findViewById(R.id.tabs);
pager = (ViewPager) root.findViewById(R.id.pager);
adapter = new ContactPagerAdapter();
pager.setAdapter(adapter);
tabs.setViewPager(pager);
return root;
}
#SuppressLint("NewApi") #SuppressWarnings("deprecation")
#Override
public void onStart() {
super.onStart();
// change dialog width
if (getDialog() != null) {
int fullWidth = getDialog().getWindow().getAttributes().width;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
Display display =
getActivity().getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
fullWidth = size.x;
} else {
Display display =
getActivity().getWindowManager().getDefaultDisplay();
fullWidth = display.getWidth();
}
final int padding = (int)
TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 24, getResources()
.getDisplayMetrics());
int w = fullWidth - padding;
int h = getDialog().getWindow().getAttributes().height;
getDialog().getWindow().setLayout(w, h);
}
}
public class ContactPagerAdapter extends PagerAdapter implements IconTabProvider {
private final int[] ICONS = { R.drawable.ic_launcher_gplus,
R.drawable.ic_launcher_gmail,
R.drawable.ic_launcher_gmaps,
R.drawable.ic_launcher_chrome };
public ContactPagerAdapter() {
super();
}
#Override
public int getCount() {
return ICONS.length;
}
#Override
public int getPageIconResId(int position) {
return ICONS[position];
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
// looks a little bit messy here
TextView v = new TextView(getActivity());
v.setBackgroundResource(R.color.background_window);
v.setText("PAGE " + (position + 1));
final int padding = (int)
TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 16, getResources()
.getDisplayMetrics());
v.setPadding(padding, padding, padding, padding);
v.setGravity(Gravity.CENTER);
container.addView(v, 0);
return v;
}
#Override
public void destroyItem(ViewGroup container, int position, Object view) {
container.removeView((View) view);
}
#Override
public boolean isViewFromObject(View v, Object o) {
return v == ((View) o);
}
}
}
well, I used this condition and now is ok:
if(position!=0 && positionOffset!=0.0){
scrollToChild(position, (int) (positionOffset *
tabsContainer.getChildAt(position).getWidth()));
}

Categories

Resources