我只能使用ViewPager向后翻页而不能向前翻页

时间:2017-07-29 13:22:25

标签: android android-viewpager android-banner

我只能使用ViewPager向后翻页而不能向前翻页。

running image

我写了一个横幅,但我只能使用ViewPager向后翻页而不能向前翻页。

这是我写的适配器。

class MyPagerAdapter extends PagerAdapter {

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        int p = position % mImgRes.length;
        container.addView(mListView.get(p));
        return mListView.get(p);
    } 

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        container.removeView((View) object);
    }

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

    @Override
    public boolean isViewFromObject(View view, Object object) {
        return (view == object);
    }

}

这是一条错误消息。

   07-29 20:45:02.098 20791-20791/com.example.myfirstpro E/AndroidRuntime: 
   FATAL EXCEPTION: main
   Process: com.example.myfirstpro, PID: 20791
   java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
       at android.view.ViewGroup.addViewInner(ViewGroup.java:4465)
       at android.view.ViewGroup.addView(ViewGroup.java:4301)
       at android.support.v4.view.ViewPager.addView(ViewPager.java:1505)
       at android.view.ViewGroup.addView(ViewGroup.java:4242)
       at android.view.ViewGroup.addView(ViewGroup.java:4215)
       at com.example.myfirstpro.MainFragment$MyPagerAdapter.instantiateItem(MainFragment.java:62)
       at android.support.v4.view.ViewPager.addNewItem(ViewPager.java:1034)
       at android.support.v4.view.ViewPager.populate(ViewPager.java:1216)
       at android.support.v4.view.ViewPager.populate(ViewPager.java:1116)
       at android.support.v4.view.ViewPager$3.run(ViewPager.java:273)
       at android.view.Choreographer$CallbackRecord.run(Choreographer.java:892)
       at android.view.Choreographer.doCallbacks(Choreographer.java:704)
       at android.view.Choreographer.doFrame(Choreographer.java:637)
       at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:878)
       at android.os.Handler.handleCallback(Handler.java:739)
       at android.os.Handler.dispatchMessage(Handler.java:95)
       at android.os.Looper.loop(Looper.java:148)
       at android.app.ActivityThread.main(ActivityThread.java:5628)
       at java.lang.reflect.Method.invoke(Native Method)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:853)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:737)

当我前进时,程序会崩溃。

这是除了适配器以外的代码。@ Hong Duan

    private ViewPager mVpScroll;
private int mImgRes[] = new int[] {
        R.drawable.banner01,
        R.drawable.banner02,
        R.drawable.banner03
};
private List<View> mListView = new ArrayList<>();
private LayoutInflater mInfalte;

public MainFragment() {
    // Required empty public constructor
}


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    for (int i = 0; i < mImgRes.length; i++) {
        View inflate = inflater.inflate(R.layout.fragment_main_scroll_item, null);
        ImageView ivBanner = (ImageView) inflate.findViewById(R.id.iv_scroll);
        ivBanner.setImageResource(mImgRes[i]);
        mListView.add(inflate);
    }
    mInfalte = inflater;
    return inflater.inflate(R.layout.fragment_main, container, false);
}

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    mVpScroll = (ViewPager) view.findViewById(R.id.vp_scroll);
    mVpScroll.setAdapter(new MyPagerAdapter());
}

1 个答案:

答案 0 :(得分:0)

如错误消息所示,根本原因是孩子View被添加两次。但为什么只有向后滑动才会发生这种情况?我做了一个测试项目,我想我找到了原因:)

ViewPager滚动时,它会使用PagerAdapter方法回收项目:instantiateItemdestroyItem,当ViewPager想要展示时调用一个新项instantiateItem,当ViewPager滚动时,屏幕外的视图将被方法destroyItem销毁。

默认情况下,ViewPager会在每侧保留 1 更多项目以实现平滑滚动,这意味着最多只有 3 < / strong>项目由ViewPager保留。

问题是,您正在使用:

int p = position % mImgRes.length;

实现&#34;循环&#34; ViewPager,这意味着如果mImgRes.length == 3,则位置3将在位置0显示相同的View

现在想想你的情况:

  • ViewPager时,项01(右侧项)由instantiateItem添加;

  • 然后向右滚动页面,显示商品1,添加商品2,现在添加商品0(左侧商品),{{1保留,1(右侧项目);

  • 再次向右滚动页面,显示项2,添加项2,方法3销毁项0,现在项目destroyItem(左侧项目),12(右侧项目,与3相同的项目)保留;

如果0instantiateItem按预期工作,一切正常,当你滚动到右边时(&#34;转发&#34;)它确实有效,但是当你执行时它不起作用滚动到左侧(&#34;向后&#34;)因为执行destroyIteminstantiateItem的顺序不同!见日志:

destroyItem

当您向右滚动时,07-30 22:00:04.385 26064-26064/com.example.test D/xxxxx: instantiateItem: 0 07-30 22:00:04.388 26064-26064/com.example.test D/xxxxx: instantiateItem: 1 07-30 22:00:17.693 26064-26064/com.example.test D/xxxxx: instantiateItem: 2 07-30 22:00:18.743 26064-26064/com.example.test D/xxxxx: destroyItem: 0 07-30 22:00:18.744 26064-26064/com.example.test D/xxxxx: instantiateItem: 3 07-30 22:00:26.477 26064-26064/com.example.test D/xxxxx: instantiateItem: 0 < -- crash!!! 07-30 22:00:18.743 26064-26064/com.example.test D/xxxxx: destroyItem: 3 先执行,然后执行destroyItem,这样就可以正常工作了,但滚动到左侧时,instantiateItem先执行,所以最后执行打印日志行,第二次添加商品instantiateItem,因为商品0(与商品3共享相同的View)尚未销毁,然后它崩溃了:))

有趣的是,如果0,它会正常工作,因为当有4个项目时,mImgRes.length > 3执行时不会太晚。

所以,如果你想用&#34;循环&#34;来实现destroyItem功能,你必须考虑如何解决这个问题。