Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get focused View from ViewPager

i use the ViewPager for switching views with left/right swipe.

The ViewPager needs an Adapter, so I've built this one:

public class ListViewPagerAdapter extends PagerAdapter {

protected static final String TAG = "ListViewPagerAdapter";
protected static final int NUM_VIEWS = 3;

protected final Activity mActivity;

public ListViewPagerAdapter(Activity activity) {
    mActivity = activity;
}

@Override
public int getCount() {
    return NUM_VIEWS;
}

@Override
public void startUpdate(View container) {}

@Override
public Object instantiateItem(View container, int position) {
    // ViewPager
    ViewPager viewPager = (ViewPager) container;

    // Wird verwendet, um die Views aufzurufen
    LayoutInflater layoutInflater = mActivity.getLayoutInflater();

    // Standardmäßig ist news eingeblendet
    View view = layoutInflater.inflate(R.layout.news_fragment, null);
    // Falls sich die Position verändert, so verändert sich auch die View
    if (position == 0) {
        view = layoutInflater.inflate(R.layout.favorite_fragment, null);
    } else if (position == 2) {
        view = layoutInflater.inflate(R.layout.videos_fragment, null);
    }

    // View einblenden
    viewPager.addView(view, 0);

    return view;
}

@Override
public void destroyItem(View container, int position, Object object) {
    // ViewPager
    ViewPager viewPager = (ViewPager) container;
    // View
    View view = (View) object;

    // View löschen
    viewPager.removeView(view);
}

@Override
public void finishUpdate(View container) {}

@Override
public boolean isViewFromObject(View view, Object object) {
    View _view = (View) object;
    return view == _view;
}

@Override
public Parcelable saveState() {
    return null;
}

@Override
public void restoreState(Parcelable state, ClassLoader loader) {}
 }

Now, i want to get the current focused view by the viewpager. I tried getChildAt(x), but it does not work.

Are there some example, or do you have any idea how to get the current view?

Thanks

like image 357
Superroot Avatar asked Jul 24 '11 14:07

Superroot


6 Answers

It is possible to save the currently active object (View, Fragment, ...) by overriding PagerAdapter.setPrimaryItem method. For example:

private View mCurrentView;

@Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
    mCurrentView = (View)object;
}
like image 144
Michael G. Avatar answered Nov 03 '22 01:11

Michael G.


You have to register a listener to your ViewPager :

pager.setOnPageChangeListener(new MyPageChangeListener()); 

You have to customize the listener by extending a stub listener:

private int focusedPage = 0;
private class MyPageChangeListener extends ViewPager.SimpleOnPageChangeListener {
    @Override
    public void onPageSelected(int position) {
        focusedPage = position;
    }
}

I found this by looking at the ViewPager.java source code in the compatibility library. I read that we can do more, for example catch onPageScrollStateChanged.

To build the adapter, I used the code on this blog post. You might want to have a look.

like image 28
Steren Avatar answered Nov 02 '22 23:11

Steren


You can add a tag to the created view in the instantiateItem method:

view.setTag(position);

Later you can access the current selected view by:

mPager.findViewWithTag(mPager.getCurrentItem());
like image 44
artkoenig Avatar answered Nov 03 '22 00:11

artkoenig


I recently needed to implement this exact solution. Here's the way I did it:

Map<Integer, Object> views = Maps.newHashMap();

@Override
public Object instantiateItem(View container, int position) {
  /* Create and add your View here */
  Object result = ???

  views.put(position, result);
  return result;
}

@Override
public void destroyItem(View container, int position, Object object) {
  /** Remove your View here */

  views.remove(position);
}

protected View findViewForPosition(int position) {
  Object object = views.get(position);
  if (object != null) {
    for (int i = 0; i < getChildCount(); i++) {
      View view = getChildAt(i);
      if (isViewFromObject(view, object)) {
        return view;
      }
    }
  }
  return null;
}
like image 4
Mark Renouf Avatar answered Nov 02 '22 23:11

Mark Renouf


Try this:

public View getCurrentView(ViewPager pager) {
    for (int i = 0; i < pager.getChildCount(); i++) {
        View child = pager.getChildAt(i);
        if (child.getX() <= pager.getScrollX() + pager.getWidth() && 
            child.getX() + child.getWidth() >= pager.getScrollX() + pager.getWidth()) {
            return child;
         }
     }
     return getChildAt(0);
}
like image 2
Arpit Avatar answered Nov 02 '22 23:11

Arpit


To get focused view I use this way:

When I inflate my view before add it on ViewPager I set tag to it. Then I check this tag.

private View getCurrentView()
{
    for (int i = 0; i < pager.getChildCount(); i++)
    {
        View v = pager.getChildAt(i);
        if (v != null)
        {
            if (v.getTag().equals(pageList.get(pager.getCurrentItem()).getTag())) return v;
            // pageList is a list of pages that I pass to page adapter
        }
    }
    return null;
}
like image 1
Nik Avatar answered Nov 03 '22 00:11

Nik