3

Strangely there is not a single method available to get exact position of selected tab in viewPager adapter,

In instantiateItem you need to decide what layout to use for a given tab in viewPager , but position of instantiateItem is not actually the exact position , so how can i decide which tab is selected and decide what xml to inflate ?

There are number of SO question answered for the same issue , and they doesn't make sense at all Q1 .

In this given Question , it doesn't make sense to get the selected tab position when layout is already inflated in my case.

My Attempts:

  • Get position by calling getItemPosition() in instantiateItem doesn't work , give -1 always.

  • Get position of tab using actually position parameter in instantiateItem , doesn't work give strange random values.

Any solutions/workarounds ?

Edit

Link for code of activity i'm using right now HorizontalCoordinatorNtbActivity.java , specifically check line 55

Community
  • 1
  • 1
Zulqurnain Jutt
  • 1,083
  • 3
  • 15
  • 41

3 Answers3

1

if you are using Tablayout with viewPager this method should help you. tabLayout.getSelectedTabPosition()

and in case if you need text of the Tab

String tabText=tabLayout.getTabAt(tabLayout.getSelectedTabPosition()).getText().toString();
Nilesh Deokar
  • 2,975
  • 30
  • 53
  • Where to use it? and tabBar i'm using as i mentioned in comments of question , doesn't have method `getSelectedTabPosition() ` – Zulqurnain Jutt Aug 23 '16 at 13:54
  • whenever you want to switch between fragments of the view Pager you can use `viewPager.setCurrentItem(1);' and to get the swipe event you can always add `setOnPageChangeListener` to `viewpager` – Nilesh Deokar Aug 23 '16 at 13:58
  • that is not the point , i have 4 different layout and i want to inflate them to each of different tabs !! , now i cannot achieve it unless i have exact position of selected tab in `instantiateItem` , setOnPageChangeListener only sets position after inflation – Zulqurnain Jutt Aug 23 '16 at 14:02
  • i didnt go through library code in details. but for `TabLayout` i dont think there is any need of knowing current position of the selected tab in `viewPager adapter`. There may be cases when you need to know the position in `activity` having `TabLayout` for which `getSelectedTabPosition()` works – Nilesh Deokar Aug 23 '16 at 14:02
  • are you using custom `adaptor` ? if yes please post the code. since `FragmentStatePagerAdapter` is common – Nilesh Deokar Aug 23 '16 at 14:04
  • i've just added activity code link i'm trying to edit – Zulqurnain Jutt Aug 23 '16 at 14:09
0

Strangely there is not a single method available to get exact position of selected tab in viewPager adapter

Adapter knows nothing about state of adapter view, even more - it shouldn't know anything about existence of such view. The only purpose of adapter is to prepare data that will be displayed by something.

If your adapter must know about current ViewPager's position - it surely means that your design has flaws.

Sergio
  • 8,099
  • 2
  • 26
  • 52
  • then how can you decide , which tab is selected and what `layout` to inflate ? – Zulqurnain Jutt Aug 23 '16 at 13:50
  • @Mr.Z You should statically assign indices to layouts you are interested in. Or you should implement some method in your adapter that will modify inflating logic. That method may be called from `OnPageChangeListener`. – Sergio Aug 23 '16 at 13:59
  • then what is the point to introduce method like `instantiateItem` ? what is it used for exactly – Zulqurnain Jutt Aug 23 '16 at 14:03
  • @Mr.Z This method is called by `ViewPager` internally when it needs view for some position. Only `ViewPager` decides what position it needs, you have nothing to do with that. Your responsibility is only to provide view to position you was asked for. – Sergio Aug 23 '16 at 14:09
0

position of instantiateItem is not actually the exact position

I assume what you mean is that position is not the currently selected/displayed position.

It shouldn't matter what view is displaying. When user swipes from page 1 to page 2, ViewPager loads the view for page 3 in anticipation of the next user swipe.

This is a Good Thing™. It means that the user is going to get a smoother swipe action because the view has already been inflated.

So when the ViewPager asks your adapter for the view for page 3, then give it the view for page 3.

Now, there may be some special things you need to do when the view does become selected/displayed. In that case, you can check the answers to this question (my answer is one of them):

android - How to determine when Fragment becomes visible in ViewPager - Stack Overflow

Any solutions/workarounds ?

The solution is:

  • When the ViewPager asks your adapter for a view for a certain tab, inflate that view.

  • When the view becomes the currently selected/displayed view, update the view as necessary.


EDIT:

The pager adapter code isn't mysterious or anything:

        @Override
        public Object instantiateItem(final ViewGroup container, final int position) {

            View view;
            switch (position) {
            case 0: // teacher
                // inflate/set up your teacher view
                break;
            case 1: // student
                // inflate/set up your student view
                break;
            case 2: // search
                // inflate/set up your search view
                break;
            case 3: // chat
                // inflate/set up your chat view
                break;
            default:
                throw new IllegalArgumentException("I don't know how to set up tab " + position);
            }

            container.addView(view);
            return view;
        }
    });

This really shows what @Serhio was trying to say: You don't need to know which view the ViewPager currently has displayed; when it asks your adapter for a view, you just give it the view it wants.

And BTW, when you inflate a view inside the pager adapter, make sure you use container as the parent:

        view = LayoutInflater.from(
                    getBaseContext()).inflate(R.layout.item_vp_list, container, false);
Community
  • 1
  • 1
kris larson
  • 30,387
  • 5
  • 62
  • 74
  • first workaround seems legit and good , can you post some helping code for that ? – Zulqurnain Jutt Aug 23 '16 at 17:08
  • Question: are you using fragments with a `FragmentPagerAdapter`? Or just views with a `PagerAdapter`? Because you didn't mention fragments at all. Also: what do the different tabs in your view represent? e.g. "ratings tab", "month view tab", "details tab" etc. etc. Actually, putting that information in the question post would be helpful to the community. – kris larson Aug 23 '16 at 17:14
  • basically , tabs are teacher(RecycleView),student(RecycleView),search(fragment),chat(Listfragment) , due to complex structure i didn't posted whole code , but starter code is exactly what is given in question below `Edit` section , and **NO** i am not using FragmentPagerAdapter , rather its supper class `PagerAdapter` – Zulqurnain Jutt Aug 23 '16 at 17:27