Vertically scrolling ViewPager--VerticalViewPager

Keywords: Android github network

VerticalViewPager a vertical scrolling ViewPager

Inherited from ViewPager, it has the same usage as ViewPager, including adapter, listening, but the sliding direction is different.

Occasionally, we will find that viewpager wants to slide vertically, but the official doesn't provide a method. We found this on stack overflow, which can perfectly fulfill our requirements. Let's make a record here

Maybe we will meet what we have achieved

VerticalViewPager github get

Dynamic graph from network


The following is the specific implementation:

As shown below, it is actually to use setPageTransformer to change the display effect of each item, plus setOverScrollMode(OVER_SCROLL_NEVER)

See the code for details, which can be used directly after copying

    /**
     * Created by yukun on 17-12-12.
     */
    
    public class VerticalViewPager extends ViewPager {
        public VerticalViewPager(Context context) {
            super(context);
            init();
        }
    
        public VerticalViewPager(Context context, AttributeSet attrs) {
            super(context, attrs);
            init();
        }
    
        private void init() {
            // The majority of the magic happens here
            //Set setPageTransformer to achieve vertical sliding
            setPageTransformer(true, new VerticalPageTransformer());
            // The easiest way to get rid of the overscroll drawing that happens on the left and right
            setOverScrollMode(OVER_SCROLL_NEVER);
        }
    
        private class VerticalPageTransformer implements ViewPager.PageTransformer {
    
            @Override
            public void transformPage(View view, float position) {
    
                if (position < -1) { // [-Infinity,-1)
                    // This page is way off-screen to the left.
                    view.setAlpha(0);
    
                } else if (position <= 1) { // [-1,1]
                    view.setAlpha(1);
    
                    // Counteract the default slide transition
                    view.setTranslationX(view.getWidth() * -position);
    
                    //set Y position to swipe in from top
                    float yPosition = position * view.getHeight();
                    view.setTranslationY(yPosition);
    
                } else { // (1,+Infinity]
                    // This page is way off-screen to the right.
                    view.setAlpha(0);
                }
            }
        }
    
        /**
         * Swaps the X and Y coordinates of your touch event.
         */
        private MotionEvent swapXY(MotionEvent ev) {
            float width = getWidth();
            float height = getHeight();
    
            float newX = (ev.getY() / height) * width;
            float newY = (ev.getX() / width) * height;
    
            ev.setLocation(newX, newY);
    
            return ev;
        }
    
        @Override
        public boolean onInterceptTouchEvent(MotionEvent ev){
            boolean intercepted = super.onInterceptTouchEvent(swapXY(ev));
            swapXY(ev); // return touch coordinates to original reference frame for any child views
            return intercepted;
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent ev) {
            return super.onTouchEvent(swapXY(ev));
        }
    }

It is mainly the following method, which can realize the effects of various item s, including transparency, reduction, etc

    private class VerticalPageTransformer implements ViewPager.PageTransformer {
            
                    @Override
                    public void transformPage(View view, float position) {
            
                        if (position < -1) { // [-Infinity,-1)
                            // This page is way off-screen to the left.
                            view.setAlpha(0);
            
                        } else if (position <= 1) { // [-1,1]
                            view.setAlpha(1);
            
                            // Counteract the default slide transition
                            view.setTranslationX(view.getWidth() * -position);
            
                            //set Y position to swipe in from top
                            float yPosition = position * view.getHeight();
                            view.setTranslationY(yPosition);
            
                        } else { // (1,+Infinity]
                            // This page is way off-screen to the right.
                            view.setAlpha(0);
                        }
                    }
                }

Here's a zoomed out viewpager animation

The effect is similar to that of the following image, which can deepen the understanding of PageTransformer.

From Jianshu

The usage is very simple. Copy directly:

 <com.yk.myselfview.views.VerticalViewPager 
        android:layout_width="match_parent"
        android:layout_centerInParent="true"
        android:id="@+id/vertical_viewpager"
        android:layout_height="240dp">
 </com.yk.myselfview.views.VerticalViewPager>

code:

mVerticalViewPager = (VerticalViewPager) findViewById(R.id.vertical_viewpager);
//Adapter
VerticalViewpagerAdapter verticalViewpagerAdapter=new VerticalViewpagerAdapter(this,mList);
        mVerticalViewPager.setAdapter(verticalViewpagerAdapter);

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

            }

            @Override
            public void onPageSelected(int position) {
                Toast.makeText(VerticalViewPagerActivity.this, "position:"+position, Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });

Adapter

    /**
     * Created by yukun on 17-12-12.
     */
    
    public class VerticalViewpagerAdapter extends PagerAdapter {
    
        private Context mContext;
        private List<Integer> mList;
    
        public VerticalViewpagerAdapter(Context mContext, List<Integer> list) {
            this.mContext = mContext;
            mList = list;
        }
    
        @Override
        public int getCount() {
            return mList.size();
        }
    
        @Override
        public boolean isViewFromObject(View view, Object object) {
            return view==object;
        }
    
        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            ImageView imageView=new ImageView(mContext);
            imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
            imageView.setImageResource(mList.get(position));
            container.addView(imageView);
            return imageView;
        }
    
        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            container.removeView((View)object);
        }
    }

Posted by hush2 on Sun, 31 May 2020 00:55:56 -0700