Android ViewPager get the current View
AndroidAndroid FragmentsTabsAndroid ViewpagerAndroid Problem Overview
I have a ViewPager, and I'd like to get the current selected and visible view, not a position.
-
getChildAt(getCurrentItem)
returns wrongView
-
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; } }
-
PageListener on
ViewPager
withgetChildAt()
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 View
s/ListView
s, 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);