Viewpager Scroll问题中的Viewpager

时间:2018-06-07 09:33:40

标签: android android-fragments android-viewpager

在我的主要活动中,我有一个水平的viewpager。在viewpager的一个片段里面,我有另一个垂直的viewpager。两者都很好。但对于水平viewpager,我需要从屏幕的边缘滚动。但是我想让它从屏幕上的任何地方滚动。

我的水平viewpager设置:

public class HorizontalViewPagerAdapter extends FragmentPagerAdapter {
    private static int NUM_ITEMS = 3;

    public HorizontalViewPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int position) {
        switch (position) {
            case 0:
                return MoreFragment.newInstance("Fragment MoreFragment", "HA HA HA");
            case 1:
                return NewsFragment.newInstance("Fragment 1", "HA HA HA");
            case 2:
                return WebViewFragment.newInstance("Fragment Webview", "HA HA HA");
            default:
                return null;
        }
    }

    @Override
    public int getCount() {
        return NUM_ITEMS;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return "Tab " + position;
    }
}

水平viewpager适配器:

viewPager = view.findViewById(R.id.shortpager);
        adapterViewPager = new VerticalPagerAdapter(getActivity().getSupportFragmentManager(), newsList);
        viewPager.setAdapter(adapterViewPager);

在我的新闻片段中,我有另一个viewpager。

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

    private 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/top page
                view.setAlpha(1);
                ViewCompat.setElevation(view, 1);
                // Counteract the default slide transition
                view.setTranslationX(view.getWidth() * -position);
                view.setTranslationY(0);

                //set Y position to swipe in from top
                float scaleFactor = MIN_SCALE + (1 - MIN_SCALE) * (1 - Math.abs(position));
                view.setScaleX(scaleFactor);
                view.setScaleY(scaleFactor);

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

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

                // Scale the page down (between MIN_SCALE and 1)
                view.setScaleX(1);
                view.setScaleY(1);

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

        }
    }

}

我的垂直viewpager类:

public class VerticalPagerAdapter extends FragmentPagerAdapter {
    private static int NUM_ITEMS = 3;
    private final ArrayList<News> newsList;

    public VerticalPagerAdapter(FragmentManager fm, ArrayList<News> newsList) {
        super(fm);
        this.newsList = newsList;
    }

    @Override
    public Fragment getItem(int position) {
        return ShortFragment.newInstance("Fragment 1", "HA HA HA", newsList.get(position));
    }

    @Override
    public int getCount() {
        return this.newsList.size();
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return "Tab " + position;
    }
}

垂直viewpager适配器:

{{1}}

垂直viewpager顺畅滚动。目前对于水平viewpager,我必须从屏幕的边缘滚动。但我需要让它像屏幕上任何地方的垂直滚动一样滚动。

2 个答案:

答案 0 :(得分:0)

您的代码问题是VerticalViewPager

如果您注意到代码,

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

步骤1,用交换手势调用super 步骤2,使用当前手势对垂直视图寻呼机执行操作。

如果您特别看到评论,// return touch coordinates to original reference frame for any child views这清楚地表明手势首先由孩子消费。

因此,在您的垂直视图寻呼机中,因为您正在交换手势,所以即使在将水平手势传递给父手势之前也会消耗它。这就是你的水平视图寻呼机没有得到手势的原因。

如果您使用垂直视图寻呼机与任何冲突的手势实现,如ScrollView,Lists,RecyclerView,ViewPager等,请使用下面链接中的一个。它已被弃用,但适用于所有手势冲突视图。

https://github.com/kaelaela/VerticalViewPager

答案 1 :(得分:0)

我遇到了这个问题,并通过将viewpager包装在Scrollview中解决了该问题

static