3

我正在尝试重现 G+ Android 应用的个人资料屏幕。在此屏幕中,您可以注意到一个包含选项卡的 Horizo​​ntalScrollView,它位于屏幕顶部。

屏幕由一个列表组成,包含一个 HeaderView(ImageBackground、头像、信息和选项卡)和列表(卡片)。

我能够使选项卡粘在顶部并捕获触摸事件,但是当标题从顶部完全消失时,投掷效果不再起作用(<=> 如果第一个可见项listview不是标题)。我可以触摸和移动HorizontalScrollView,它可以工作,直到我尝试投掷。

Fling OK:

飞好

Fling KO:

飞哥

这是我所做的:

第一步:HorizontalScrollView添加一个子类ScrollChangedListener

@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);
}

第二步:

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());
    }
});

第 3 步:抽奖

@Override
protected void dispatchDraw(Canvas canvas) {
    super.dispatchDraw(canvas);
    if (mViewToDraw == null) {
      return;
    }

    canvas.translate(-mCurrentScrollX, 0);
    mViewToDraw.draw(canvas);
}

第四步:捕捉触摸事件

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() <= 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);
}

我试图不复制标签视图,因为我很确定我可以这样做。希望我足够清楚。

编辑:我制作了一个小视频

如您所见,它可以完美运行,直到标题视图完全消失。

4

2 回答 2

1

几个月前,我开发了这个流畅的 UI(粘性标题视图)。我在抛出作为 Horizo​​ntalScrollView 的粘性标题时没有任何问题

在我的 github 上检查:https ://github.com/flavienlaurent/sandbox/blob/master/src/com/fourmob/sandbox/activities/StickyHeaderViewActivity.java

于 2013-10-08T13:10:08.583 回答
1

我在此处发表了一篇关于此的博客文章

于 2013-11-04T17:05:10.290 回答