Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android ViewPager get the current View

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);
like image 773
lacas Avatar asked Oct 12 '12 08:10

lacas


People also ask

How do I update my Android ViewPager adapter?

The ViewPager and pager adapter just deal with data in memory. So when data in memory is updated, we just need to call the adapter's notifyDataSetChanged() . Since the fragment is already created, the adapter's onItemPosition() will be called before notifyDataSetChanged() returns.


11 Answers

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.

like image 194
lacas Avatar answered Sep 25 '22 16:09

lacas


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

View view = MyActivity.mViewPager.getFocusedChild();
like image 26
ZeCodea Avatar answered Sep 25 '22 16:09

ZeCodea


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;
    }
like image 22
Dmitry Yablokov Avatar answered Sep 25 '22 16:09

Dmitry Yablokov


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 ;)

like image 27
Gilian Avatar answered Sep 24 '22 16:09

Gilian


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.
like image 43
Boris Strandjev Avatar answered Sep 27 '22 16:09

Boris Strandjev


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);
    }

    // .......

}
like image 21
AnCode Avatar answered Sep 24 '22 16:09

AnCode


viewpager.getChildAt(0)

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

like image 23
M.Usman Avatar answered Sep 23 '22 16:09

M.Usman


Try this

 final int position = mViewPager.getCurrentItem();
    Fragment fragment = getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.rewards_viewpager + ":"
            + position);
like image 29
Son Nguyen Thanh Avatar answered Sep 24 '22 16:09

Son Nguyen Thanh


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;
            }
        }
like image 43
Kamen Dobrev Avatar answered Sep 25 '22 16:09

Kamen Dobrev


I'm using ViewPagerUtils from FabulousFilter:

ViewPagerUtils.getCurrentView(ViewPager viewPager)
like image 36
Aleksandar Acić Avatar answered Sep 27 '22 16:09

Aleksandar Acić


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;
}
like image 38
Michael Kern Avatar answered Sep 23 '22 16:09

Michael Kern