与 ScrollView 结合使用滑动/滑动选项卡更改?
我在这个特定问题上能找到的最好的(尽管我不使用图库): ScrollView 和 Gallery interfering< /a> - 但并没有真正给出具体的答案。显然,我的实现不使用图库。
跳到下一个粗体部分,了解有趣的部分
所以我不久前在我的应用程序上得到了 Fling/Swipe/Flick/任何你想调用的东西。灵感来自几个不同的地方,其中一些是 Stack Overflow 上的“基本手势检测”(网格布局上的滑动手势检测),Code Shogun (http://www.codeshogun.com/blog/2009/04/16/how-to-implement-swipe-action-in-android/ )和开发 Android ( http://developingandroid.blogspot.com/2009/09/implementing -swipe-gesture.html ),但我不在我的应用程序中使用 ViewFlipper。当发生猛击时,我只需更改选项卡(在两端环绕)。
现在,我的一些选项卡包含 ScrollViews。这些 ScrollView 显然响应向上/向下滚动,以便让您查看其中的所有数据,这并不奇怪。 问题是这些 ScrollView 的“滚动”功能会覆盖我的快速手势。我无法在 ScrollView 内部快速滚动(滚动效果很好),但它在外部可以完美地工作(在同一个选项卡上,在其他视图上,例如 TableRow 或其他视图上)。
我快速浏览了 http:// /blog.velir.com/index.php/2010/11/17/android-snapping-horizontal-scroll/ 也是如此,它提供了一种实现 HorizontalScrollView 的方法。但它仍然通过一个扩展 SimpleOnGestureListener 的类(并覆盖 onFling)来处理手势,这与我的实现相同(这让我相信它不会真正有帮助)。 来自 Google 的 ScrollView 源代码: http://google.com/codesearch/p?hl=en#uX1GffpyOZk/core/java/android/widget/ScrollView.java&d=3
有什么方法可以让我的实现 Swipe 和 ScrollView 毫不费力地协同工作?
我猜这就是问题所在。 ScrollView.java 还使用了一个名为 onTouchEvent 的方法,并且 Activity 状态的 onTouchEvent 的文档如下:
“触摸屏事件发生时调用 不受以下任何视图的处理 它。这对处理最有用 外部发生的触摸事件 你的窗口边界,那里没有 查看以接收它。”
- 我该怎么办?有没有办法确保两者都被检查?当 ScrollView 处理 onTouchEvent 时,我的 onTouchEvent 不会被命中:
@Override
/** Used for swipe gestures */
public boolean onTouchEvent(MotionEvent event) {
if (gestureDetector.onTouchEvent(event))
return true;
else
return false;
}
下面是更通用的源代码我的 Tabs 类中的gestureDetector 及其关联的侦听器可能不是很重要:
// Gestures
gestureDetector = new GestureDetector(new MyGestureDetector());
gestureListener = new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (gestureDetector.onTouchEvent(event)) {
return true;
}
return false;
}
};
我的手势类是我的 Tabs 类(扩展 TabActivity)的嵌套类 - 它与您在该主题上找到的任何其他代码相同:
/** GestureDetector used to swipe between classes */
class MyGestureDetector extends SimpleOnGestureListener {
TabHost tabHost = getTabHost();
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
try {
if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH) return false;
if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
// my tab code
return true;
} else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
// my tab code
return true;
}
} catch (Exception e) {
Log.e("MyGestureDetector onFling", e.toString());
}
return false;
}
}
The best I could find on this particular issue (although I do not use a Gallery): ScrollView and Gallery interfering - doesn't really give a specific answer though. And my implementation does not use a Gallery, obviously.
Jump down to the next bold part for the interesting part
So I got Fling/Swipe/Flick/whatever you want to call it to work a while ago on my application. Inspiration was gathered from a couple of different places, some of them being "basic gesture detection" here on Stack Overflow ( Fling gesture detection on grid layout ), Code Shogun ( http://www.codeshogun.com/blog/2009/04/16/how-to-implement-swipe-action-in-android/ ) and Developing Android ( http://developingandroid.blogspot.com/2009/09/implementing-swipe-gesture.html ), but I do not use a ViewFlipper in my application. When a fling occurs I simply change the tab (wrapping around at the ends).
Now, some of my tabs contain ScrollViews. These ScrollViews obviously respond to up/down scrolls in order to let you view all data inside it, no surprise there.
The issue is that it would appear the 'scroll' function of these ScrollViews overwrite my fling gesture. I cannot fling inside a ScrollView (scroll just fine), but it works flawlessly outside them (on the same tab, on other views such as TableRow or whatever).
I had a quick look at http://blog.velir.com/index.php/2010/11/17/android-snapping-horizontal-scroll/ too, which provides a way to implement HorizontalScrollView. But it still handles gestures through a class that extends SimpleOnGestureListener (and overwrites onFling), which is the same implementation as I have (which leads me to believe it won't really help).
Source code for ScrollView from Google: http://google.com/codesearch/p?hl=en#uX1GffpyOZk/core/java/android/widget/ScrollView.java&d=3
Is there any way to have my implementation of Swipe and ScrollView working together effortlessly?
This is where the problem lies, I guess. ScrollView.java also uses a method called onTouchEvent and the documentation for the onTouchEvent for Activity states:
"Called when a touch screen event was
not handled by any of the views under
it. This is most useful to process
touch events that happen outside of
your window bounds, where there is no
view to receive it."
So the ScrollView does "override" it - what do I do? Is there no way to ensure both are checked? My onTouchEvent which is not hit when the onTouchEvent is handled by the ScrollView:
@Override
/** Used for swipe gestures */
public boolean onTouchEvent(MotionEvent event) {
if (gestureDetector.onTouchEvent(event))
return true;
else
return false;
}
More general source code below, it's probably not very vital. The gestureDetector inside my Tabs class with its associated listener:
// Gestures
gestureDetector = new GestureDetector(new MyGestureDetector());
gestureListener = new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (gestureDetector.onTouchEvent(event)) {
return true;
}
return false;
}
};
My gesture class which is a nested class of my Tabs class (which extends TabActivity) - it's the same as any other code you will find on this subject:
/** GestureDetector used to swipe between classes */
class MyGestureDetector extends SimpleOnGestureListener {
TabHost tabHost = getTabHost();
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
try {
if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH) return false;
if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
// my tab code
return true;
} else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
// my tab code
return true;
}
} catch (Exception e) {
Log.e("MyGestureDetector onFling", e.toString());
}
return false;
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我建议您查看 Google I/O 2010 应用源代码,因为他们的
FlingableTabHost
实现似乎已经解决了这个问题:http://iosched.googlecode.com/svn/trunk/src/com/google/ android/apps/iosched/ui/ScheduleActivity.java
我认为关键在于扩展
TabHost
并重写其onInterceptTouchEvent
方法。I would suggest you have a look at the Google I/O 2010 app source code, as their
FlingableTabHost
implementation would appear to have solved this problem:http://iosched.googlecode.com/svn/trunk/src/com/google/android/apps/iosched/ui/ScheduleActivity.java
I think the key is in extending
TabHost
and overriding itsonInterceptTouchEvent
method.在寻求解决我遇到的类似问题时,我遇到了这个小窍门:
。 ="nofollow">Android 开发网站,它讨论了在布局文件的
根目录中使用此属性。In looking to solve a similar issue I am having, I came across this tid-bit:
From the Android Dev site, it talks about using this attribute in the
<android.gesture.GestureOverlayView>
Root in your layout file.无论如何,我发现 onFling 方法非常不可靠。我重写 SimpleGestureDetector 中的 onScroll 方法,并将 onInterceptTouchEvent 定义为:
For what it's worth, I found the onFling method very unreliable. I override the onScroll method in the SimpleGestureDetector, and define my onInterceptTouchEvent as: