Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ViewPager inside a ScrollView does not scroll correclty

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?

  • Platform Version: 1.6
  • Compatibility Library v4.
  • Device: HTC Incredible S

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> 
like image 814
electricSunny Avatar asked Dec 05 '11 06:12

electricSunny


People also ask

Is it possible to have viewpager inside 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.

Is nestedscrollview a good practice in Android?

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.

How do I prevent ScrollView from intercepting touch events?

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).


1 Answers

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);     } }); 
like image 99
The Finest Artist Avatar answered Oct 13 '22 01:10

The Finest Artist