gpt4 book ai didi

android - ScrollView 和 Gallery 干扰

转载 作者:行者123 更新时间:2023-11-29 22:28:47 24 4
gpt4 key购买 nike

我有一个由许多 ScrollView 组成的 Gallery,每个 ScrollView 都占据了整个屏幕。问题是 ScrollViews 的 onTouchEvent 返回 true,因此阻止 DOM 中的任何其他 View 处理相同的事件(在 ScrollView 级别处理后被吞没)。结果画廊不再滚动。另一方面,如果我像这样覆盖 onTouchEvent:

   @Override
public boolean onTouchEvent(MotionEvent ev) {
super.onTouchEvent(ev);
return false; // <<<<<<<<<<<<<<<<<
}

然后 Gallery 收到要处理的 on 事件,但 SrollView 不再滚动。反正你输了!还是你?

这个问题听起来令人费解,但我敢肯定,如果你过去偶然发现了它,你会立即认出它,因为它是一个该死的问题!

谢谢

最佳答案

这是我尝试使用垂直 ScrollViews 的图库。

它使用自己的 GestureDetector 实例,并为它提供来自 onInterceptTouchEventMotionEvents

当手势检测器识别到滚动时,我们确定它是水平还是垂直并锁定方向,直到手势完成。这避免了对角线滚动。

如果是水平滚动,onInterceptTouchEvent 将返回 true,以便将来的运动事件转到继承的 Gallery.onTouchEvent 以进行实际滚动。

Gallery 自己的手势检测器(Gallery.java 中的mGestureDetector)不会获取所有运动事件,因此有时会报告巨大的突发事件导致画廊跳来跳去的卷轴。我做了一个讨厌的 hack 来丢弃那些。

代码:

import android.content.Context;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.widget.Gallery;

public class BetterGallery extends Gallery {
/* This gets set when we detect horizontal scrolling */
private boolean scrollingHorizontally = false;

/* This gets set during vertical scrolling. We use this to avoid detecting
* horizontal scrolling when vertical scrolling is already in progress
* and vice versa. */
private boolean scrollingVertically = false;

/* Our own gesture detector, Gallery's mGestureDetector is private.
* We'll feed it with motion events from `onInterceptTouchEvent` method. */
private GestureDetector mBetterGestureDetector;

public BetterGallery(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mBetterGestureDetector = new GestureDetector(new BetterGestureListener());
}

public BetterGallery(Context context, AttributeSet attrs) {
super(context, attrs);
mBetterGestureDetector = new GestureDetector(new BetterGestureListener());
}

public BetterGallery(Context context) {
super(context);
mBetterGestureDetector = new GestureDetector(new BetterGestureListener());
}

@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
// Limit velocity so we don't fly over views
return super.onFling(e1, e2, 0, velocityY);
}

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
// Documentation on this method's contract:
// http://developer.android.com/reference/android/view/ViewGroup.html#onInterceptTouchEvent(android.view.MotionEvent)

// Reset our scrolling flags if ACTION_UP or ACTION_CANCEL
switch (ev.getAction()) {
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
scrollingHorizontally = false;
scrollingVertically = false;
}

// Feed our gesture detector
mBetterGestureDetector.onTouchEvent(ev);

// Intercept motion events if horizontal scrolling is detected
return scrollingHorizontally;
}


@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
// Hack: eat jerky scrolls caused by stale state in mGestureDetector
// which we cannot directly access
if (Math.abs(distanceX) > 100) return false;

return super.onScroll(e1, e2, distanceX, distanceY);
}


@Override
public boolean onTouchEvent(MotionEvent event) {
// Reset our scrolling flags if ACTION_UP or ACTION_CANCEL
switch(event.getAction()) {
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
scrollingHorizontally = false;
scrollingVertically = false;
}

super.onTouchEvent(event);
return scrollingHorizontally;
}

private class BetterGestureListener implements GestureDetector.OnGestureListener {

@Override
public boolean onDown(MotionEvent arg0) {
return false;
}

@Override
public boolean onFling(MotionEvent arg0, MotionEvent arg1, float arg2, float arg3) {
return false;
}

@Override
public void onLongPress(MotionEvent arg0) {
}

@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
if (scrollingHorizontally || scrollingVertically) {
// We already know we're scrolling, ignore this callback.
// This avoids changing scrollingHorizontally / scrollingVertically
// flags mid-scroll.
return false;
}

scrollingHorizontally |= Math.abs(distanceX) > Math.abs(distanceY);
// It's a scroll, and if it's not horizontal, then it has to be vertical
scrollingVertically = !scrollingHorizontally;

return false;
}

@Override
public void onShowPress(MotionEvent arg0) {

}

@Override
public boolean onSingleTapUp(MotionEvent arg0) {
return false;
}
}
}

警告:类(class)名称中的“Better”一词可能具有误导性!

更新:

忘记说了,我还设置了将它的 onTouchEvent 转发到 gallery 的 Activity:

@Override
public boolean onTouchEvent(MotionEvent event) {
return mGallery.onTouchEvent(event);
}

更新 2:

我对这段代码做了一些改进并将其发布在 bitbucket 上.还有一个示例应用程序。它表明此小部件与作为子级的 ListView 存在问题:-/

enter image description here

更新 3:

Gallery 切换到 Horizo​​ntalScrollView 作为我的自定义小部件的基类。 More on this here . Flings 工作,ListViews 和 ExpandableListViews 作为 child 工作,在 Android 1.6、2.2、2.3.4 上测试。它的行为现在非常接近谷歌应用程序的行为,IMO。

更新 4:

Google 已发布 ViewPager !

关于android - ScrollView 和 Gallery 干扰,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5012545/

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