在 PagerAdapter 中实现循环滚动

发布于 2024-12-17 17:16:03 字数 6723 浏览 3 评论 0原文

我正在使用 PagerAdapter 进行水平滑动,以在我的应用程序中显示报纸页面。

目前我想在这个应用程序中实现循环滚动。现在我所做的是 每当我进入最后一页时,我都会尝试将 currentItem 设置为第一页即适用于最后一页的功能第一页,但问题是如何从第一页转到最后一页。 在这里我粘贴与 pagerAdapter & 相关的代码onPageChangeListener:-

    awesomeAdapter = new AwesomePagerAdapter(awesomePager);
    awesomePager.setAdapter(awesomeAdapter);
    awesomePager.setPageMargin(10);
    awesomePager.setOnPageChangeListener(new OnPageChangeListener() {

        int lastPosition;
        float posOffset = 0;
        @Override
        public void onPageSelected(int position) {
               viewerPage = position;
               CommonLogic.logMessage("Viewer Page:- "+ viewerPage, TAG, Log.VERBOSE);
               posOffset = 0;
        }

        @Override
        public void onPageScrolled(int position,float positionOffset,int positionOffsetPixels) {
            if (positionOffset == 0 && positionOffsetPixels == 0 && position != 0) {
                    lastPosition = position;
            }

            posOffset -= positionOffset;

            CommonLogic.logMessage(" Position:-  "
                                     + position + " Position Offset:- "                                     + positionOffset
                                        + " Position Offset Variable:-  "
                                        + posOffset
                                        + "  Position Offset Pixels:- "
                                        + positionOffsetPixels
                                        + " Last Position " + lastPosition,
                                        TAG, Log.VERBOSE);

                                CommonLogic.logMessage(" Last Position "
                                        + lastPosition, TAG, Log.VERBOSE);

        }

        @Override
        public void onPageScrollStateChanged(int state) {
                 // To Detect the Last Page & This Sets it to first page.This working fine. 
         if (state == ViewPager.SCROLL_STATE_DRAGGING && viewerPage == (uris.size() - 1)) {
            CommonLogic.logMessage("Scroll State Changed ", TAG,Log.VERBOSE);
            postDelayed(new Runnable() {
               @Override
               public void run() {
                awesomePager.setCurrentItem(0, true);
               }
            }, 200);
        }
// I have also used this to detect whether the user is on first & try to move on last page,but it is not working well.
else if (state == ViewPager.SCROLL_STATE_DRAGGING && (lastPosition == 0 || lastPosition == (uris.size() - 1)) && viewerPage == 0 && posOffset <= 0) {
                                    CommonLogic.logMessage( "Scroll State Changed ", TAG,Log.VERBOSE);
    postDelayed(new Runnable() {
        @Override
        public void run() {
         awesomePager.setCurrentItem((uris.size() - 1), true);
                }
        }, 200);
        } 
}
}
    });

在我的情况下,PagerAdapter 即 AwesomweAdapter 也如下:-

private class AwesomePagerAdapter extends PagerAdapter {

    ViewPager pdfContainer;
    DocumentNewView documentNewView;
    CustomViewPager customViewPager;

    public AwesomePagerAdapter(CustomViewPager awesomePager) {
        this.customViewPager = awesomePager;
    }

    @Override
    public int getItemPosition(Object object) {
        return POSITION_NONE;
    }

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

    public DocumentNewView addViewAt(int position, DocumentNewView mainView) {
        CommonLogic.logMessage("Position of View:- " + position, TAG,
                Log.VERBOSE);
        pdfContainer.addView(mainView);
        return mainView;
    }

    /**
     * Create the page for the given position. The adapter is responsible
     * for adding the view to the container given here, although it only
     * must ensure this is done by the time it returns from
     * {@link #finishUpdate()}.
     * 
     * @param container
     *            The containing View in which the page will be shown.
     * @param position
     *            The page position to be instantiated.
     * @return Returns an Object representing the new page. This does not
     *         need to be a View, but can be some other container of the
     *         page.
     */
    @Override
    public Object instantiateItem(View collection, int position) {
        CommonLogic
                .logMessage("Instantiate Item Called ", TAG, Log.VERBOSE);

        documentNewView = new DocumentNewView(cxt, display, customViewPager);
        documentNewView.setPdfContext(new PdfContext());
        CodecDocument codecDocument = documentNewView.open(uris
                .get(position));
        documentNewView.renderDocument(codecDocument);
        documentNewView.setMaxZoom(4f);
        documentNewView.setVerticalScrollBarEnabled(true);
        codecDocument = null;
        this.pdfContainer = (ViewPager) collection;
        return addViewAt(position, documentNewView);
     }

    /**
     * Remove a page for the given position. The adapter is responsible for
     * removing the view from its container, although it only must ensure
     * this is done by the time it returns from {@link #finishUpdate()}.
     * 
     * @param container
     *            The containing View from which the page will be removed.
     * @param position
     *            The page position to be removed.
     * @param object
     *            The same object that was returned by
     *            {@link #instantiateItem(View, int)}.
     */
    @Override
    public void destroyItem(View collection, int position, Object view) {
        pdfContainer.removeView((DocumentNewView) view);

    }

    /**
     * Called when the a change in the shown pages has been completed. At
     * this point you must ensure that all of the pages have actually been
     * added or removed from the container as appropriate.
     * 
     * @param container
     *            The containing View which is displaying this adapter's
     *            page views.
     */
    @Override
    public void finishUpdate(View arg0) {
        CommonLogic.logMessage("Finish Update Called ", TAG, Log.VERBOSE);
    }

    @Override
    public void restoreState(Parcelable arg0, ClassLoader arg1) {
    }

    @Override
    public Parcelable saveState() {
        return null;
    }

    @Override
    public void startUpdate(View arg0) {
        CommonLogic.logMessage("State Update Called ", TAG, Log.VERBOSE);
    }

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

    }

请给我代码中的任何建议/更改(如果适用)。 提前致谢。

I am using PagerAdapter for horizontal swiping for showing newspaper pages in my app.

Currently I want to implement the circular scrolling in this app.Right now what I have done is whenever I am getting on last page I try to set the currentItem to first pagei.e that functionality working for last page to first page,but the problem is that how can I go to last page from first page.
Here I am pasting my code related to pagerAdapter & onPageChangeListener:-

    awesomeAdapter = new AwesomePagerAdapter(awesomePager);
    awesomePager.setAdapter(awesomeAdapter);
    awesomePager.setPageMargin(10);
    awesomePager.setOnPageChangeListener(new OnPageChangeListener() {

        int lastPosition;
        float posOffset = 0;
        @Override
        public void onPageSelected(int position) {
               viewerPage = position;
               CommonLogic.logMessage("Viewer Page:- "+ viewerPage, TAG, Log.VERBOSE);
               posOffset = 0;
        }

        @Override
        public void onPageScrolled(int position,float positionOffset,int positionOffsetPixels) {
            if (positionOffset == 0 && positionOffsetPixels == 0 && position != 0) {
                    lastPosition = position;
            }

            posOffset -= positionOffset;

            CommonLogic.logMessage(" Position:-  "
                                     + position + " Position Offset:- "                                     + positionOffset
                                        + " Position Offset Variable:-  "
                                        + posOffset
                                        + "  Position Offset Pixels:- "
                                        + positionOffsetPixels
                                        + " Last Position " + lastPosition,
                                        TAG, Log.VERBOSE);

                                CommonLogic.logMessage(" Last Position "
                                        + lastPosition, TAG, Log.VERBOSE);

        }

        @Override
        public void onPageScrollStateChanged(int state) {
                 // To Detect the Last Page & This Sets it to first page.This working fine. 
         if (state == ViewPager.SCROLL_STATE_DRAGGING && viewerPage == (uris.size() - 1)) {
            CommonLogic.logMessage("Scroll State Changed ", TAG,Log.VERBOSE);
            postDelayed(new Runnable() {
               @Override
               public void run() {
                awesomePager.setCurrentItem(0, true);
               }
            }, 200);
        }
// I have also used this to detect whether the user is on first & try to move on last page,but it is not working well.
else if (state == ViewPager.SCROLL_STATE_DRAGGING && (lastPosition == 0 || lastPosition == (uris.size() - 1)) && viewerPage == 0 && posOffset <= 0) {
                                    CommonLogic.logMessage( "Scroll State Changed ", TAG,Log.VERBOSE);
    postDelayed(new Runnable() {
        @Override
        public void run() {
         awesomePager.setCurrentItem((uris.size() - 1), true);
                }
        }, 200);
        } 
}
}
    });

Also the PagerAdapter i.e AwesomweAdapter in my case,is also as folllows:-

private class AwesomePagerAdapter extends PagerAdapter {

    ViewPager pdfContainer;
    DocumentNewView documentNewView;
    CustomViewPager customViewPager;

    public AwesomePagerAdapter(CustomViewPager awesomePager) {
        this.customViewPager = awesomePager;
    }

    @Override
    public int getItemPosition(Object object) {
        return POSITION_NONE;
    }

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

    public DocumentNewView addViewAt(int position, DocumentNewView mainView) {
        CommonLogic.logMessage("Position of View:- " + position, TAG,
                Log.VERBOSE);
        pdfContainer.addView(mainView);
        return mainView;
    }

    /**
     * Create the page for the given position. The adapter is responsible
     * for adding the view to the container given here, although it only
     * must ensure this is done by the time it returns from
     * {@link #finishUpdate()}.
     * 
     * @param container
     *            The containing View in which the page will be shown.
     * @param position
     *            The page position to be instantiated.
     * @return Returns an Object representing the new page. This does not
     *         need to be a View, but can be some other container of the
     *         page.
     */
    @Override
    public Object instantiateItem(View collection, int position) {
        CommonLogic
                .logMessage("Instantiate Item Called ", TAG, Log.VERBOSE);

        documentNewView = new DocumentNewView(cxt, display, customViewPager);
        documentNewView.setPdfContext(new PdfContext());
        CodecDocument codecDocument = documentNewView.open(uris
                .get(position));
        documentNewView.renderDocument(codecDocument);
        documentNewView.setMaxZoom(4f);
        documentNewView.setVerticalScrollBarEnabled(true);
        codecDocument = null;
        this.pdfContainer = (ViewPager) collection;
        return addViewAt(position, documentNewView);
     }

    /**
     * Remove a page for the given position. The adapter is responsible for
     * removing the view from its container, although it only must ensure
     * this is done by the time it returns from {@link #finishUpdate()}.
     * 
     * @param container
     *            The containing View from which the page will be removed.
     * @param position
     *            The page position to be removed.
     * @param object
     *            The same object that was returned by
     *            {@link #instantiateItem(View, int)}.
     */
    @Override
    public void destroyItem(View collection, int position, Object view) {
        pdfContainer.removeView((DocumentNewView) view);

    }

    /**
     * Called when the a change in the shown pages has been completed. At
     * this point you must ensure that all of the pages have actually been
     * added or removed from the container as appropriate.
     * 
     * @param container
     *            The containing View which is displaying this adapter's
     *            page views.
     */
    @Override
    public void finishUpdate(View arg0) {
        CommonLogic.logMessage("Finish Update Called ", TAG, Log.VERBOSE);
    }

    @Override
    public void restoreState(Parcelable arg0, ClassLoader arg1) {
    }

    @Override
    public Parcelable saveState() {
        return null;
    }

    @Override
    public void startUpdate(View arg0) {
        CommonLogic.logMessage("State Update Called ", TAG, Log.VERBOSE);
    }

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

    }

Please give me any suggestions/changes in my code (if applicable) for it.
Thanks in Advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

要走就滚别墨迹 2024-12-24 17:16:03

我可以通过重写 OnPageChangeListeneronPageSelected 方法来实现此目的。假设您有三个页面,顺序为 A<->B<->C。目标是,如果我们从 A 向右滚动,则到达 C;如果我们从 C 向左滚动,则类似地到达 A >。

为此,请将您的页面定义为 5 个页面 (3+2),并按如下方式组织页面:

C<->A<-> ;B<->C<->A

现在在 onPageSelected 方法中,检查位置是否0,更改它到 3 (getCount()-2) 并且如果位置是 4 (getCount()-1),将其更改为1。确保使用该方法:

setCurrentItem(item, smoothScroll)

这是 CircularPagerAdaptor 类的完整代码:

package zolender.adapters;

import android.content.Context;
import android.os.Parcelable;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.view.LayoutInflater;
import android.view.View;

public class CircularPagerAdapter extends PagerAdapter{

    private int[] pageIDsArray;
    private int count;

    public CircularPagerAdapter(final ViewPager pager, int... pageIDs) {
        super();
        int actualNoOfIDs = pageIDs.length;
        count = actualNoOfIDs + 2;
        pageIDsArray = new int[count];
        for (int i = 0; i < actualNoOfIDs; i++) {
            pageIDsArray[i + 1] = pageIDs[i];
        }
        pageIDsArray[0] = pageIDs[actualNoOfIDs - 1];
        pageIDsArray[count - 1] = pageIDs[0];

        pager.setOnPageChangeListener(new OnPageChangeListener() {

            @Override
            public void onPageSelected(int position) {
                int pageCount = getCount();
                if (position == 0){
                    pager.setCurrentItem(pageCount-2,false);
                } else if (position == pageCount-1){
                    pager.setCurrentItem(1,false);
                }
            }

            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                // TODO Auto-generated method stub
            }

            @Override
            public void onPageScrollStateChanged(int state) {
                // TODO Auto-generated method stub
            }
        });
    }

    public int getCount() {
        return count;
    }

    public Object instantiateItem(View container, int position) {
        LayoutInflater inflater = (LayoutInflater) container.getContext()
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        int pageId = pageIDsArray[position];
        View view = inflater.inflate(pageId, null);
        ((ViewPager) container).addView(view, 0);
        return view;
    }

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

    @Override
    public void finishUpdate(View container) {
        // TODO Auto-generated method stub
    }

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

    @Override
    public void restoreState(Parcelable state, ClassLoader loader) {
        // TODO Auto-generated method stub
    }

    @Override
    public Parcelable saveState() {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public void startUpdate(View container) {
        // TODO Auto-generated method stub
    }
}

以下是如何使用它:

myPager = (ViewPager) findViewById(R.id.myfivepanelpager);
PagerAdapter adapter = new CircularPagerAdapter(myPager, new int[]{R.layout.farleft, R.layout.left, R.layout.middle, R.layout.right, R.layout.farright});
myPager.setAdapter(adapter);
myPager.setCurrentItem(3);

I could achieve this by overriding onPageSelected method of OnPageChangeListener. Consider you have three pages in this order A<->B<->C. To goal is to reach C if we scroll right from A and similarly to reach A if we scroll left from C.

To do this, define your to have 5 pages (3+2), and organize the pages as follows:

C<->A<->B<->C<->A

Now in the onPageSelected method, check and if position if 0, change it to 3 (getCount()-2) and if position is 4 (getCount()-1), change it to 1. Make sure to use the method:

setCurrentItem(item, smoothScroll)

Here is complete code for CircularPagerAdaptor Class :

package zolender.adapters;

import android.content.Context;
import android.os.Parcelable;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.view.LayoutInflater;
import android.view.View;

public class CircularPagerAdapter extends PagerAdapter{

    private int[] pageIDsArray;
    private int count;

    public CircularPagerAdapter(final ViewPager pager, int... pageIDs) {
        super();
        int actualNoOfIDs = pageIDs.length;
        count = actualNoOfIDs + 2;
        pageIDsArray = new int[count];
        for (int i = 0; i < actualNoOfIDs; i++) {
            pageIDsArray[i + 1] = pageIDs[i];
        }
        pageIDsArray[0] = pageIDs[actualNoOfIDs - 1];
        pageIDsArray[count - 1] = pageIDs[0];

        pager.setOnPageChangeListener(new OnPageChangeListener() {

            @Override
            public void onPageSelected(int position) {
                int pageCount = getCount();
                if (position == 0){
                    pager.setCurrentItem(pageCount-2,false);
                } else if (position == pageCount-1){
                    pager.setCurrentItem(1,false);
                }
            }

            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                // TODO Auto-generated method stub
            }

            @Override
            public void onPageScrollStateChanged(int state) {
                // TODO Auto-generated method stub
            }
        });
    }

    public int getCount() {
        return count;
    }

    public Object instantiateItem(View container, int position) {
        LayoutInflater inflater = (LayoutInflater) container.getContext()
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        int pageId = pageIDsArray[position];
        View view = inflater.inflate(pageId, null);
        ((ViewPager) container).addView(view, 0);
        return view;
    }

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

    @Override
    public void finishUpdate(View container) {
        // TODO Auto-generated method stub
    }

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

    @Override
    public void restoreState(Parcelable state, ClassLoader loader) {
        // TODO Auto-generated method stub
    }

    @Override
    public Parcelable saveState() {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public void startUpdate(View container) {
        // TODO Auto-generated method stub
    }
}

And here is how you can use it:

myPager = (ViewPager) findViewById(R.id.myfivepanelpager);
PagerAdapter adapter = new CircularPagerAdapter(myPager, new int[]{R.layout.farleft, R.layout.left, R.layout.middle, R.layout.right, R.layout.farright});
myPager.setAdapter(adapter);
myPager.setCurrentItem(3);
一袭水袖舞倾城 2024-12-24 17:16:03

我还需要一个圆形 ViewPager。这就是我所做的。我假设您从某处获取 pageCount 值。

...
    pager = (ViewPager) findViewById(R.id.pager);
    //Gesture detection
    final GestureDetector gestureDetector = new GestureDetector(new MyGestureDetector());
    pager.setOnTouchListener(new OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            return gestureDetector.onTouchEvent(event);
        }
    });

    //pagelistener is just for getting selected page
    pager.setOnPageChangeListener(new OnPageChangeListener() {

        @Override
        public void onPageSelected(int position) {
            selectedPage = position;
        }

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

        @Override
        public void onPageScrollStateChanged(int state) {
        }
    });

这是手势检测器。
此处复制

    class MyGestureDetector extends SimpleOnGestureListener {

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {

        int SWIPE_MIN_DISTANCE = Utils.ConvertToPixel(mContext, 50);
        int SWIPE_MAX_OFF_PATH = Utils.ConvertToPixel(mContext, 250);
        int SWIPE_THRESHOLD_VELOCITY = Utils.ConvertToPixel(mContext, 200);

        try {

            if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH)
                return false;
            // right to left swipe
            if(e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE 
                    && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY
                    && selectedPage == (pageCount - 1)) {
                pager.setCurrentItem(0);
                return true;
            }  else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE 
                    && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY
                    && selectedPage == 0) {
                pager.setCurrentItem(pageCount - 1);
                return true;
            }
        } catch (Exception e) {
            // nothing
        }
        return false;
    }

}

I also needed a circular ViewPager. This is what I've done. I assume you get pageCount value from somewhere.

...
    pager = (ViewPager) findViewById(R.id.pager);
    //Gesture detection
    final GestureDetector gestureDetector = new GestureDetector(new MyGestureDetector());
    pager.setOnTouchListener(new OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            return gestureDetector.onTouchEvent(event);
        }
    });

    //pagelistener is just for getting selected page
    pager.setOnPageChangeListener(new OnPageChangeListener() {

        @Override
        public void onPageSelected(int position) {
            selectedPage = position;
        }

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

        @Override
        public void onPageScrollStateChanged(int state) {
        }
    });

and here is the GestureDetector.
Copied from here

    class MyGestureDetector extends SimpleOnGestureListener {

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {

        int SWIPE_MIN_DISTANCE = Utils.ConvertToPixel(mContext, 50);
        int SWIPE_MAX_OFF_PATH = Utils.ConvertToPixel(mContext, 250);
        int SWIPE_THRESHOLD_VELOCITY = Utils.ConvertToPixel(mContext, 200);

        try {

            if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH)
                return false;
            // right to left swipe
            if(e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE 
                    && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY
                    && selectedPage == (pageCount - 1)) {
                pager.setCurrentItem(0);
                return true;
            }  else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE 
                    && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY
                    && selectedPage == 0) {
                pager.setCurrentItem(pageCount - 1);
                return true;
            }
        } catch (Exception e) {
            // nothing
        }
        return false;
    }

}
电影里的梦 2024-12-24 17:16:03

扩展 Z0lenDer 的答案,当使用常规 ViewPager 时,您不需要释放每个关联视图的内存,存储创建的视图比存储布局 ID 更有效。如果想要消除切换项目时的任何延迟和闪烁,这是必要的。

使用 onPageSelected 时动画也存在问题,因为它不会让幻灯片在切换之前完成。我发现避免这种情况的唯一方法是仅在滚动状态更改为 SCROLL_STATE_IDLE 后才执行切换,并仅在 onPageSelected 中设置当前项目。

private int currentPage = 0;

...

    pager.setOnPageChangeListener(new OnPageChangeListener() {

        @Override
        public void onPageSelected(int position) {
            currentPage = position;
        }

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

        }

        @Override
        public void onPageScrollStateChanged(int state) {
            // TODO Auto-generated method stub
            Log.d(TAG, "onPageScrollStateChanged: " + state);
            if (state == ViewPager.SCROLL_STATE_IDLE) {
                int pageCount = getCount();
                if (currentPage == 0){
                    pager.setCurrentItem(pageCount-2,false);
                } else if (currentPage == pageCount-1){
                    pager.setCurrentItem(1,false);
                }
            }
        }

    });

Expanding on Z0lenDer's answer, when using a regular ViewPager where you don't need to free the memory for each associated view, it's more efficient to store the created views rather than the layout IDs. This is necessary if wanting to get rid of any delay and flicker when the item is being switched.

There's also an issue with the animation when using onPageSelected, as it doesn't let the slide finish before doing the switch. The only way I found to avoid this is to only perform the switch once the scroll state has changed to SCROLL_STATE_IDLE and just setting the current item in onPageSelected.

private int currentPage = 0;

...

    pager.setOnPageChangeListener(new OnPageChangeListener() {

        @Override
        public void onPageSelected(int position) {
            currentPage = position;
        }

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

        }

        @Override
        public void onPageScrollStateChanged(int state) {
            // TODO Auto-generated method stub
            Log.d(TAG, "onPageScrollStateChanged: " + state);
            if (state == ViewPager.SCROLL_STATE_IDLE) {
                int pageCount = getCount();
                if (currentPage == 0){
                    pager.setCurrentItem(pageCount-2,false);
                } else if (currentPage == pageCount-1){
                    pager.setCurrentItem(1,false);
                }
            }
        }

    });
七颜 2024-12-24 17:16:03

试试这个

((ViewPager) container)
                .setOnPageChangeListener(new OnPageChangeListener() {
                    @Override
                    public void onPageSelected(int position) {
                        Log.i("TAG", "pos::" + position);

                    }
                    @Override
                    public void onPageScrollStateChanged(int state) {
                        // TODO Auto-generated method stub                            
                           int currentPage = pager.getCurrentItem();
                           Log.i("TAG", "currentPage::" + currentPage);
                           Log.i("TAG", "currentState::" + currentState);
                           Log.i("TAG", "previousState::" + previousState);
                           if (currentPage == 4 || currentPage == 0) {
                            previousState = currentState;
                            currentState = state;
                            if (previousState == 1 && currentState == 0) {
                             pager.setCurrentItem(currentPage == 0 ? 4 : 0);
                            }
                           }

                    }

                    @Override
                    public void onPageScrolled(int arg0, float arg1,
                            int arg2) {
                        // TODO Auto-generated method stub

                    }
                });

        return

这应该放在里面

 @Override
    public Object instantiateItem(final View container, int position) {}

Try this

((ViewPager) container)
                .setOnPageChangeListener(new OnPageChangeListener() {
                    @Override
                    public void onPageSelected(int position) {
                        Log.i("TAG", "pos::" + position);

                    }
                    @Override
                    public void onPageScrollStateChanged(int state) {
                        // TODO Auto-generated method stub                            
                           int currentPage = pager.getCurrentItem();
                           Log.i("TAG", "currentPage::" + currentPage);
                           Log.i("TAG", "currentState::" + currentState);
                           Log.i("TAG", "previousState::" + previousState);
                           if (currentPage == 4 || currentPage == 0) {
                            previousState = currentState;
                            currentState = state;
                            if (previousState == 1 && currentState == 0) {
                             pager.setCurrentItem(currentPage == 0 ? 4 : 0);
                            }
                           }

                    }

                    @Override
                    public void onPageScrolled(int arg0, float arg1,
                            int arg2) {
                        // TODO Auto-generated method stub

                    }
                });

        return

This should be placed inside

 @Override
    public Object instantiateItem(final View container, int position) {}
陈独秀 2024-12-24 17:16:03

我是这样用的
适配器中的片段布局 0>1>2>3>4>5,
0 & 5个是虚拟的

    viewPager.setAdapter(adapter);
    viewPager.setCurrentItem(1, false);        //going to page 1;

    final int[] pagePosition = new int[1];

    viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

        }

        @Override
        public void onPageSelected(int position) {
            pagePosition[0] = position;
        }

        @Override
        public void onPageScrollStateChanged(int state) { //state changes from 2 to 0 during a swipe

            if (state == 0 && pagePosition[0] == 0){            
                viewPager.setCurrentItem(4, false);
            } else if (state == 0 && pagePosition[0] == 5){
                viewPager.setCurrentItem(1, false);
            }
        }
    });

I used it this way,
fragment layouts in adapter 0>1>2>3>4>5,
0 & 5 are dummy

    viewPager.setAdapter(adapter);
    viewPager.setCurrentItem(1, false);        //going to page 1;

    final int[] pagePosition = new int[1];

    viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

        }

        @Override
        public void onPageSelected(int position) {
            pagePosition[0] = position;
        }

        @Override
        public void onPageScrollStateChanged(int state) { //state changes from 2 to 0 during a swipe

            if (state == 0 && pagePosition[0] == 0){            
                viewPager.setCurrentItem(4, false);
            } else if (state == 0 && pagePosition[0] == 5){
                viewPager.setCurrentItem(1, false);
            }
        }
    });
感性不性感 2024-12-24 17:16:03

嗯,这有帮助

 private class CircularViewPagerHandler implements ViewPager.OnPageChangeListener {
    private ViewPager mViewPager;
    private int mCurrentPosition;
    private int mScrollState;
    private int mPreviousPosition;

    public CircularViewPagerHandler(final ViewPager viewPager) {
        mViewPager = viewPager;
    }

    @Override
    public void onPageSelected(final int position) {
        mCurrentPosition = position;
        mPreviousPosition = position-1;
    }

    @Override
    public void onPageScrollStateChanged(final int state) {
        if (state == ViewPager.SCROLL_STATE_IDLE) {
            setNextItemIfNeeded();
        }
        mScrollState = state;
    }


    private void setNextItemIfNeeded() {
        if (!isScrollStateSettling()) {
            handleSetNextItem();
        }
    }

    private boolean isScrollStateSettling() {
        return mScrollState == ViewPager.SCROLL_STATE_SETTLING; //indicated page is settling to it's final position
    }

    private void handleSetNextItem() {
        final int lastPosition = mViewPager.getAdapter().getCount() - 1;
        if (mCurrentPosition == 0) {
            mViewPager.setCurrentItem(lastPosition,false);
        } else if (mCurrentPosition == lastPosition) {
            mViewPager.setCurrentItem(0, false);
        }
    }

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

    }
}

,这是 @tobi_b 的答案

Well this helped

 private class CircularViewPagerHandler implements ViewPager.OnPageChangeListener {
    private ViewPager mViewPager;
    private int mCurrentPosition;
    private int mScrollState;
    private int mPreviousPosition;

    public CircularViewPagerHandler(final ViewPager viewPager) {
        mViewPager = viewPager;
    }

    @Override
    public void onPageSelected(final int position) {
        mCurrentPosition = position;
        mPreviousPosition = position-1;
    }

    @Override
    public void onPageScrollStateChanged(final int state) {
        if (state == ViewPager.SCROLL_STATE_IDLE) {
            setNextItemIfNeeded();
        }
        mScrollState = state;
    }


    private void setNextItemIfNeeded() {
        if (!isScrollStateSettling()) {
            handleSetNextItem();
        }
    }

    private boolean isScrollStateSettling() {
        return mScrollState == ViewPager.SCROLL_STATE_SETTLING; //indicated page is settling to it's final position
    }

    private void handleSetNextItem() {
        final int lastPosition = mViewPager.getAdapter().getCount() - 1;
        if (mCurrentPosition == 0) {
            mViewPager.setCurrentItem(lastPosition,false);
        } else if (mCurrentPosition == lastPosition) {
            mViewPager.setCurrentItem(0, false);
        }
    }

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

    }
}

It was @tobi_b's answer

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文