Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
275 views
in Technique[技术] by (71.8m points)

android - Implementing Circular Scrolling In PagerAdapter

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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);

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...