Custom selected tab text color in SlidingTabLayout

前端 未结 6 1991
执笔经年
执笔经年 2020-12-13 14:14

I\'m using the SlidingTabLayout from google (https://developer.android.com/samples/SlidingTabsBasic/src/com.example.android.common/view/SlidingTabLayout.html).

It wo

相关标签:
6条回答
  • 2020-12-13 14:48

    The problem is, sliding layout do not set item's state as selected. Here is my approach to solve the problem.

    1) Create COLOR selector (ColorStateList) for your view. You can imagine it this way:

    /res/color/tab_text_color.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
      <item android:color="@color/white" android:state_selected="true"/>
      <item android:color="@color/black"/>
    </selector>
    

    2) Place created selector to your item's view textColor (or other required) attribute:

    <TextView
      ...
      android:textColor="@color/tab_text_color"
      ... />
    

    3) Do this changes in file SlidingTabLayout.java:

    View oldSelection = null; // new field indicating old selected item
    
    // method to remove `selected` state from old one
    private void removeOldSelection() { 
        if(oldSelection != null) {
            oldSelection.setSelected(false);
        }
    }
    
    // improve method scrollToTab() as follows
    private void scrollToTab(int tabIndex, int positionOffset) {
        final int tabStripChildCount = mTabStrip.getChildCount();
        if (tabStripChildCount == 0 || tabIndex < 0 || tabIndex >= tabStripChildCount) {
            return;
        }
    
        View selectedChild = mTabStrip.getChildAt(tabIndex);
        if (selectedChild != null) {
    
            if(positionOffset == 0 && selectedChild != oldSelection) { // added part
                selectedChild.setSelected(true);
                removeOldSelection();
                oldSelection = selectedChild;
            }
    
            int targetScrollX = selectedChild.getLeft() + positionOffset;
    
            if (tabIndex > 0 || positionOffset > 0) {
                // If we're not at the first child and are mid-scroll, make sure we obey the offset
                targetScrollX -= mTitleOffset;
            }
    
            scrollTo(targetScrollX, 0);
        }
    }
    
    private void populateTabStrip() {
        removeOldSelection(); // add those two lines
        oldSelection = null;
        ...
    }
    
    0 讨论(0)
  • 2020-12-13 14:57

    1) First of all create color folder under res (/res/color)
    2) create xml file selector.xml under /res/color folder

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_selected="true" android:color="@android:color/white" />
    <item android:state_focused="true" android:color="@android:color/white" />
    <item android:state_pressed="true" android:color="@android:color/white" />
    <item android:color="#504f4f" /> 
    </selector> 
    

    3) Then in the populateTabStrip() method in SlidingTabLayout put this

    tabTitleView.setTextColor(getResources().getColorStateList(R.color.selector));
    

    now you have a selector and you can change the color of the text on any event you want

    if that is not working add the following lines of code.
    a) in populateTabStrip() method at the end add this

    if (i == mViewPager.getCurrentItem()) {
        tabView.setSelected(true);
    }
    

    and b) change the onPageSelected() method to this

        @Override
        public void onPageSelected(int position) {
            if (mScrollState == ViewPager.SCROLL_STATE_IDLE) {
                mTabStrip.onViewPagerPageChanged(position, 0f);
                scrollToTab(position, 0);
            }
            for (int i = 0; i < mTabStrip.getChildCount(); i++) {
                mTabStrip.getChildAt(i).setSelected(position == i);
            }
            if (mViewPagerPageChangeListener != null) {
                mViewPagerPageChangeListener.onPageSelected(position);
            }
        }    
    
    0 讨论(0)
  • 2020-12-13 14:59

    I created a function

    private void setTabTextSelected(TextView textView, boolean selected){
            if (selected){
                textView.setTextColor(getResources().getColor(R.color.Black));
                textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);
            }
            else{
                textView.setTextColor(getResources().getColor(R.color.ColorPrimaryDark));
                textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 13);
    
            }
    
        }
    

    and called it in two functions in SlidingTabLayout:

    1. at the end of populateTabStrip:
    setTabTextSelected(tabTitleView, i == mViewPager.getCurrentItem());
    
    1. at onPageSelected:
    for (int i = 0; i < mTabStrip.getChildCount(); i++) {
                  TextView textView = (TextView) mTabStrip.getChildAt(i);
                  setTabTextSelected(textView, position == i);
                }
    
    0 讨论(0)
  • 2020-12-13 15:00

    I had a similar problem but I was using a custom page title View with an icon and a text. To set custom colors when a tab is selected/unselected, I used the selector created by @PanayiotisIrakleous, so a big thanks to him for posting it.

    Here's how I did it:-

    1- Create a xml file for the selector. I made a file, slidingtab_title_color.xml and placed it in Drawable folder.

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:state_selected="true" android:color="@android:color/white" />
        <item android:state_focused="true" android:color="@android:color/white" />
        <item android:state_pressed="true" android:color="@android:color/white" />
        <item android:color="#504f4f" />
    </selector> 
    

    2- Open your custom layout for tab title and add the selector file in the android:textColor attribute. My custom file is named as slidingtab_title_color.xml and has the following code-

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:padding="10dp"
        android:background="@drawable/ripple_effect">
    
        <ImageView
            android:id="@+id/imageView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
    <!--Adding the selector file in textColor attribute-->
        <TextView
            android:id="@+id/textView2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="New Text"
            android:textColor="@drawable/slidingtab_title_color"/>    
    </LinearLayout>
    

    3- (Optional) If you want to change the color of the indicator and the background of sliding tab then add the following line to the file where you are initializing your SlidingTabLayout-

    mSlidingTab.setBackgroundColor(getResources().getColor(R.color.primaryColor));
    mSlidingTab.setSelectedIndicatorColors(getResources().getColor(R.color.accentColor));
    

    Just make sure that you are adding these lines before you are setting the ViewPager for the SlidingTabLayout.

    And that's it, here's how it will look.SlidingTab with tab selector

    For those who still have problems, here's the bitbucket link for the project source and this link for the all the projects on Material design.

    0 讨论(0)
  • 2020-12-13 15:02

    Try this piece of code in your onCreate() method.

    tabTitleView.setTabTextColors(
        getResources().getColor(R.color.active), 
        getResources().getColor(R.color.inactive));
    
    0 讨论(0)
  • 2020-12-13 15:05

    In case anyone is interested in another solution without using a Selector XML resource file, here is one somehow based on @Panayiotis' answer.

    Add the below methods to the SlidingTabStrip.java class:

    public void setTabTitlesTextColor(int selectedPosition) {
        for (int i = 0; i < getChildCount(); i++) {
            if (TextView.class.isInstance(getChildAt(i))) {
                ((TextView) getChildAt(i)).setTextColor((selectedPosition == i) ? getTabColorizer().getIndicatorColor(i) : Color.argb(90, 0,0,0)  );
            }
        }
    }
    
    public SlidingTabLayout.TabColorizer getTabColorizer() {
        if (mCustomTabColorizer != null)
            return mCustomTabColorizer;
        else
            return mDefaultTabColorizer;
    }
    

    Call the newly created setTabTitlesTextColor() method in onPageSelected and setViewPager on the SlidingTabLayout.java class as below:

    public void setViewPager(ViewPager viewPager) {
        mTabStrip.removeAllViews();
    
        mViewPager = viewPager;
        if (viewPager != null) {
            viewPager.setOnPageChangeListener(new InternalViewPagerListener());
            populateTabStrip();
            mTabStrip.setTabTitlesTextColor(viewPager.getCurrentItem());
        }
    }
    
    @Override
        public void onPageSelected(int position) {
            if (mScrollState == ViewPager.SCROLL_STATE_IDLE) {
                mTabStrip.onViewPagerPageChanged(position, 0f);
                scrollToTab(position, 0);
            }
    
            mTabStrip.setTabTitlesTextColor(position);
    
            if (mViewPagerPageChangeListener != null) {
                mViewPagerPageChangeListener.onPageSelected(position);
            }
        }
    
    0 讨论(0)
提交回复
热议问题