gpt4 book ai didi

android - 从 Scrollview 派发事件到底层 Viewpager

转载 作者:搜寻专家 更新时间:2023-11-01 08:00:57 24 4
gpt4 key购买 nike

在我的 Android 应用程序中,我有以下布局:

<CustomRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>

<android.support.v4.view.ViewPager
android:id="@+id/image_viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>

<OverScrollBounceScrollView
android:id="@+id/scrollview"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
>

<LinearLayout
android:id="@+id/user_profile_scroll_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>

<RelativeLayout
android:id="@+id/dummy_viewport"
android:layout_width="match_parent"
android:layout_height="350dp"
>

</RelativeLayout>

<LinearLayout
android:id="@+id/scroll_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@android:color/white"
>

...some content

</LinearLayout>
</LinearLayout>
</OverScrollBounceScrollView>
</CustomRelativeLayout>

它看起来是这样的:

http://i.stack.imgur.com/lzL5u.png

我的目标是:

  1. 当我在 Y 方向滚动时,我希望 ScrollView 接管并正常滚动
  2. 当我在 X 方向滚动时,我希望 ScrollView 下的 viewpager 接管

现在的问题是,scrollview 拿走了所有的事件,viewpager 根本就达不到。

关于如何解决这个问题有什么想法吗?

最佳答案

对于任何对此问题的答案感兴趣或有类似问题的人,以下是我的解决方法。

首先,一般的方法是制作一个自定义 View ,拦截某些触摸事件并将它们委托(delegate)给正确的 child 。

在我的例子中,viewpager 应该拦截水平手势,位于 viewpager 顶部 的 ScrollView 应该只获取垂直滚动事件。我的一个特殊要求是,viewpager 还应该只拦截特定范围内的触摸事件,即虚拟视口(viewport),它是覆盖 ScrollView 内部的子项。

在自定义布局类中,必须结合 onTouchEvent() 方法重写 onInterceptTouchEvent() 方法:

@Override
public boolean onInterceptTouchEvent ( MotionEvent event ) {
// 1.) remember DOWN event ALWAYS as this is important start for every gesture
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mInitialX = event.getX();
mInitialY = event.getY();
mInitialDownEvent = MotionEvent.obtainNoHistory(event);
mIsDownEventDispatched = false;
break;
case MotionEvent.ACTION_MOVE:
final float x = event.getX();
final float y = event.getY();
final int yDiff = (int) Math.abs(y - mInitialY);
final int xDiff = (int) Math.abs(x - mInitialX);
calculateDelegatesHitRectangle();
if(xDiff > mTouchSlop && mDelegateBounds.contains((int)event.getX(), (int)event.getY())){
// 2.) if we scroll more in X-direction AND we are within the bounds of our delegatinView
// then INTERCEPT event here, so this views onTouch will be called
Log.d("hitrect", "HITRECT--- TOP: " + mDelegateBounds.top + " BOTTOM: " + mDelegateBounds.bottom);
return true;
}
break;
}

return super.onInterceptTouchEvent(event);

}


@Override
public boolean onTouchEvent(MotionEvent event) {

// 3.) we receive ALL following event after X-Scroll has been intercepted
// but the DOWN event was handled by this view so we have to dispatch the remembered down event
// so the dispatch-target has a valid start for the scroll-gesture
if(!mIsDownEventDispatched){
mDispatchTargetView.dispatchTouchEvent(mInitialDownEvent);
mIsDownEventDispatched = true;
}
mDispatchTargetView.dispatchTouchEvent(event);
Log.d("touch", "ROOT: onTouchEvent after Intercept " + event.getActionMasked());
return true;
}

如您所见,我总是检查并保存类成员中的 DOWN 事件,一旦检测到移动,我就会检查它是否在 x 方向(对于 viewpager)执行。被截获了。在这种情况下,我的 calculateDelegatesHitRectangle() 方法只检查我是否在边界内,我想在边界内排除触摸事件。

在 onTouch 中,我只将截获的水平手势重新路由到我的 viewpager,它通过 setter 注入(inject)到这个自定义 View 中。为了有一个正确的手势,我还需要重新路由拦截的 DOWN 事件。

在我的 Activity 代码中,我只是设置了调度目标和委托(delegate) View :

dispatchAwareLayout.setDispatchTargetView(mImageViewPager);
dispatchAwareLayout.setDelegateView(mDummyViewport);

关于android - 从 Scrollview 派发事件到底层 Viewpager,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21315075/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com