onPageSelected在调用onCreateView之前运行?

时间:2017-09-08 22:53:32

标签: android

我正在使用ViewPager循环遍历一组片段,我想在每个片段滑到屏幕后更新它们。基本上,我希望文本在片段结束后“淡入”。

我尝试使用片段的onStartonResume方法,虽然这适用于大多数页面,但它不适用于第二页,因为无论什么愚蠢的原因,第一页AND第二页的onStart / onResume方法同时被调用(在第二页打到屏幕之前)。

现在我正在尝试使用onPageChangeListener的onPageSelected回调。该方法如下所示:

@Override
public void onPageSelected(final int position) {
    mCurrentPosition = position;

    PageFragment fragment = (PageFragment) ((MainActivity.ScreenSlidePagerAdapter) mViewPager.getAdapter()).getItem(position);

    fragment.onSelect();

}

片段中的onSelect方法如下所示:

public void onSelect(){

    new android.os.Handler().postDelayed(
            new Runnable() {
                public void run() {

                    mSwitcher.setText("");

                    mNum = getArguments() != null ? getArguments().getInt("num") : 1;
                    Media currentMedia = slideshow.getMedia().get(mNum);

                    mSwitcher.setText(currentMedia.getDisplayName());
                }
            },
            4000);
}

这种方式的问题是,行mSwitcher.setText("");会抛出NullPointerException

java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextSwitcher.setText(java.lang.CharSequence)' on a null object reference

这表明该类中的onCreateView方法尚未运行,因为mSwitcher变量已实例化。这对我来说似乎是香蕉,因为此时视线已经滑到了屏幕上。

有关如何解决此问题的任何想法将不胜感激。这是我的第一次Android体验,我一直在努力解决这个愚蠢的文本淡入问题整整一周没有运气。在这一点上,我几乎已经准备好放弃移动作为一个平台,因为到目前为止每一次微小的改变都是多么痛苦。

2 个答案:

答案 0 :(得分:1)

ViewPager将下一页保留在内存中这是默认行为。你可以调用它来调整它:

viewPager.setOffscreenPageLimit(2);

然而,这可能没有用,就像在上面的方法中传递0一样,viewPager会忽略它。

你正朝着正确的方向前进。我相信现在问题出在你的ScreenSlidePagerAdapter。在getItem(int position)中,您可能会有类似

的内容
if(position == 1)
    return new PageFragment();

而是将适配器更改为以下内容,

public class ScreenSlidePagerAdapter extends FragmentPagerAdapter {

    private List<Fragment> mFragments = new ArrayList<>();

    public ScreenSlidePagerAdapter(FragmentManager fm, List<Item> items) {
        super(fm);

        for (Item item : items) {
            mFragments.add(new PageFragment());
        }
    }


    @Override
    public int getCount() {
        return mFragments.size();
    }

    @Override
    public Fragment getItem(int position) {
        return mFragments.get(position); // Return from list instead of new PagerFragment()
    }
}

答案 1 :(得分:0)

我遇到与你类似的问题,在片段初始化之前调用onPageSelected(),但你的描述不够详细,例如你如何选择第二页。

当适配器被送入Fragments时,或者我们说getCount()&gt; 0,getItem()将返回一个片段,它不是null。但这并不意味着它已初始化,至少从FragmentStatePagerAdapter延伸它并不是没有。

当适配器被提供数据并调用notifyDataSetChange()时,适配器将默认初始化前两页。如果在notifyDataSetChange()之后立即调用setCurrentItem()移动到其他页面,则可能会发生问题。在运行时,setCurrentItem() - &gt;可以在片段初始化之前调用onPageSelected()。

我的解决方案是在setCurrentItem()时使用view.post()。 e.g。

viewPager.post(() -> viewPager.setCurrentItem(index));