首页 文章

当当前页面不是第一页时,ViewPager在旋转屏幕后有错误的偏移数据

提问于
浏览
5

App结构:

我的应用程序只有一个 FragmentActivity ,而 FragmentActivity 主机 Fragment 主机 ViewPager . ViewPager 有一个子类 FragmentStatePagerAdapater 的适配器,该适配器覆盖 getItem() 以根据位置返回一个新的Fragment; getCount() 设置为始终返回2 .

问题:

应用程序工作正常,直到两件事情发生:当ViewPager显示第二个片段时发生旋转,或者如果在 onResume() 中,ViewPager被告知滚动到第一个片段之外的页面 . 据我所知,这些情况是相同的 . 当其中一个事件发生时,滚动停止了,可见的Fragment是ViewPager管理的第二个片段, the onPageScrolled(int, float, int) callback is called with the 'position' argument still at '0' (it should be 1) and the 'positionOffset' argument set to '1' (which is outside the the [0,1) range as promised in the docs). 我在ViewPager代码中做了一些调查,发现 boolean pageScrolled(int xpos) 函数来自于调用值使用范围[-940,0](第一个为-940,第二个为0)的值调用[0,940](第一页上为0,然后是第二页上为940)的范围 . 如果ViewPager被重置为认为第二页是第一页,那么这实际上是有意义的(有点),虽然它根本不是我想要的 .

一些代码:

ViewPagerFragment(托管ViewPager) . MyViewPager只是支持库的ViewPager的复制/粘贴;我想从其私有方法中打印出一些数据 .

public class ViewPagerFragment extends Fragment implements MyViewPager.OnPageChangeListener{

@InjectView(R.id.view_pager) MyViewPager viewPager;

@DebugLog
public ViewPagerFragment() {
    setRetainInstance(true);
}


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_view_pager, container, false);
    ButterKnife.inject(this,view);
    Log.d("onCreateView()","ViewPagerFragment = "+this.toString());
    return view;
}

@Override
public void onResume() {
    super.onResume();
    setupPager();
}

void setupPager(){
    if(viewPager != null) {
        if (viewPager.getAdapter() == null) {
            viewPager.setAdapter(new MyFragmentAdapter(getChildFragmentManager()));
        }
        viewPager.setOnPageChangeListener(this);
        viewPager.setPageMargin(40);
    }
}

@Override
@DebugLog
public void onDestroyView() {
    super.onDestroyView();
    viewPager.setOnPageChangeListener(null);
    ButterKnife.reset(this);
}

@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

    if(positionOffset == 1f){
        Log.d("onPageScrolled","position offset == 1 and position == "+position+". That's bad!");
    } else if(position == 1){
        Log.d("onPageScrolled","position offset == "+positionOffset+" and position == 1. That's good!");
    }

}

public static class MyFragmentAdapter extends FragmentStatePagerAdapter{

    public MyFragmentAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    @DebugLog
    public Fragment getItem(int position) {
        return PageFragment.newInstance(position);
    }

    @Override
    public int getCount() {
        return 2;
    }
}

}

我的问题,如果不是暗示,是 'What have I done to mess up my ViewPager, and how can I fix it?' 删除 setRetainInstance() 呼叫显然会将事情重置为正常,但后来我在ViewPager中丢失了我的'place' . 删除 setRetainInstance() 调用然后使用 Bundle savedInstanceState 保留ViewPager位置也不起作用(如我文章顶部所述) .

提前致谢!

2 回答

  • 0

    旋转后ViewPager上似乎有一个错误 .

    我计算当前页面的scrollX(偏移量),当一页滚动完成时,它总是为0 .

    但是,旋转后,它会达到1或X(页面宽度大约为938~9,如果页面宽度为940) .

    当设备旋转时,我在 onPageScrolled 上遇到了一些问题,我通过在 onConfigurationChanged 等旋转回调上再次调用 setAdapter 解决了这些问题 .

    这是一些代码块 . Device 是我的自定义类 .

    public void configOnOrientationChange() {
        if (Device.isPortrait(getContext())) {
            configOnPortraitOrientation();
        } else if (Device.isLandscape(getContext())) {
            configOnLandscapeOrientation();
        }
    
        int currentItem = mViewPager.getCurrentItem();
        if (mPagerAdapter != null) {
            mViewPager.setAdapter(mPagerAdapter);
            mViewPager.setCurrentItem(currentItem);
        }
    }
    

    希望这可以帮助 .

  • 0

    像这样覆盖ViewPager的onSizeChanged方法:

    @Override
        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
            super.onSizeChanged(w, h, oldw, oldh);
             beginFakeDrag();
            fakeDragBy(0);
            endFakeDrag();
        }
    

相关问题