Android ViewPager无法按预期工作

时间:2014-08-12 04:03:24

标签: android android-viewpager

我尝试制作一个包含三个视图的无限ViewPager:

    int lastPos;

    pager.setOnPageChangeListener(new OnPageChangeListener() {
        @Override
        public void onPageScrolled(int pos, float v, int i2) {
            Log.d("page", "scoll:" + pos);
        }

        @Override
        public void onPageSelected(int pos) {
            Log.d("page", "selected:" + pos);
        }

        @Override
        public void onPageScrollStateChanged(int state) {
            Log.d("page", "state:" + state);
            if (state == ViewPager.SCROLL_STATE_DRAGGING) {
                lastPos = getCurrentItem();
            }
            if (state == ViewPager.SCROLL_STATE_IDLE) {
                Log.d("page", "idle");
                int npos = getCurrentItem();
                if (npos != lastPos) {
                    setCurrentItem(1, false);
                    //resetPageContent(npos - lastPos);  //npos - lastPos  ==> Negative means left, positive means right.
                }
            }
        }
    });

如图所示,我将当前项目重置为1(以使寻呼机可以翻转),然后我将相应地更改页面内容。

但我现在有一些问题:

1)OnPageChangeListener:

我添加了一些日志以确保在OnPageChangeListener阶段发生了什么,这就是结果:

page﹕ scoll:1
page﹕ state:1
page﹕ scoll:1
page﹕ scoll:1
page﹕ scoll:1
page﹕ scoll:1
page﹕ state:2
page﹕ selected:2
page﹕ scoll:1
page﹕ scoll:1
page﹕ scoll:1
page﹕ scoll:1
page﹕ scoll:1
page﹕ scoll:1
page﹕ scoll:2
page﹕ state:0
page﹕ idle
page﹕ selected:1
page﹕ scoll:1

我无法理解,在页面滚动状态变为onPageScrolled后,IDLE将被称为事件。

onPageSelected被调用两次。

为什么?

2无限无法按预期工作。

一旦我正常滚动ViewPager,它就可以正常工作,但是一旦我快速滚动它,ViewPager将在某个时间结束。

我不确定是什么问题。我希望有人可以给我一些帮助。


更新:整个viewpager代码:

public class CustomViewPager extends ViewPager {
    private MyPagerAdapter myPagerAdapter;
    private int lastPos = 1;

    private int globalIndex = 1;

    private SinglePageView[] mPages = new SinglePageView[3];

    public CustomViewPager(Context context) {
        this(context, null);
    }


    public CustomViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
        myPagerAdapter = new MyPagerAdapter();
        setOnPageChangeListener(new OnPageChangeListener() {
            @Override
            public void onPageScrolled(int pos, float v, int i2) {
            }

            @Override
            public void onPageSelected(int pos) {
            }

            @Override
            public void onPageScrollStateChanged(int state) {
                if (state == ViewPager.SCROLL_STATE_IDLE) {
                    int npos = getCurrentItem();
                    if (npos != lastPos) {
                        resetPageContent(npos - lastPos);
                    }
                }
            }
        });
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        if (changed) {
            int w = r - l, h = b - t;

            for (int i = 0; i < 3; i++) {
                mPages[i] = new SinglePageView(getContext());
                mPages[i].setMinimumWidth(w);
                mPages[i].setMinimumHeight(h);
            }
            setAdapter(myPagerAdapter);
            resetPageContent(0);
        }
    }

    private void resetPageContent(int dir) {

        if (dir > 0) {
            globalIndex++;
        } else if (dir < 0)
            globalIndex--;

        mPages[1].setContent(String.valueOf(globalIndex));

        globalIndex--;
        mPages[0].setContent(String.valueOf(globalIndex));
        globalIndex++;

        globalIndex++;
        mPages[2].setContent(String.valueOf(globalIndex));
        globalIndex--;


        setCurrentItem(1, false);
        globalIndex++;
    }


    class MyPagerAdapter extends PagerAdapter {
        private MyPagerAdapter() {
        }

        @Override
        public int getCount() {
            return mPages.length;
        }

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            SinglePageView spv = mPages[position];
            container.addView(spv, 0);
            return spv;
        }

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

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

    class SinglePageView extends View {
        private String mContent = "Unassigned";
        private Paint mPaint;

        public SinglePageView(Context context) {
            super(context);
            mPaint = new Paint();
            mPaint.setColor(Color.RED);
        }

        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            canvas.save();
            canvas.drawText(mContent, 100, 100, mPaint);
            canvas.restore();
        }

        public void setContent(String content) {
            mContent = content;
        }
    }
}

虽然目前没有正确计算内容,但在快速滑动之前它是无限的,请演示:http://imgbin.org/images/18754.gif

3 个答案:

答案 0 :(得分:0)

如果使用ViewPager包含Fragment,则可以使用mViewPage.setAdapter(new PagerAdapter()); 而且你不需要实现监听器。

答案 1 :(得分:0)

如果您使用Fragment,您可以这样做:

第一: 在你的布局xml:

<android.support.v4.view.ViewPager 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/pager"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    />

第二

public static class MyFragment extends Fragment {


    public static Fragment getInstanceFragment(int sectionNumber) {     
        return getFragment(sectionNumber);

    }


    private static Fragment getFragment(int sectionNumber) {


        switch (sectionNumber) {

        case 0:
             return  Fragment.instantiate(mContext,
                    FirstFragment.class.getName());

        case 1:
            return  Fragment.instantiate(mContext,SecondFragment.class.getName());
        case 1:
            return  Fragment.instantiate(mContext,ThirdFragment.class.getName());


        default :   
            return  Fragment.instantiate(mContext,FirstFragment.class.getName());

        }


    }

} 

第三

public class SectionsPagerAdapter extends FragmentPagerAdapter {

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

    @Override
    public Fragment getItem(int position) {

        return MyFragment.getInstanceFragment(position);
    }

    @Override
    public int getCount() {
        // Show 3 total pages.
        return 3;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        Locale l = Locale.getDefault();
        switch (position) {
        case 0:
            return "First Fragment";
        case 1:
            return "Second Fragment";

        case 2:
            return "Second Fragment";
        default:
              return "First Fragment";

        }

    }


}

然后:

 ViewPager mViewPage = (ViewPager) findViewById(R.id.pager);

 SectionsPagerAdapter mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());

 mViewPage.setAdapter(mSectionsPagerAdapter);;

如果您想实现ViewPaper的Listener:

mViewPage.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener(){

        @Override
        public void onPageSelected(int position) {


        }


    });

答案 2 :(得分:0)

对于无限的ViewPager,我编写了自己的代码,如this