20

我正在使用 viewpager 跨多个页面显示一些文本。我正在尝试获取当前视图并选择一个新页面。我想获取当前视图的原因是因为基于页码我正在更改一些视图组件的一些属性,如 textview、image 等。我使用下面的代码相同

ViewPager mPager = (ViewPager) findViewById(R.id.pager);
mPagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager());
mPager.setAdapter(mPagerAdapter);
View CurrView;
OnPageChangeListener pageChangelistener = new OnPageChangeListener() {
  @Override
       public void onPageSelected(int pageSelected) {
          currView = mPager.getChildAt(mPager.getCurrentItem());
      myTextView = (TextView)currView.findViewById(R.id.myTextView);
              loadBookmarkSetting(pageSelected);//do some changes in myTextView    properties based on the page number  }
 mPager.setOnPageChangeListener(pageChangelistener);

现在我面临的问题是,在我滚动 3 页之后,当我来到第 4 页时,我在“myTextView = (TextView)currView.findViewById(R.id.myTextView);”这一行上得到了空指针异常。这是因为 currView 为空。如果我在这里做错了任何想法。有没有其他方法可以在 viewpager 中捕获当前视图(页面),以便我可以根据我所在的页码对视图进行更改?

4

5 回答 5

66

您可以将 setTag 与您在 instantiateItem 方法 (PagerAdapter) 中返回的视图一起使用。

因此,当您在 PagerAdapter 中实例化您的视图时,方法也是instantiateItem(ViewGroup container, int position)),您应该使用 setTag 到您的视图。

像这样:

view.setTag("myview" + position);
return view;

当您需要当前视图时:

View view = (View) pager.findViewWithTag("myview" + pager.getCurrentItem());
于 2013-11-25T07:24:35.610 回答
4

您使用这种方法:

@Nullable
    public static View getActiveView(@Nonnull final ViewPager viewPager) {
        final PagerAdapter adapter = viewPager.getAdapter();
        if (null == adapter || adapter.getCount() == 0 || viewPager.getChildCount() == 0) {
            return null;
        }

        int position;
        final int currentPosition = viewPager.getCurrentItem();

        for (int i = 0; i < viewPager.getChildCount(); i++) {
            final View child = viewPager.getChildAt(i);
            final LayoutParams layoutParams = (LayoutParams) child.getLayoutParams();
            if (layoutParams.isDecor) {
                continue;
            }
            final Field positionField;
            try {
                positionField = LayoutParams.class.getDeclaredField("position");
                positionField.setAccessible(true);
                position = positionField.getInt(layoutParams);
            } catch (NoSuchFieldException e) {
                break;
            } catch (IllegalAccessException e) {
                break;
            }
            if (position == currentPosition) {
                return child;
            }
        }
        return null;
    }
于 2015-09-21T16:26:33.537 回答
1

由于您已将 offscreenPageLimit 设置为 3,因此出现空指针异常。viewpager 将仅存储 3 页。mPager.getChildAt(4) 将获得空值。要设置textview,您可以使用适配器的片段管理器来获取所有片段并获取片段在位置处的视图。

adapter.fragmentManager.fragments[position1].view
于 2019-08-22T09:23:49.483 回答
0

我向我的适配器添加了一个 SparseArray 并将视图添加到其中instantiateItem()并将其删除destroyItem()

val views = SparseArray<View>()

...

override fun instantiateItem(container: ViewGroup, position: Int): Any 
{
    //...

    container.addView(view)
    views.put(position, view)
    return view
}

override fun destroyItem(container: ViewGroup, position: Int, obj: Any) 
{
    views.remove(position)
    container.removeView(obj as View)
}

fun showFooter(currentItem: Int) {
    views[currentItem].footer_layout.animate().alpha(1f)
}

fun hideFooter(currentItem: Int) {
    views[currentItem].footer_layout.animate().alpha(0f)
}

然后我可以调用适配器上的方法:

viewPager.addOnPageChangeListener(object: ViewPager.OnPageChangeListener {
    override fun onPageScrollStateChanged(state: Int) {
        when (state) {
            SCROLL_STATE_IDLE -> adapter.showFooter(viewPager.currentItem)
            SCROLL_STATE_DRAGGING -> adapter.hideFooter(viewPager.currentItem)
        }
    }

    override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {}

    override fun onPageSelected(position: Int) {}

})
于 2018-02-16T06:17:10.817 回答
-1

您当前视图为空的原因是因为寻呼机适配器开始销毁其项目以提高内存效率。我发现一种可行的方法是覆盖寻呼机适配器的destroyItem() 方法,并通过列表或parceable 类保存您的数据。

于 2017-04-04T08:50:20.333 回答