I've been trying to figure out the behavior of MotionEvents in ScrollViews in Android and there's something i can't figure out.
As an example I made an Activity that has a ScrollView inside of it and the ScrollView has a LinearLayout inside of it. I implemented my own classes to have control over the touch-related functions:
public class MainActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); MyInnerLayout inner = new MyInnerLayout(getApplicationContext()); MyLayout layout = new MyLayout(getApplicationContext()); layout.addView(inner,new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT)); setContentView(layout); } @Override public boolean dispatchTouchEvent(MotionEvent ev) { Log.i("scrollview","activity dispatchTouchEvent "+ev.getAction()); return super.dispatchTouchEvent(ev); }; @Override public boolean onTouchEvent(MotionEvent ev) { Log.i("scrollview","activity on touch "+ev.getAction()); return super.onTouchEvent(ev); } public class MyLayout extends ScrollView { public MyLayout(Context context) { super(context); } @Override public boolean dispatchKeyEvent(KeyEvent ev) { Log.i("scrollview","layout dispatchKeyEvent "+ev.getAction()); return super.dispatchKeyEvent(ev); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { Log.i("scrollview","layout onInterceptTouchEvent "+ev.getAction()); return false; } @Override public boolean onTouchEvent(MotionEvent ev) { Log.i("scrollview","layout on touch "+ev.getAction()); return false; } } public class MyInnerLayout extends LinearLayout{ public MyInnerLayout(Context context) { super(context); } @Override public boolean dispatchTouchEvent(MotionEvent ev) { Log.i("scrollview","inner layout dispatchTouchEvent "+ev.getAction()); return true; } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { Log.i("scrollview","inner layout onInterceptTouchEvent "+ev.getAction()); return true; } @Override public boolean onTouchEvent(MotionEvent ev) { Log.i("scrollview","inner layout on touch "+ev.getAction()); return true; } } } When I click anywhere on the screen I get this log:
10-14 18:11:48.631: I/scrollview(14906): activity dispatchTouchEvent 0 10-14 18:11:48.631: I/scrollview(14906): layout onInterceptTouchEvent 0 10-14 18:11:48.631: I/scrollview(14906): layout on touch 0 10-14 18:11:48.631: I/scrollview(14906): activity on touch 0 10-14 18:11:48.647: I/scrollview(14906): activity dispatchTouchEvent 1 10-14 18:11:48.647: I/scrollview(14906): activity on touch 1 that means that the touch event didn't make the way down to the inner layout inside the scrollview. however when I change the ScrollView to a LinearLayout (simply just change it in the extends), the event goes down to the inner layout:
10-14 18:24:08.975: I/scrollview(15115): activity dispatchTouchEvent 0 10-14 18:24:08.975: I/scrollview(15115): layout onInterceptTouchEvent 0 10-14 18:24:08.975: I/scrollview(15115): inner layout dispatchTouchEvent 0 10-14 18:24:09.045: I/scrollview(15115): activity dispatchTouchEvent 1 10-14 18:24:09.045: I/scrollview(15115): layout onInterceptTouchEvent 1 10-14 18:24:09.045: I/scrollview(15115): inner layout dispatchTouchEvent 1 I looked in the source code of the ScrollView class and the only touch-related methods that it overrides are the ones I overrided myself. So I don't understand what makes the difference between the behavior of the LinearLayout and the ScrollView.