Android ViewPager get the current View

AndroidAndroid FragmentsTabsAndroid Viewpager

Android Problem Overview


I have a ViewPager, and I'd like to get the current selected and visible view, not a position.

  1. getChildAt(getCurrentItem) returns wrong View

  2. This works not all the time. Sometimes returns null, sometimes just returns wrong View.

     @Override
     public void setUserVisibleHint(boolean isVisibleToUser) {
         super.setUserVisibleHint(isVisibleToUser);
    
         if (isVisibleToUser == true) { 
             mFocusedListView = ListView; 
         }
     }
    
  3. PageListener on ViewPager with getChildAt() also not working, not giving me the correct View every time.

How can i get current visible View?

View view = MyActivity.mViewPager.getChildAt(MyActivity.mViewPager.getCurrentItem()).getRootView();
ListView listview = (ListView) view.findViewById(R.id.ListViewItems);

Android Solutions


Solution 1 - Android

I've figured it out. What I did was to call setTag() with a name to all Views/ListViews, and just call findViewWithTag(mytag), mytag being the tag.

Unfortunately, there's no other way to solve this.

Solution 2 - Android

I just came across the same issue and resolved it by using:

View view = MyActivity.mViewPager.getFocusedChild();

Solution 3 - Android

I use this method with android.support.v4.view.ViewPager

View getCurrentView(ViewPager viewPager) {
        try {
            final int currentItem = viewPager.getCurrentItem();
            for (int i = 0; i < viewPager.getChildCount(); i++) {
                final View child = viewPager.getChildAt(i);
                final ViewPager.LayoutParams layoutParams = (ViewPager.LayoutParams) child.getLayoutParams();

                Field f = layoutParams.getClass().getDeclaredField("position"); //NoSuchFieldException
                f.setAccessible(true);
                int position = (Integer) f.get(layoutParams); //IllegalAccessException

                if (!layoutParams.isDecor && currentItem == position) {
                    return child;
                }
            }
        } catch (NoSuchFieldException e) {
            Log.e(TAG, e.toString());
        } catch (IllegalArgumentException e) {
            Log.e(TAG, e.toString());
        } catch (IllegalAccessException e) {
            Log.e(TAG, e.toString());
        }
        return null;
    }

Solution 4 - Android

You can get the current element by accessing your list of itens from your adapter calling myAdapter.yourListItens.get(myViewPager.getCurrentItem()); As you can see, ViewPager can retrieve the current index of element of you adapter (current page).

If you is using FragmentPagerAdapter you can do this cast:

FragmentPagerAdapter adapter = (FragmentPagerAdapter)myViewPager.getAdapter();

and call

adapter.getItem(myViewPager.getCurrentItem());

This works very well for me ;)

Solution 5 - Android

During my endeavors to find a way to decorate android views I think I defined alternative solution for th OP's problem that I have documented in my blog. I am linking to it as the code seems to be a little bit too much for including everything here.

The solution I propose:

  • keeps the adapter and the view entirely separated
  • one can easily query for a view with any index form the view pager and he will be returned either null if this view is currently not loaded or the corresponding view.

Solution 6 - Android

Use an Adapter extending PagerAdapter, and override setPrimaryItem method inside your PagerAdapter.

https://developer.android.com/reference/android/support/v4/view/PagerAdapter.html

class yourPagerAdapter extends PagerAdapter
{
    // .......

    @Override
    public void setPrimaryItem (ViewGroup container, int position, Object object)
    {
        int currentItemOnScreenPosition = position;
        View onScreenView = getChildAt(position);
    }

    // .......

}

Solution 7 - Android

If you do not have many pages and you can safely apply setOffscreenPageLimit(N-1) where N is the total number of pages without wasting too much memory then you could do the following:

public Object instantiateItem(final ViewGroup container, final int position) {		
	CustomHomeView RL = new CustomHomeView(context);
	if (position==0){
		container.setId(R.id.home_container);} ...rest of code

then here is code to access your page

((ViewGroup)pager.findViewById(R.id.home_container)).getChildAt(pager.getCurrentItem()).setBackgroundColor(Color.BLUE);

If you want you can set up a method for accessing a page

RelativeLayout getPageAt(int index){
	RelativeLayout rl =  ((RelativeLayout)((ViewGroup)pager.findViewById(R.id.home_container)).getChildAt(index));
	return rl;
}

Solution 8 - Android

Try this

 final int position = mViewPager.getCurrentItem();
    Fragment fragment = getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.rewards_viewpager + ":"
            + position);

Solution 9 - Android

I had to do it more general, so I decided to use the private 'position' of ViewPager.LayoutParams

        final int childCount = viewPager.getChildCount();
        for (int i = 0; i < childCount; i++) {
            final View child = viewPager.getChildAt(i);
            final ViewPager.LayoutParams lp = (ViewPager.LayoutParams) child.getLayoutParams();
            int position = 0;
            try {
                Field f = lp.getClass().getDeclaredField("position");
                f.setAccessible(true);
                position = f.getInt(lp); //IllegalAccessException
            } catch (NoSuchFieldException | IllegalAccessException ex) {ex.printStackTrace();}
            if (position == viewPager.getCurrentItem()) {
                viewToDraw = child;
            }
        }

Solution 10 - Android

I'm using ViewPagerUtils from FabulousFilter:

ViewPagerUtils.getCurrentView(ViewPager viewPager)

Solution 11 - Android

viewpager.getChildAt(0)

this always returns my currently selected view. this worked for me.

Solution 12 - Android

is that your first activity on the screen or have you layered some above each other already?

try this:

findViewById(android.R.id.content).getRootView()

or just:

findViewById(android.R.id.content) 

also depending on what you want try:

((ViewGroup)findViewById(android.R.id.content)).getChildAt(0)

Solution 13 - Android

You can find fragment by system tag. It's work for me. I used it in OnMeasure function.

id - viewPager ID

position - fragment which you want to get

Important! You get this fragment if your fragment was created in adapter. So you must to check supportedFragmentManager.findFragmentByTag("android:switcher:" + id + ":" + position) nullify

You can get view like this:

supportedFragmentManager.findFragmentByTag("android:switcher:" + id + ":" + position).view

You shouldn't give custom tag in adapter

Solution 14 - Android

You can get it by viewpager listener to get slected item position

viewPager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener{
        override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
            
        }

        override fun onPageSelected(position: Int) {
            
        }

        override fun onPageScrollStateChanged(state: Int) {
            
        }

    })

Solution 15 - Android

Use this method.

View getCurrentView(ViewPager viewPager) {
        try {
            final int currentItem = viewPager.getCurrentItem();
            for (int i = 0; i < viewPager.getChildCount(); i++) {
                final View child = viewPager.getChildAt(i);
                final ViewPager.LayoutParams layoutParams = (ViewPager.LayoutParams) child.getLayoutParams();

                Field f = layoutParams.getClass().getDeclaredField("position"); //NoSuchFieldException
                f.setAccessible(true);
                int position = (Integer) f.get(layoutParams); //IllegalAccessException

                if (!layoutParams.isDecor && currentItem == position) {
                    return child;
                }
            }
        } catch (NoSuchFieldException e) {
            Log.e(TAG, e.toString());
        } catch (IllegalArgumentException e) {
            Log.e(TAG, e.toString());
        } catch (IllegalAccessException e) {
            Log.e(TAG, e.toString());
        }
        return null;
    }

it will may return null in androidx if anybody knows the solution comment here

Solution 16 - Android

Please check this

((ViewGroup))mViewPager.getChildAt(MyActivity.mViewPager.getCurrentItem()));

else verify this link.

Solution 17 - Android

If you examine carefully, there are at most 3 views saved by ViewPager. You can easily get the current view by

view     = MyActivity.mViewPager.getChildAt(1);

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionlacasView Question on Stackoverflow
Solution 1 - AndroidlacasView Answer on Stackoverflow
Solution 2 - AndroidZeCodeaView Answer on Stackoverflow
Solution 3 - AndroidDmitry YablokovView Answer on Stackoverflow
Solution 4 - AndroidGilianView Answer on Stackoverflow
Solution 5 - AndroidBoris StrandjevView Answer on Stackoverflow
Solution 6 - AndroidAnCodeView Answer on Stackoverflow
Solution 7 - AndroidMichael KernView Answer on Stackoverflow
Solution 8 - AndroidSon Nguyen ThanhView Answer on Stackoverflow
Solution 9 - AndroidKamen DobrevView Answer on Stackoverflow
Solution 10 - AndroidAleksandar AcićView Answer on Stackoverflow
Solution 11 - AndroidM.UsmanView Answer on Stackoverflow
Solution 12 - AndroidSunnySonicView Answer on Stackoverflow
Solution 13 - AndroidАксенов ВладимирView Answer on Stackoverflow
Solution 14 - AndroidTarif ChakderView Answer on Stackoverflow
Solution 15 - AndroidTariq HussainView Answer on Stackoverflow
Solution 16 - AndroidSathish KumarView Answer on Stackoverflow
Solution 17 - AndroidAkshay VatsView Answer on Stackoverflow