astuetz / PagerSlidingTabStrip

An interactive indicator to navigate between the different pages of a ViewPager
139 stars 44 forks source link

Can the text color be set differently for active and inactive tabs? #141

Open alexblack opened 9 years ago

alexblack commented 9 years ago

I'd like the currently selected tab to use white text, and the rest of the tabs to use grey.

I'm trying this but no luck, all the tabs text turns out white (which was unexpected)

    <com.astuetz.PagerSlidingTabStrip
        android:id="@+id/tabs"
        android:background="@color/deep_orange_500"
        app:pstsUnderlineColor="#fff"
        app:pstsIndicatorColor="#fff"
        android:textColor="@color/tab_text"
        android:layout_width="match_parent"
        android:layout_height="48dip" />
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:state_checked="true" android:color="#fff" android:drawable="@drawable/my_dummy_drawable"/>
    <item android:color="#aaa" android:drawable="@drawable/my_dummy_drawable"/>
</selector>
goonerDroid commented 9 years ago

Yes you can do it.Implement onPage Listener in your activity

private LinearLayout mTabsLinearLayout;

   @Override
public void onPageScrolled(int i, float v, int i2) {
    //overriden method not used
}

@Override
public void onPageSelected(int position) {
    for(int i=0; i < mTabsLinearLayout.getChildCount(); i++){
        TextView tv = (TextView) mTabsLinearLayout.getChildAt(i);
        if(i == position){
               tv.setTextColor(Color.WHITE);
        } else {
            tv.setTextColor(Color.GREY);
        }
    }
}

@Override
public void onPageScrollStateChanged(int i) {
         //overriden method not used
}

use this when your are setting up tabstrip when the activity is created..

      public void setUpTabStrip(){   

              //your other customizations related to tab strip...blahblah
              // Set first tab selected
    mTabsLinearLayout = ((LinearLayout)tabStrip.getChildAt(0));
    for(int i=0; i < mTabsLinearLayout.getChildCount(); i++){
        TextView tv = (TextView) mTabsLinearLayout.getChildAt(i);

        if(i == 0){
            tv.setTextColor(Color.WHITE);
        } else {
            tv.setTextColor(Color.GREY);
        }
    }

}

alexblack commented 9 years ago

Great, thanks for posting that.

Is there anyway to do that via XML? On Oct 31, 2014 1:27 AM, "goonerDroid" notifications@github.com wrote:

Yes you can do it.Implement onPage Listener in your activity

private LinearLayout mTabsLinearLayout;

@Override public void onPageScrolled(int i, float v, int i2) { //overriden method not used }

@Override public void onPageSelected(int position) { for(int i=0; i < mTabsLinearLayout.getChildCount(); i++){ TextView tv = (TextView) mTabsLinearLayout.getChildAt(i); if(i == position){ tv.setTextColor(Color.WHITE); } else { tv.setTextColor(Color.GREY); } } }

@Override public void onPageScrollStateChanged(int i) { //overriden method not used }

use this when your are setting up tabstrip when the activity is created..

  public void setUpTabStrip(){

          //your other customizations related to tab strip...blahblah
          // Set first tab selected
mTabsLinearLayout = ((LinearLayout)tabStrip.getChildAt(0));
for(int i=0; i < mTabsLinearLayout.getChildCount(); i++){
    TextView tv = (TextView) mTabsLinearLayout.getChildAt(i);

    if(i == 0){
        tv.setTextColor(Color.WHITE);
    } else {
        tv.setTextColor(Color.GREY);
    }
}

}

— Reply to this email directly or view it on GitHub https://github.com/astuetz/PagerSlidingTabStrip/issues/141#issuecomment-61231341 .

goonerDroid commented 9 years ago

NO...as far as i know the textview widget of the sliding tab strip cannot be modified using the XML.You would have to dynamically change the value on page selected by the user.Also close this issue if it solved your problem

xiaojidonggong commented 9 years ago

Thank you ! very useful to me !

pkpio commented 9 years ago

:+1: @goonerDroid for the sample code :)

frakc commented 9 years ago

I advise to change block inside library (listener inside notifydatasetchanged() 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);
            }
            //modify previous tab to display inactive text
            TextView tab = (TextView)tabsContainer.getChildAt(currentPosition);
            tab.setTextColor(Color.parseColor("#50FFFFFF"));
            //modify previous tab to display active text
            currentPosition = pager.getCurrentItem();
             tab = (TextView) tabsContainer.getChildAt(currentPosition);
            tab.setTextColor(Color.parseColor("#FFFFFF"));
            scrollToChild(currentPosition, 0);
        }
    });
pkpio commented 9 years ago

@frakc This is better solution! Thanks :smile: :+1:

frakc commented 9 years ago

Update

The previous method was unreliable.
Next solution will allow to set Colors from your main module, change them at run time and consumes less resourses, so sliding is smoother

In activity or fragment:

    tabs.setTextColor(getResources().getColor(R.color.white_80));
    tabs.setActiveColor(getResources().getColor(R.color.white), getResources().getColor(R.color.white_80));
    tabs.setViewPager(pager);

In Library add those field and setters:

private int activeTabTextColor;
    private int inActiveTabTextColor;
    private boolean useActiveColor =false;
    public void setActiveColor(int active, int inactive){
        useActiveColor=true;
        activeTabTextColor=active;
        inActiveTabTextColor=inactive;
    }
    public void disableActiveColor(){
        useActiveColor=false;
        }
        public void enableActiveClor(){
            useActiveColor = true;
        }

Update setViewPager:

    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();
        pageListener.curPage=currentPosition;
        pageListener.prevPage=currentPosition;
        if(useActiveColor){
            TextView tab  = (TextView)tabsContainer.getChildAt(currentPosition);
            tab.setTextColor(activeTabTextColor);
        }

    }

Update Page Listener:

private class PageListener implements 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) {
            prevPage=curPage;
            curPage=position;
            if(useActiveColor) {
                TextView tab = (TextView) tabsContainer.getChildAt(prevPage);
                tab.setTextColor(inActiveTabTextColor);
                //modify previous tab to display active text
                tab = (TextView) tabsContainer.getChildAt(curPage);
                tab.setTextColor(activeTabTextColor);
            }
            if (delegatePageListener != null) {
                delegatePageListener.onPageSelected(position);
            }
        }

    }
goonerDroid commented 9 years ago

@frakc any particular reason for using your solution.The code i'm using is working reliablily and so far there was no issues.Sorry if i being naive.

frakc commented 9 years ago

@goonerDroid when i tried you sample my animation of tab changes was a bit of spiky, my way request a bit less redrowing, but it not very sutable as i see it now

rockwotj commented 9 years ago

This worked for me, all in XML.

 <com.astuetz.PagerSlidingTabStrip
     android:id="@+id/tabs"
     android:layout_width="match_parent"
     android:layout_height="?attr/actionBarSize"
     android:background="?attr/colorPrimary"
     app:pstsTextColorSelected="@color/white"
     style="@style/PagerSlidingTabStripStyle"
     />

 <style name="PagerSlidingTabStripStyle" parent="">
     <item name="android:textColorPrimary">@color/gray</item>
 </style>
aldefy commented 9 years ago

Thanks @frakc it helped me , can u tell me if i reduce the height of the divider , my indicator color is say yellow and divider is white , while i swipe through i can see the White cut through the yellow , what can i do to change it , im thinking onDraw or use the divider padding attr - pstsDividerPadding, please advise

baeggot commented 9 years ago

Thanks @rockwotj !!! I solved this problem finally~!!! :D

FerrisPan commented 9 years ago

@goonerDroid thank you!

simran-lbbd commented 9 years ago

I used @frakc 's solution but there is a bug. My default selected tab is always of the inactive colour. How do i make it the active colour?

Tooto commented 9 years ago

@rockwotj where did u find tag app:pstsTextColorSelected ? There is no this tag in library.

rockwotj commented 9 years ago

@Tooto I just realized that I am using a fork of this project! Oops! facepalm

munnadroid commented 9 years ago

This worked for me

<com.astuetz.PagerSlidingTabStrip
            android:id="@+id/tabs"
            android:layout_width="match_parent"
            android:textColorPrimary="@color/white" //active tab color
            android:textColor="#cacaca" //inactive tab color
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary" />
pawan-nagarro commented 8 years ago

@munnadroid thanks ur solution worked

ghost commented 8 years ago

make following changes in library, worked for me!!

private void unSelect(View tab) {
        if (tab != null) {
            TextView tab_title = (TextView) tab.findViewById(R.id.psts_tab_title);
            tab_title.setTextColor(Color.GRAY);
            if (tab_title != null) {
                tab_title.setSelected(false);
            }
            if (isCustomTabs) ((CustomTabProvider) mPager.getAdapter()).tabUnselected(tab);
        }
    }

    private void select(View tab) {
        if (tab != null) {
            TextView tab_title = (TextView) tab.findViewById(R.id.psts_tab_title);
            tab_title.setTextColor(Color.WHITE);
            if (tab_title != null) {
                tab_title.setSelected(true);
            }
            if (isCustomTabs) ((CustomTabProvider) mPager.getAdapter()).tabSelected(tab);
        }
    }
MohamedHatemAbdu commented 8 years ago

Is there a solution using only selector (From XML) ?

Parkjonghyun93 commented 7 years ago

Thanks.. !!! very nice solution !