title: Stick a horizontalScrollView and capture touch events
body: <p>I'm trying to reproduce the profile screen of the G+ Android app. In this screen, you can notice a horizontalScrollView containing tabs, which sticks at the top the screen.</p>
  
  <p>The screen is made of a list, containing a HeaderView (ImageBackground, avatar, informations and tabs), and the list (cards). </p>
  
  <p>I am able to make the tabs stick to the top and capture touch events, but the fling effect doesn't work anymore when the header fully disappear from the top (&lt;=> if the firstVisible item of the <code>listview</code> is not the header). I am able to touch and move the <code>HorizontalScrollView</code>, it works until I try to fling. </p>
  
  <p><code>Fling OK:</code></p>
  
  <p><img src="https://i.stack.imgur.com/mWYPe.png" alt="FLING OK"></p>
  
  <p><code>Fling KO:</code></p>
  
  <p><img src="https://i.stack.imgur.com/w7yTI.png" alt="FLING KO"></p>
  
  <p>Here is what I did:</p>
  
  <p>1st step: subclass <code>HorizontalScrollView</code> to add a <code>ScrollChangedListener</code>:</p>
  
  <pre><code>@Override
  protected void onScrollChanged(int l, int t, int oldl, int oldt) {
      super.onScrollChanged(l, t, oldl, oldt);
      if(mOnScrollChangedListener != null) mOnScrollChangedListener.onScrollChanged(l, t, oldl, oldt);
  }
  </code></pre>
  
  <p>2nd step:</p>
  
  <pre><code>mViewToDraw.setOnScrollChangedListener(new MyHorizontalScrollView.OnScrollChangedListener() {
      @Override
      public void onScrollChanged(int l, int t, int oldl, int oldt) {
          mCurrentScrollX = l;
          invalidate(0, 0, getWidth(), mViewToDraw.getMeasuredHeight());
      }
  });
  </code></pre>
  
  <p>Step 3: The draw</p>
  
  <pre><code>@Override
  protected void dispatchDraw(Canvas canvas) {
      super.dispatchDraw(canvas);
      if (mViewToDraw == null) {
        return;
      }
  
      canvas.translate(-mCurrentScrollX, 0);
      mViewToDraw.draw(canvas);
  }
  </code></pre>
  
  <p>Step 4: capturing the touch event</p>
  
  <pre><code>private enum TouchState {NONE, TOUCHING_HEADER}
  
  @Override
  public boolean dispatchTouchEvent(MotionEvent ev) {
    if (mViewToDraw == null) {
      return super.dispatchTouchEvent(ev);
    }
  
    int bottom = mViewToDraw.getMeasuredHeight();
    boolean captured = false;
    boolean invalidate = false;
    switch (ev.getAction()) {
      case MotionEvent.ACTION_DOWN:
        if (ev.getY() &lt;= bottom) {
          mTouchState = TouchState.TOUCHING_HEADER;
          invalidate = true;
          captured = mViewToDraw.dispatchTouchEvent(ev);
        }
        break;
      case MotionEvent.ACTION_CANCEL:
      case MotionEvent.ACTION_UP:
        if (mTouchState == TouchState.TOUCHING_HEADER) {
          mTouchState = TouchState.NONE;
          invalidate = true;
          captured = mViewToDraw.dispatchTouchEvent(ev);
        }
        break;
      default:
        if (mTouchState == TouchState.TOUCHING_HEADER) {
          invalidate = true;
          captured = mViewToDraw.dispatchTouchEvent(ev);
        }
    }
  
    if (invalidate) {
      mViewToDraw.invalidate();
      invalidate(0, 0, getWidth(), bottom);
    }
  
    if (captured) {
      return true;
    }
  
    return super.dispatchTouchEvent(ev);
  }
  </code></pre>
  
  <p>I'm trying not to duplicate the tabs view because I'm pretty sure I can do this way. Hope I was clear enough.</p>
  
  <p><strong>EDIT</strong>: I made a <a href="http://www.youtube.com/watch?v=3FFKsWN9sIg" rel="nofollow noreferrer">small video</a></p>
  
  <p>As you can see, it works perfectly until the header view fully disappear.</p>