Why do the TabLayout's tabs' icons/texts blink when swiping between pages?
Asked Answered
W

1

9

Background

I've used the PagerSlidingTabStrip library for a long time, to show tabs above a ViewPager.

Recently, I was tasked to set icons (using selectors, with selected-vs-unselected states) instead of texts for the tabs, and so I did. However, it seems that the library couldn't handle it well, showing empty tabs sometimes, so I've moved to TabLayout, which is a part of the design library by Google

The problem

I've noticed a few solutions of how to add icons to the TabLayout, but each of them has one or more of those issues :

  1. no icons are shown
  2. icons are shown, but can blink from time to time, especially when using a selector for them with "exitFadeDuration" being set, or when swiping fast
  3. clicking on tabs does not change the current page of the viewPager.

The code

The code I've used is from cheesesquare sample, in the MainActivity.java file. It's quite basic:

      final TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
      ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
      ...
      tabLayout.setupWithViewPager(viewPager);

The solutions I've tried are:

  1. setting an icon for each tab (and remove "getPageTitle" code of the adapter) :

    for (int i = 0; i < tabLayout.getTabCount(); i++) 
        tabLayout.getTabAt(i).setIcon(...);
    

    Also tried adding setOnTabSelectedListener for when I didn't use a selector.

    This solution results in blinking effect (issue #2).

  2. Extending TabLayout to support icons or implementing TabViewProvider, as shown here.

    Extending TabLayout doesn't show icons at all (issue #1), and implementing TabViewProvider has the issue of blinking icons (quite rare though).

  3. For getPageTitle, return a SpannableString that has the icon in it, as shown here . This didn't show the icons at all for me.

I remember I tried other solutions too, but they also had issues as I've mentioned.

The question

What is the correct way to set icons for the tabs?

Is there an official way to achieve this? I'd like to at least have a selected&unselected images for each tab. The transition of when selecting is a good bonus, which I've hoped to achieve as it looks nicer this way.

Why do the icons blink anyway? I've noticed that it occurs even for texts...

Is there maybe a workaround?

Whilom answered 5/8, 2015 at 9:32 Comment(7)
In my case I used a custom view for the icons and the text but I also have the blinking problem. Two things that I noticed: 1. When I do a "long" swipe the blinking does not appear, when I do a "short" swipe the blink appears. 2. When I directly press the tab there is no blink at all.Clare
@Clare So even a custom view doesn't help? I actually thought of trying it out, but didn't have the time for this. Is it possible it's a bug in the support library? If so, maybe I should write about it here: code.google.com/p/android/issues/listWhilom
Yes, it seems to be a bug, please let me know if you write an issue. In my case a custom view does not help at all. I'm using two TextViews (one for a font-awesome icon, the other for the text) with a ColorStateList. I aso spotted another possible bug in which the first selected tab appears as not selected until there is a page change.Clare
@Clare Well the other issue can be fixed easily (and I think I did it too) by selecting it... Anyway, I will see if this post gets any answer, and will post about it when I see that nothing happens in the near future.Whilom
ok, reported here: code.google.com/p/android/issues/detail?id=182387 . Hope it will get fixed soon, or that there will be a workaround.Whilom
@Clare I thought I've found a workaround (use an earlier version of the design library), but it doesn't help: icons can still disappear sometimes. :(Whilom
@Clare ok, not it's completely "fixed" using my workaround. Hope next version of the design library will fix it without me needing this kind of solution.Whilom
W
8

It seems to be a known issue, and that it happens for texts too:

https://code.google.com/p/android/issues/detail?id=180454

It will get fixed on the next version of the library.

A workaround is to use previous versions, for now:

com.android.support:design:22.2.0

EDIT: this is not a good workaround, as icons can disappear on some cases (I think a combination of orientation change and swiping).

EDIT: I think that it doesn't disappear, but more like changing its color to something else that doesn't exist in the selector I've given it (which has only 2 states: selected and default).

EDIT: ok, found a workaround for the icons.

  1. use the old version (22.2.0) as I've mentioned above.

  2. you need to avoid using selectors for the icons. Use the exact image resource ids instead:

    private static final int[] TAB_ICONS_UNSELECTED = {...    };
    private static final int[] TAB_ICONS_SELECTED = {...    };
    
  3. update the icons based on the page selections, as such:

    mViewPager.addOnPageChangeListener(new OnPageChangeListener() {
        @Override
        public void onPageSelected(final int position) {
            for (int i = 0; i < tabLayout.getTabCount(); ++i)
                tabLayout.getTabAt(i).setIcon(i != position ? TAB_ICONS_UNSELECTED[i] : TAB_ICONS_SELECTED[i]);
        }
    });
    

Also, remember to call about the same loop when initializing the TabLayout. Something like that:

    for (int i = 0; i < tabLayout.getTabCount(); ++i)
        tabLayout.getTabAt(i).setIcon(i != mViewPager.getCurrentItem() ? TAB_ICONS_UNSELECTED[i] : TAB_ICONS_SELECTED[i]);

I think that this should also fix the issue for texts and not just icons.


EDIT: it seems that v23 will get it fixed, and that it will be available very soon.

Whilom answered 11/8, 2015 at 9:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.