i go through your Github code. I made it work for you. I have sent a pull request too. Problem was that onInterceptTouchEvent
if returned true
it makes ViewPager
to scroll and if we return it false
it disable ViewPager
touch and make NestedScrollView
to scroll. So here i did was to check if NestedScrollView
needs to be scrolled then i returned it false
if NestedScrollView
is on top or bottom, I returned it to true
. I am posting code here. You can modify it and make it more clean.
Github Link - https://github.com/karanatwal/vertical-viewpager-nestedscrollview
Below is VerticalViewPager
code -
@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;
}
Your 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;
}
}
For avoiding Restricted API methods- Use below logic as a alternate
//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))));
All you need is percentage of scroll and direction of swipe. There are alot more questions on SO for finding scroll percentage and swipe direction like this and this. You should do little R&D for it.