在Gallery中嵌入ListView

目标是实现一个Gallery,其适配器返回ListViews(换句话说,垂直滚动嵌入在水平滚动Gallery中的ListView)。 它经过一些工作后才有用,但是当试图水平滚动时,ListView看起来非常紧张,就像它有一定的粘性一样。 我没有在Gallery中嵌入任何其他类型的View中观察到这种行为。

这是我尝试过的:

最初,我发现ListView压缩了触摸事件,因此Gallery上的手势监听器永远不会被触发。

所以在Activity的onCreate()方法中,我创建了一个GestureDetector:

galleryGestureDetector = new GestureDetector(this, gallery);

然后,在Gallery适配器的getView()方法内部,在ListView被充气和配置之后,我有一些代码如下:

 listView.setOnTouchListener(new OnTouchListener() { public boolean onTouch(View v, MotionEvent event) { galleryGestureDetector.onTouchEvent(event); return true; } }); 

在这种情况下,我甚至走到了从OnTouchListener返回true的极端步骤,以确保实际上从未调用listView的onTouchEvent()方法。 发生同样的紧张行为。 因此,我认为我可以排除在两个视图之间竞争onTouchEvent()实现。

我试图通过扩展Gallery的触摸矩形来包含ListView然后强制ListView委托给它来滥用TouchDelegate概念,但这也是徒劳的。

我会举手说当前不可能,但与DroidX打包在一起的社交网络应用程序以某种方式实现了它!

问题是ListView拦截了Gallery中的触摸事件,然后改变了视图位置本身。 这就是我在使用小部件时看到的来回抖动效果的原因。 我认为这是Gallery小部件中的一个错误,但与此同时它可以通过子类化Gallery来修复,如下所示:

 public class BetterGallery extends Gallery { private boolean scrollingHorizontally = false; public BetterGallery(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public BetterGallery(Context context, AttributeSet attrs) { super(context, attrs); } public BetterGallery(Context context) { super(context); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { super.onInterceptTouchEvent(ev); return scrollingHorizontally; } @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { scrollingHorizontally = true; return super.onScroll(e1, e2, distanceX, distanceY); } @Override public boolean onTouchEvent(MotionEvent event) { switch(event.getAction()) { case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: scrollingHorizontally = false; } return super.onTouchEvent(event); } 

}

如果您使用BetterGallery代替Gallery,整个过程就可以了!