使用内部的NestedScrollView处理VerticalViewPager的滚动

时间:2018-04-17 12:01:02

标签: android android-viewpager scrollview android-nestedscrollview nestedscrollview

背景

我使用的是ViewPager的变体,它不是在水平方向滚动,而是在垂直方向滚动。

VerticalViewPager https://android.googlesource.com/platform/packages/apps/DeskClock/+/master/src/com/android/deskclock/VerticalViewPager.java

android.support.v4.app.FragmentStatePagerAdapter用于设置VerticalViewPager中的内容。

我每次android.support.v4.app.Fragment调用FragmentStatePagerAdapter getItem()时都会FragmentStatePagerAdapter创建并返回@Override public Fragment getItem(int position) { return PreviewFragment.getNewFragmentInstance(position); } 的新实例,如下所示:

PreviewFragment

android.support.v4.widget.NestedScrollView呈现可能不适合屏幕的内容。 为了显示不适合屏幕的所有内容,PreviewFragment用作PreviewFragment布局的父元素。

问题:

PreviewFragment的内容会按预期滚动到位置0。 但是,为了切换到下一页,必须多次执行甩动或滑动操作才能轻扫到位置1的页面。

此外,投掷或滑回位置0非常困难或几乎不可能。

必填:

投掷或滑动或切换到HTTP/1.1 200 OK Cache-Control: no-cache, no-store, max-age=0, must-revalidate Content-Length: 2951 Content-Type: application/json Date: Tue, 17 Apr 2018 06:34:03 GMT Expires: 0 Pragma: no-cache Strict-Transport-Security: max-age=3175000 ; includeSubDomains X-Content-Type-Options: nosniff X-Frame-Options: DENY X-Vcap-Request-Id: de1csd11-2721-de3a-548e-573sdt3fae22 X-Xss-Protection: 1; mode=block Connection: close 的下一个实例应该是平滑的。 换句话说,滚动内容应该是流畅的,同时请记住,滑动到下一页也应该顺利进行。

Link to the sample project as mentioned above

1 个答案:

答案 0 :(得分:6)

我查看了您的Github代码。我让它适合你。我也发送了拉取请求。问题是onInterceptTouchEvent如果返回true,则会ViewPager滚动,如果我们将其false返回,则会停用ViewPager触摸并使NestedScrollView成为NestedScrollView滚动。所以我在这里检查是否需要滚动false然后如果NestedScrollView位于顶部或底部,我将其返回true,我将其返回到VerticalViewPager。我在这里发布代码。你可以修改它并使它更干净。

Github链接 - https://github.com/karanatwal/vertical-viewpager-nestedscrollview

以下是@Override public boolean onInterceptTouchEvent(MotionEvent ev) { boolean toIntercept = super.onInterceptTouchEvent(flipXY(ev)); // Return MotionEvent to normal float x = ev.getX(); flipXY(ev); int direction=1; switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: mStartDragX = x; break; case MotionEvent.ACTION_MOVE: if (mStartDragX < x ) { direction=-1; } else if (mStartDragX > x) { direction=1; } MainActivity.MyPagerAdapter adapter = (MainActivity.MyPagerAdapter)this.getAdapter(); if (adapter.getCurrentFragment() instanceof FragmentViewPager){ FragmentViewPager fragmentViewPager = (FragmentViewPager)adapter.getCurrentFragment(); toIntercept = !fragmentViewPager.getNestedScrollView().canScrollVertically(direction); int range = fragmentViewPager.getNestedScrollView().computeVerticalScrollRange(); int offset = fragmentViewPager.getNestedScrollView().computeVerticalScrollOffset(); int extent = fragmentViewPager.getNestedScrollView().computeVerticalScrollExtent(); int percentage = (int)(100.0 * offset / (float)(range - extent)); System.out.println(" range: "+range); System.out.print(" offset: "+offset); System.out.print(" extent: "+extent); System.out.print(" percentage: "+percentage); System.out.print(" direction: "+direction); if (fragmentViewPager.getNestedScrollView().computeVerticalScrollOffset()==0 && direction==-1){ //top return true; } else if (percentage>99 && direction==1){ //bottom return true; }else { //scroll nestedscrollview return false; } } break; } return toIntercept; } 代码 -

MyPagerAdapter

您的public class MyPagerAdapter extends FragmentStatePagerAdapter { public MyPagerAdapter(FragmentManager fm) { super(fm); } private Fragment mCurrentFragment; public Fragment getCurrentFragment() { return mCurrentFragment; } //... @Override public void setPrimaryItem(ViewGroup container, int position, Object object) { if (getCurrentFragment() != object) { mCurrentFragment = ((Fragment) object); } super.setPrimaryItem(container, position, object); } @Override public android.support.v4.app.Fragment getItem(int pos) { switch (pos) { case 0: return FragmentViewPager.newInstance("Title Start", R.drawable.ic_launcher_background); case 1: return FragmentViewPager.newInstance("Rock", R.drawable.rock); case 2: return FragmentViewPager.newInstance("Paper", R.drawable.paper); case 3: return FragmentViewPager.newInstance("Scissors", R.drawable.scissors); case 4: return FragmentViewPager.newInstance("Title End", R.drawable.ic_launcher_background); default: return FragmentViewPager.newInstance("Default Title", R.drawable.rock); } } @Override public int getCount() { return 5; } } -

 //offset , range and extent
            int scrollY = scrollView.getScrollY();               
            int scrollContentHeight = scrollView.getChildAt(0).getHeight();
            int screenHeight = Utility.getScreenHeight(context); 
            int statusBarHeight = Utility.getStatusBarHeight(context);

            double percent = ((((float) scrollY) / ((float) (scrollContentHeight - screenHeight + statusBarHeight))));

为避免受限制的API方法 - 将以下逻辑用作备用

SQLite database

您需要的只是百分比滚动和方向的滑动。有关SO的更多问题,可以查找滚动百分比和滑动方向,例如thisthis。你应该为它做一点R&amp; D.