I have a 'page' that has a number of components on it, and who's content is longer than the height of the device. Fine, just put all of the layout (the entire page) inside a ScrollView
, no problem.
One of the components is a ViewPager
. This renders correctly, but the response to a swipe/fling is not performing correctly, it is jittery and doesn't always work. It seems to be getting 'confused' with the ScrollView
, so only works 100% when you fling in an exact horizontal line.
If I remove the ScrollView
, the ViewPager responds perfectly.
I've had a search around and have not found this as a known defect. Has anyone else experienced this?
Below is some example code for you to test with, comment out ScrollView
to see it working correctly.
Activity:
package com.ss.activities; import com.ss.R; import android.app.Activity; import android.content.Context; import android.graphics.Color; import android.os.Bundle; import android.os.Parcelable; import android.support.v4.view.PagerAdapter; import android.support.v4.view.ViewPager; import android.view.View; import android.widget.TextView; public class PagerInsideScollViewActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); ViewPager vp = (ViewPager) findViewById(R.id.viewpager); vp.setAdapter(new MyPagerAdapter(this)); } } class MyPagerAdapter extends PagerAdapter { private Context ctx; public MyPagerAdapter(Context context) { ctx = context; } @Override public int getCount() { return 2; } @Override public Object instantiateItem(View collection, int position) { TextView tv = new TextView(ctx); tv.setTextSize(50); tv.setTextColor(Color.WHITE); tv.setText("SMILE DUDE, SMILE DUDE, SMILE DUDE, SMILE DUDE, SMILE DUDE, " + "SMILE DUDE, SMILE DUDE, SMILE DUDE, SMILE DUDE, SMILE DUDE, " + "SMILE DUDE, SMILE DUDE, SMILE DUDE, SMILE DUDE, SMILE DUDE, " + "SMILE DUDE, SMILE DUDE, SMILE DUDE"); ((ViewPager) collection).addView(tv); return tv; } @Override public void destroyItem(View collection, int position, Object view) { ((ViewPager) collection).removeView((View) view); } @Override public boolean isViewFromObject(View view, Object object) { return view == object; } @Override public Parcelable saveState() { return null; } @Override public void restoreState(Parcelable arg0, ClassLoader arg1) { } @Override public void startUpdate(View arg0) { } @Override public void finishUpdate(View arg0) { } }
Layout:
<?xml version="1.0" encoding="utf-8"?> <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" > <LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <android.support.v4.view.ViewPager android:id="@+id/viewpager" android:layout_width="fill_parent" android:layout_height="300dp" /> </LinearLayout> </ScrollView>
Yes it is possible to have viewpager inside scrollview. Use below code and you will achieve your goal, i have done the same in my code as well. Hope this aids someone in resolving scroll issues with nested ViewPager within a ScrollView. Show activity on this post.
Using NestedScrollView is not a good practice as the nested scroll view uses lot of memory and processing power which will slow your application, if you want to test this please use old version android phone with less memory.
With a ViewPager, you can capture page-change events and prevent the ScrollView from intercepting the touch event that caused the page change. This is very simple, using ViewGroup.requestDisallowInterceptTouchEvent(boolean).
I had the same problem. My solution was to call requestDisallowInterceptTouchEvent
when the ViewPager scroll started.
Here is my code:
pager.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { v.getParent().requestDisallowInterceptTouchEvent(true); return false; } }); pager.setOnPageChangeListener(new SimpleOnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { pager.getParent().requestDisallowInterceptTouchEvent(true); } });
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With