3

I wanted to make a Vertical ViewPager looklike inshorts application.

I have tried several solutions found on Stack Overflow and in Github. All of them have the same way of implementation of code, and all of them have the same lagging issue while scrolling up and down(vertical scroll), you can see in the video, but the design implementation is same as inshorts.

The link which I have tried are,

1) VerticalViewPager

2) DirectionViewPager

3) Github Repos

I have also tried for mFlingDistance,mMinimumVelocity etc from android's Viewpager class for increasing fling in Viewpager. But with no luck of making it working.

Below is my VerticalViewPager class

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

    /**
     * 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));
    }
}

And using VerticaPageTransformer class for page transition.

class VerticalPageTransformer implements ViewPager.PageTransformer {
     private static final float MIN_SCALE = 0.75f;
        @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 <= 0) { // [-1,0]
                // Use the default slide transition when moving to the left page
                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);
                view.setScaleX(1);
                view.setScaleY(1);

            } else if (position <= 1) { // [0,1]
                view.setAlpha(1);

                // Counteract the default slide transition
                view.setTranslationX(view.getWidth() * -position);


                // Scale the page down (between MIN_SCALE and 1)
                float scaleFactor = MIN_SCALE
                        + (1 - MIN_SCALE) * (1 - Math.abs(position));
                view.setScaleX(scaleFactor);
                view.setScaleY(scaleFactor);

            } else { // (1,+Infinity]
                // This page is way off-screen to the right.
                view.setAlpha(0);
            }

        }

    }

The one that worked for me was of castorflex solution for smooth scrolling, but when I apply a PageTransformer to castorflex solution, instead of scrolling vertically is scroll diagonally.You can see the reference video here.

I have also tried with ViewPager2 and with RecyclerView(with SnapHelper) but with viewpager2, I am getting the same diagonal issue. And with Snaphelper, I am unable to provide a page effect like inshorts(see the videos). May be, it will be possible by LinearLayoutManager of RecyclerView, as I have seen here. But failed to convert my page animation.

So anyone can give me any hint, or any idea about

1) How to make smooth scrolling with above approach? or

2) How to make vertical page transition from below approach, instead of diagonal? or

3) Or any other way if you people have.

Thanks in advance

You can see Castorflex's VerticalViewPager class, and using the same VerticlePageTransform class for page transformation

Ranjan
  • 1,326
  • 18
  • 38
  • There was a recent post about using `MotionLayout` for swipe behavior. https://badootech.badoo.com/swipe-right-on-motion-layout-641c1452d6a5 Maybe something along that line works for you. – Froyo Jul 08 '19 at 20:49
  • Yes, but its is horizontal and there is stack animation. And I want animation like inShorts. – Ranjan Jul 09 '19 at 05:08
  • Change the direction from Horizontal to Vertical. – Froyo Jul 09 '19 at 05:56
  • I am seeing that only, but there is two problem, one is fling(like viewpager,or recyclerview snap helper) and the other one is inshorts like animation. – Ranjan Jul 09 '19 at 06:11

1 Answers1

0

Check this Github Repo https://github.com/dipanshukr/Viewpager-Transformation


SampleActivity.java

private void initViewPager() {
    VerticalViewPager viewPager = (VerticalViewPager) findViewById(R.id.vertical_viewpager);
    //viewPager.setPageTransformer(false, new ZoomOutTransformer());
    //viewPager.setPageTransformer(true, new StackTransformer());
    String title = "ContentFragment";
    viewPager.setAdapter(new ContentFragmentAdapter.Holder(getSupportFragmentManager())
            .add(ContentFragment.newInstance(title, 1))
            .add(ContentFragment.newInstance(title, 2))
            .add(ContentFragment.newInstance(title, 3))
            .add(ContentFragment.newInstance(title, 4))
            .add(ContentFragment.newInstance(title, 5))
            .set());
    // If you setting other scroll mode,
    // the scrolled fade is shown from either side of display.
    viewPager.setOverScrollMode(View.OVER_SCROLL_NEVER);
}

VerticalViewPager.java

public class VerticalViewPager extends ViewPager {

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

    public VerticalViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
        setPageTransformer(false, new DefaultTransformer());
    }

    private MotionEvent swapTouchEvent(MotionEvent event) {
        float width = getWidth();
        float height = getHeight();

        float swappedX = (event.getY() / height) * width;
        float swappedY = (event.getX() / width) * height;

        event.setLocation(swappedX, swappedY);

        return event;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        boolean intercept = super.onInterceptTouchEvent(swapTouchEvent(event));
        //If not intercept, touch event should not be swapped.
        swapTouchEvent(event);
        return intercept;
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        return super.onTouchEvent(swapTouchEvent(ev));
    }
}

DefaultTransformer.java

public class DefaultTransformer implements ViewPager.PageTransformer {

    @Override
    public void transformPage(View view, float position) {
        float alpha = 0;
        if (0 <= position && position <= 1) {
            alpha = 1 - position;
        } else if (-1 < position && position < 0) {
            alpha = position + 1;
        }
        view.setAlpha(alpha);
        view.setTranslationX(view.getWidth() * -position);
        float yPosition = position * view.getHeight();
        view.setTranslationY(yPosition);
    }
}
Arindam Karmakar
  • 156
  • 1
  • 2
  • 11
  • Your vertical view pager is also same as others, as they all suffer lagging if used inside an other view pager(like vertical in horizontal). I have also written it in the question itself, have a look into it. – Ranjan Jul 10 '19 at 08:37