75

我有一个 ViewPager,我想获取当前选定的可见视图,而不是位置。

  1. getChildAt(getCurrentItem)返回错误View
  2. 这并非一直有效。有时返回 null,有时只是返回错误的 View。

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
    
        if (isVisibleToUser == true) { 
            mFocusedListView = ListView; 
        }
    }
    
  3. PageListener也无法正常工作ViewPagergetChildAt()每次都没有给我正确的视图。

如何获取当前可见视图?

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

17 回答 17

135

我已经想通了。我所做的是给setTag()所有Views/ ListViews 命名,然后调用findViewWithTag(mytag)mytag作为标签。

不幸的是,没有其他方法可以解决这个问题。

于 2012-10-12T12:03:20.723 回答
10

我刚刚遇到了同样的问题并通过使用解决了它:

View view = MyActivity.mViewPager.getFocusedChild();
于 2013-01-30T19:03:26.443 回答
8

您可以通过从您的适配器调用访问您的项目列表来获取当前元素myAdapter.yourListItens.get(myViewPager.getCurrentItem()); 如您所见,ViewPager 可以检索您的适配器(当前页面)的元素的当前索引。

如果您使用的是 FragmentPagerAdapter,您可以执行以下操作:

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

并打电话

adapter.getItem(myViewPager.getCurrentItem());

这对我来说非常有效;)

于 2013-07-17T15:39:10.547 回答
8

我用这个方法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;
    }
于 2019-05-27T12:14:14.483 回答
2

在我努力寻找装饰 android 视图的方法期间,我认为我为我在博客中记录的 OP 问题定义了替代解决方案。我正在链接到它,因为代码似乎有点太多,无法在这里包含所有内容。

我提出的解决方案:

  • 保持适配器和视图完全分离
  • 可以轻松地从视图寻呼机查询具有任何索引的视图,null如果当前未加载此视图或相应的视图,他将被返回。
于 2014-12-02T14:16:53.800 回答
2

使用扩展 PagerAdapter 的适配器,并在 PagerAdapter 中覆盖 setPrimaryItem 方法。

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

    // .......

}
于 2018-02-15T12:35:16.713 回答
1

如果您没有很多页面,并且您可以安全地应用setOffscreenPageLimit(N-1) 其中 N 是页面总数而不会浪费太多内存,那么您可以执行以下操作:

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

那么这里是访问您的页面的代码

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

如果需要,您可以设置访问页面的方法

RelativeLayout getPageAt(int index){
    RelativeLayout rl =  ((RelativeLayout)((ViewGroup)pager.findViewById(R.id.home_container)).getChildAt(index));
    return rl;
}
于 2014-02-02T16:47:16.603 回答
1

尝试这个

 final int position = mViewPager.getCurrentItem();
    Fragment fragment = getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.rewards_viewpager + ":"
            + position);
于 2016-11-09T07:14:43.927 回答
1
viewpager.getChildAt(0)

这总是返回我当前选择的视图。这对我有用。

于 2020-02-16T07:26:32.160 回答
1

我必须做得更笼统,所以我决定使用 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;
            }
        }
于 2017-05-22T19:18:09.943 回答
1

我正在使用来自FabulousFilter的ViewPagerUtils

ViewPagerUtils.getCurrentView(ViewPager viewPager)
于 2018-07-18T10:02:48.740 回答
0

这是您在屏幕上的第一个活动,还是您已经将一些活动分层?

尝试这个:

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

要不就:

findViewById(android.R.id.content) 

也取决于你想尝试什么:

((ViewGroup)findViewById(android.R.id.content)).getChildAt(0)
于 2012-10-12T08:11:26.180 回答
0

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

于 2022-01-10T06:27:05.163 回答
0

您可以通过系统标签找到片段。这对我有用。我在OnMeasure函数中使用它。

id- viewPager ID

position- 你想得到的片段

重要的!如果您的片段是在适配器中创建的,您将获得此片段。所以你必须检查supportedFragmentManager.findFragmentByTag("android:switcher:" + id + ":" + position)无效

你可以得到这样的视图:

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

您不应该在适配器中提供自定义标签

于 2018-07-29T21:45:36.050 回答
0

您可以通过 viewpager 侦听器获取它以获取选定的项目位置

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

        override fun onPageSelected(position: Int) {
            
        }

        override fun onPageScrollStateChanged(state: Int) {
            
        }

    })
于 2021-10-11T09:38:39.577 回答
-3

如果仔细检查,ViewPager 最多保存 3 个视图。您可以通过以下方式轻松获取当前视图

view     = MyActivity.mViewPager.getChildAt(1);
于 2012-12-12T22:09:20.487 回答
-3

请检查这个

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

否则验证此链接

于 2012-10-12T08:28:38.053 回答