【问题标题】:ViewPager getItemPosition() never called. Who should call it?ViewPager getItemPosition() 从未调用过。谁应该调用它?
【发布时间】:2016-01-04 21:06:00
【问题描述】:

我对@9​​87654321@ 有点疑惑。基本上我的问题是我需要根据屏幕方向更改ViewPager 的内容(片段)。我阅读了许多关于此的帖子,有人说我应该从PagerAdapter 覆盖getItemPosition(Object)。我已经这样做了,但是从未调用过该方法,并且在PagerAdapterFragmentPagerAdapterFragmentStatePagerAdapter 中找不到任何调用它的方法。有谁知道这是如何工作的并介意解释一下吗?

目前我在instantiateItem() 中做了一个丑陋的黑客攻击来测试我的理论,但这并不是我真正想要使用的。如您所见,如果getItemPosition() 返回POSITION_NONE,我将删除该片段。在getItemPosition() 中,我有一些逻辑可以确定片段是否仍应在寻呼机中。

        @Override
        public Object instantiateItem(ViewGroup container, int position) {

            // Hack since getItemPosition is never called.
            final long itemId = getItemId(position);
            String name = makeFragmentName(container.getId(), itemId);
            Fragment fragment = mFragmentManager.findFragmentByTag(name);
            if(fragment != null && getItemPosition(fragment) == POSITION_NONE) {
                mFragmentManager.beginTransaction().remove(fragment).commit();
                mFragmentManager.executePendingTransactions();
            }

            fragment = (Fragment) super.instantiateItem(container, position);
            registeredFragments.put(position, fragment);
            return fragment;
        }

JavaDoc 说:

public int getItemPosition(Object object) 当宿主视图试图确定一个项目的位置时调用 已经改变。如果给定的位置返回 POSITION_UNCHANGED 项目未更改或 POSITION_NONE 如果项目不再存在 在适配器中。

默认实现假定项目永远不会 更改位置并始终返回 POSITION_UNCHANGED。 @param object 表示项目的对象,之前通过调用返回 实例化项目(视图,int)。 @return 对象的新位置索引来自 [0, getCount()), POSITION_UNCHANGED 如果对象的位置没有改变, POSITION_NONE 如果项目不再存在。

我在 API 级别 19 和 22 上测试了我的代码,问题是一样的。

提前致谢。

编辑:我扩展FragmentStatePagerAdapterFragmentPagerAdapter。如果我扩展 PagerAdapter 并编写自己的实例化和销毁方法,我也许可以解决这个问题。希望我不会有太多。再加上看不懂很烦。 ;)

【问题讨论】:

  • 我认为您不必这样做。当在屏幕方向上重新创建 Activity 时,通常会重新创建 PagerAdapter。相反,您只需更改适配器实例化的片段。
  • (更新)我认为FragmentManager 在旋转时重新创建片段,并且适配器不会再次重新创建它们。至少当我跟踪代码时,它们不会在旋转时重新创建。我确实扩展了FragmentPagerAdapter 而不是PagerAdapter,可能是后者阻止了片段的自动重新创建。

标签: android android-fragments


【解决方案1】:

getItemPosition() 仅在 notifyDataSetChanged() 调用之后调用。

首先,修改您的数据集,然后拨打notifyDataSetChanged() 电话。 您还必须覆盖 getItemId() 以返回静态标识符。默认情况下它返回给定的位置。

【讨论】:

  • 在调用 notifyDataSetChange 之后,它会重新实例化我不想要的其他视图。删除视图后我想做什么,以便其他视图保持原样?\
【解决方案2】:

getItemPosition() 在适配器上调用 notifyDataSetChanged() 之后调用。这就像说您要更改 ViewPager 中的哪些片段。

对于您的情况,如果您要更改屏幕方向,则可能会删除并重建整个活动,因此只需让适配器执行正确的操作即可。用非常简单的话来说:

    @Override
    public Object instantiateItem(ViewGroup container, int position) {

        if (orientation == ORIENTATION_PORTRAIT) {
            // ... set up the views for portrait
        } else {
            // ... set up the views for landscape
        }
    }

【讨论】:

  • 我前段时间尝试了notifyDataSetChanged(),但它没有按预期工作。我想如果我只扩展 PagerAdapter 而不是 Fragment(State)PagerAdapter 你的解决方案可能会奏效。然而,后者将“记住”旋转时的片段并且永远不会重新创建它们(也许是 FragmentManager 重新创建它们)。我的印象是getItemPosition() 会说是否必须重新创建它。我希望我不必编写自己的实例化和销毁代码。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-10-20
  • 2014-12-05
  • 1970-01-01
  • 1970-01-01
  • 2017-03-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多