16

I have multiple HorizontalScrollViews inside a ScrollView. Horizontal scroll isn't smooth at all. I have to scroll almost perfectly horizontally for scrolling to work. Is there a simple fix to tweak this ??? Thanks!

Multiple HorizontalScrollViews inside a single ScrollView

Community
  • 1
  • 1
vladexologija
  • 6,857
  • 4
  • 29
  • 28

6 Answers6

8

You can use Recycler view with Staggered layout manager

 StaggeredGridLayoutManager  staggeredGridLayoutManager = new StaggeredGridLayoutManager(4, StaggeredGridLayoutManager.HORIZONTAL);

 RecyclerViewAdapter recyclerViewAdapter = newRecyclerViewAdapter(this);

 recyclerView.setAdapter(recyclerViewAdapter); //Don't miss to initialize your adapter
Yousef Zakher
  • 1,634
  • 15
  • 18
4

This class creates a ScrollView containing a HorizontalScrollView combined into one class. You can put stuff inside it using the AddChild() method. The dispatchTouchEvent overide keeps the scrolling smooth so you can pan around with a single slide of the finger.

(I recently used this to wrap a programmatically created TextView)

class MultiScrollView extends ScrollView
{           
 public HorizontalScrollView hscroll;

 public MultiScrollView ( Context context ) 
 { 
   super( context );
 }

 public void AddChild( View child ) 
 {                                              
   hscroll.addView( child );
 }

 @Override
 public boolean dispatchTouchEvent( MotionEvent event ) 
 {
   hscroll.dispatchTouchEvent(event);
   onTouchEvent(event);
   return true;
 }
}
David
  • 452
  • 5
  • 8
2

If you are using the horizontal scroll view solution from (http://www.dev-smart.com/archives/34) the solution for the cross focus problem between the scroll view and the list view is blocking the focus to the scroll view once you have focus on the list view.

From a technical point of view you should add the following line to the onScroll function inside the HorizontalListView class.

getParent().requestDisallowInterceptTouchEvent(true);

Hope this helps.

EyalBellisha
  • 1,874
  • 19
  • 28
Ailon V
  • 31
  • 2
1

I've found the solution and still can't believe that this is what you have to do to make this work normal! Just added blank onClickListener to the each item in the HorizontalScrollView:

    item.setOnClickListener(new OnClickListener() {         
        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
        }
    });

After this slide is really smooth, both upwards and downwards.

vladexologija
  • 6,857
  • 4
  • 29
  • 28
  • 1
    if this is the case you can probably put `android:clickable="true"` in your list item root XML, instead of in code. – ataulm Feb 03 '14 at 07:21
0

In general, you shouldn't be using nested ScrollViews in Android at all, the behaviour of scrolling in this way is unnatural too.

You may want to rethink your layout design, is it anything that couldn't be achieved with an expandable list?

Guykun
  • 2,780
  • 23
  • 28
  • If you are 100% adamant about this though, take a look at the solution in: http://stackoverflow.com/questions/2646028/android-horizontalscrollview-within-scrollview-touch-handling?rq=1 – Guykun Aug 22 '12 at 14:39
  • I'm trying to implement this pattern: http://www.androidpatterns.com/uap_pattern/scrollable-rows – vladexologija Aug 22 '12 at 14:42
0

While David's answer works, it has a downside. It passes ScrollView's MotionEvent object directly to HorizontalScrollView.onTouchEvent(), so if HorizontalScrollView or its children try to get the event coordinates, they will get the wrong coordinates which based on ScrollView.

My solution:

public class CustomScrollView extends ScrollView{

    /*************skip initialization*************/

    @Override
    public boolean onInterceptTouchEvent(MotionEvent e){
        //returning false means ScrollView is not interested at any events,
        //so ScrollView's onTouchEvent() won't be called,
        //and all of the events will be passed to ScrollView's child
        return false;
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        //manually call ScrollView's onTouchEvent(),
        //the vertical scrolling happens there.
        onTouchEvent(ev);
        //dispatch the event,
        //ScrollView's child will have every event.
        return super.dispatchTouchEvent(ev);
    }
}

Just wrap this CustomScrollView around the HorizontalScrollView in your layout file.

handhand
  • 736
  • 7
  • 12
  • I'm getting this `Binary XML file line #266: Error inflating class com.booklibrary.shared.view.CustomScrollView` error after doing. And also asks for Default Constructor otherwise there is compile error. – Sadman Samee Nov 15 '18 at 09:41