垂直ViewPager,具有流畅的滚动和页面转换(如inshorts应用程序)

时间:2019-06-28 14:01:12

标签: android android-fragments android-viewpager fragmentpageradapter

我想制作一个垂直ViewPager短裤应用程序。

我尝试了堆栈溢出 Github 中找到的几种解决方案。 它们全都具有相同的代码实现方式,并且在video中都可以看到它们在向上滚动和向下滚动(垂直滚动)时都存在相同的滞后问题,但是设计实现与< strong>短裤。

我尝试过的链接是

1)VerticalViewPager

2)DirectionViewPager

3)Github Repos

我还尝试了从Android的 Viewpager 类中获取 mFlingDistance,mMinimumVelocity 等,以增加Viewpager中的掠夺。但是没有运气。

下面是我的 VerticalViewPager

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

并使用 VerticaPageTransformer 类进行页面转换。

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

        }

    }

对我有用的是castorflex解决方案,用于平滑滚动,但是当我将PageTransformer应用于castorflex解决方案时,而不是垂直滚动是对角滚动。您可以在此处看到reference video

我也尝试过使用ViewPager2和RecyclerView(使用SnapHelper),但是使用 viewpager2 时,遇到了同样的对角线问题。借助Snaphelper,我无法提供像短裤一样的页面效果(请参阅视频)。如我所见,here可能是RecyclerView的 LinearLayoutManager 实现的。但是无法转换我的页面动画。

任何人都可以给我任何提示或任何想法

1)如何通过上述方法使滚动平滑?或

2)如何从下面的方法而不是对角线过渡到垂直页面?或

3)或其他任何方式。

预先感谢

您可以看到Castorflex's VerticalViewPager 类,并使用相同的 VerticlePageTransform 类进行页面转换

1 个答案:

答案 0 :(得分:-1)

  

检查此Github存储库 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);
    }
}