How to Implement the interaction between two ViewPager and achieve the interaction between viewpager

Source: Internet
Author: User

How to Implement the interaction between two ViewPager and achieve the interaction between viewpager

I have written an article about how to implement zaker5.0's guiding interface. For details, see view interaction effect (modify viewpager implementation) of zaker's latest guide interface ), this article is a continuation of the article.

Let's take a look at the final effect:


Linkage ViewPager means that when a viewpager slides, another ViewPager also slides, and the two are synchronized.

If ViewPager has a callback interface for moving distance, this is easy to do. Unfortunately, there is no callback interface. There is only one OnPageChangeListener. I tried using onPageScrolled (int position, float positionOffset, int positionOffsetPixels.

Then only custom ViewPager is available.

I directly extract the source code of ViewPager to v4 and remove unnecessary things until the class cannot be found,

In addition to ViewPager, you also need to take out the relevant PagerAdapter class. Otherwise, ViewPager uses its own and adapter uses v4, which may cause problems.

Add a private variable to ViewPager to achieve interaction.mFollowViewPager(Add the set Method of the variable at the same time ):

private ViewPager mFollowViewPager;public  void setFlolwViewPager(ViewPager page){mFollowViewPager = page;}
My idea is to call mFollowViewPagerScrollTo method. So where can I add it? After carefully tracking the ViewPager behavior, I found that when the finger is not released, the mongomdrag method handles the relevant movement, he calls his own scrollTo to implement its own translation. Therefore, we only need to add the following code in the mongomdrag method:
//add by jcodecraeerfinal float pageOffset =  scrollX / width;if(mFollowViewPager!=null){mFollowViewPager.scrollTo( (int)(pageOffset*mFollowViewPager.getWidth()), mFollowViewPager.getScrollY());}

Note that it is not how far the main ViewPager is moved,mFollowViewPagerHow far is the movement, because the width of the two ViewPager may be different, so you need to convert it. In the code abovefinal float pageOffset =  scrollX / width;pageOffset
Only the obtained values are converted.

ModifiedperformDragAs follows:

    private boolean performDrag(float x) {        boolean needsInvalidate = false;        final float deltaX = mLastMotionX - x;        mLastMotionX = x;                float oldScrollX = getScrollX();        float scrollX = oldScrollX + deltaX;        final int width = getWidth();        float leftBound = width * mFirstOffset;        float rightBound = width * mLastOffset;        boolean leftAbsolute = true;        boolean rightAbsolute = true;        final ItemInfo firstItem = mItems.get(0);        final ItemInfo lastItem = mItems.get(mItems.size() - 1);        if (firstItem.position != 0) {            leftAbsolute = false;            leftBound = firstItem.offset * width;        }        if (lastItem.position != mAdapter.getCount() - 1) {            rightAbsolute = false;            rightBound = lastItem.offset * width;        }        if (scrollX < leftBound) {            if (leftAbsolute) {                float over = leftBound - scrollX;                needsInvalidate = mLeftEdge.onPull(Math.abs(over) / width);            }            scrollX = leftBound;        } else if (scrollX > rightBound) {            if (rightAbsolute) {                float over = scrollX - rightBound;                needsInvalidate = mRightEdge.onPull(Math.abs(over) / width);            }            scrollX = rightBound;        }        // Don't lose the rounded component        mLastMotionX += scrollX - (int) scrollX;        scrollTo((int) scrollX, getScrollY());        pageScrolled((int) scrollX);        //add by jcodecraeerfinal float pageOffset =  scrollX / width;if(mFollowViewPager!=null){mFollowViewPager.scrollTo( (int)(pageOffset*mFollowViewPager.getWidth()), mFollowViewPager.getScrollY());}        return needsInvalidate;    }

It is not enough to translate the processed finger without leaving the screen. When the finger is released, ViewPager will continue for a certain distance. Therefore, mFollowViewPager should also be moved, whether the finger is released in case MotionEvent. what is processed in ACTION_UP?

Find the relevant code:

case MotionEvent.ACTION_UP:    if (mIsBeingDragged) {        final VelocityTracker velocityTracker = mVelocityTracker;        velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);        int initialVelocity = (int) VelocityTrackerCompat.getXVelocity(                velocityTracker, mActivePointerId);        mPopulatePending = true;        final int width = getWidth();        final int scrollX = getScrollX();        final ItemInfo ii = infoForCurrentScrollPosition();        final int currentPage = ii.position;        final float pageOffset = (((float) scrollX / width) - ii.offset) / ii.widthFactor;        final int activePointerIndex =                MotionEventCompat.findPointerIndex(ev, mActivePointerId);        final float x = MotionEventCompat.getX(ev, activePointerIndex);        final int totalDelta = (int) (x - mInitialMotionX);        int nextPage = determineTargetPage(currentPage, pageOffset, initialVelocity,                totalDelta);        setCurrentItemInternal(nextPage, true, true, initialVelocity);                                                                     mActivePointerId = INVALID_POINTER;        endDrag();        needsInvalidate = mLeftEdge.onRelease() | mRightEdge.onRelease();    }
We can see that setCurrentItemInternalMediumCalled ScrollToItem (item, smoothScroll, velocity, dispatchSelected. That is to say,mFollowViewPagerIf we callsetCurrentItemInternalSo that he can also move. Based on this idea, we will rewrite the code segment of case MotionEvent. ACTION_UP:
case MotionEvent.ACTION_UP:    if (mIsBeingDragged) {        final VelocityTracker velocityTracker = mVelocityTracker;        velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);        int initialVelocity = (int) VelocityTrackerCompat.getXVelocity(                velocityTracker, mActivePointerId);        mPopulatePending = true;        final int width = getWidth();        final int scrollX = getScrollX();        final ItemInfo ii = infoForCurrentScrollPosition();        final int currentPage = ii.position;        final float pageOffset = (((float) scrollX / width) - ii.offset) / ii.widthFactor;        final int activePointerIndex =                MotionEventCompat.findPointerIndex(ev, mActivePointerId);        final float x = MotionEventCompat.getX(ev, activePointerIndex);        final int totalDelta = (int) (x - mInitialMotionX);        int nextPage = determineTargetPage(currentPage, pageOffset, initialVelocity,                totalDelta);        setCurrentItemInternal(nextPage, true, true, initialVelocity);        //add by jcodecraeer        if(mFollowViewPager!=null){            mFollowViewPager.setCurrentItemInternal(nextPage, true, true, initialVelocity);        }        mActivePointerId = INVALID_POINTER;        endDrag();        needsInvalidate = mLeftEdge.onRelease() | mRightEdge.onRelease();    }


So far, we have completed all the modifications, but we have not actually changed a few lines.

So how can we use the modified ViewPager in the activity to link two viewpagers? Assume that one is mViewPager and the other is mFollowViewPager.mFollowViewPagerWithmViewPagerDynamic, then:

mPager.setFollowViewPager(mFollowViewPager);

Note that in the demo I will give next, I blocked followViewPagerTo overwrite the main ViewPager in Above followViewPager, which is consistent with the effect I want to achieve. If you wantfollowViewPagerIn turn, the main ViewPager can also be moved and called in turn:

MFollowViewPager. setFollowViewPager (mPager );

However, I am not sure whether this two-way call will cause problems, because I have not strictly consideredmFollowViewPagerSome state changes (such as related variables) that should be caused by moving the variable ). You can give it a try and then make improvements.


Source code: http://jcodecraeer.com/a/opensource/2014/1031/1885.html


Add by jcodecraeer labels are used for ViewPager Transformation (excluding unnecessary code to delete)

There are only two ViewPager items, and the two items have operations such as networking and input boxes. How can we achieve circular sliding?

New Employee reports. view the original post>

How to Implement nested ViewPager

Grace, but you 'd better rewrite the title above ViewPager. More beautiful
 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.