IndexOutOfBoundsException in TabLayout in android support design lib
Asked Answered
P

2

8

I use android.support.design in all my projects, and today I updated it to latest version

com.android.support:design:22.2.1

It was a bad idea, because my project crashed with

java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0
java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
java.util.ArrayList.get(ArrayList.java:308)
android.support.design.widget.TabLayout.getTabAt(TabLayout.java:407)
android.support.design.widget.TabLayout.setupWithViewPager(TabLayout.java:585)

After some debugging, I found a problem in this method:

 public void setupWithViewPager(@NonNull ViewPager viewPager) {
    PagerAdapter adapter = viewPager.getAdapter();
    if(adapter == null) {
        throw new IllegalArgumentException("ViewPager does not have a PagerAdapter set");
    } else {
        this.setTabsFromPagerAdapter(adapter);
        viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(this));
        this.setOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(viewPager));
        if(this.mSelectedTab == null || this.mSelectedTab.getPosition() != viewPager.getCurrentItem()) {
            this.getTabAt(viewPager.getCurrentItem()).select();// ERROR On my code I'm used empty adapter 
        }

    }
}

But in previous version 22.2.0 of lib, all was working fine:

    public void setupWithViewPager(ViewPager viewPager) {
    PagerAdapter adapter = viewPager.getAdapter();
    if(adapter == null) {
        throw new IllegalArgumentException("ViewPager does not have a PagerAdapter set");
    } else {
        this.setTabsFromPagerAdapter(adapter);
        viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(this));
        this.setOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(viewPager));
    }
}

Who did it and who can be punished for it?

Please help me find developers for Android support Design library.

Perforce answered 6/8, 2015 at 17:36 Comment(2)
from what I see, I feel viewPager.getCurrentItem() is not zero-indexed and the method, getTabAt() expects it to be. Check the APIs, try this.getTabAt(viewPager.getCurrentItem() - 1).select();Austroasiatic
@SudhansuChoudhary: getCurrentItem() on ViewPager is zero-based.Compliancy
S
2

I'd love to just comment with this, but I don't have the reputation.

It looks like this issue is being tracked and pegged for a fix in a future release: https://code.google.com/p/android/issues/detail?id=180453

Stapler answered 6/8, 2015 at 18:3 Comment(0)
C
3

My guess is that your problem is due to:

// ERROR On my code I'm used empty adapter

Apparently, TabLayout does not like empty adapters. This does not surprise me.

So, do not call setupWithViewPager() right away. When you do eventually update your PagerAdapter to return a non-zero value from getCount(), you can call setupWithViewPager(). Second and subsequent times you change the PagerAdapter, after calling notifyDataSetChanged() on the adapter, call setTabsFromPagerAdapter() to refresh the tabs to align with the PagerAdapter contents. You can use a boolean to track whether you need to call setupWithViewPager() or setTabsFromPagerAdapter().

You are certainly welcome to file a feature request for TabLayout to support empty adapters.

Compliancy answered 6/8, 2015 at 17:59 Comment(1)
This answer is great, it makes sense and it does fix the problem. I am very surprised the the other one which should actually be deleted was accepted.Heydon
S
2

I'd love to just comment with this, but I don't have the reputation.

It looks like this issue is being tracked and pegged for a fix in a future release: https://code.google.com/p/android/issues/detail?id=180453

Stapler answered 6/8, 2015 at 18:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.