rup*_*pps 6 android touch scrollview touch-event
我有一个容器ViewGroup,可以把它的屏幕内ScrollView.这个容器视图托管了许多其他Views的调用它们的小部件,其中一些有兴趣阻止ScrollView滚动并使用MotionEvent自己(例如一个pannable图像)
我无法弄清楚要使用的正确的事件拦截策略.ScrollView始终在子项之前处理事件,或者子项处理事件但是scrollview已禁用.
我读过关于getParent().requestDisableInterceptTouchEvent()在子视图中发出这个视图是否想要捕获事件,但是onTouchEvent没有调用它们,我想是因为ScrollView事先已经吞没了事件.我想我有2级层(容器+小部件)的事实阻止了它的工作,我想容器ViewGroup必须在这里发挥重要作用,但我无法弄清楚哪一个......
我是否可以在ScrollView's onInterceptTouchEvent级别上知道容器上的哪个小部件viewGroup被触摸以决定是否应该拦截?
要么...
如何才能获得事件中的"小部件"图层,ViewGroupScrollView以便我可以调用getParent().onRequestDisableInterceptTouch() ......或者是它getParent().getParent().onRequestDisableInterceptTouch()?
提前致谢
我已阅读相关问题,但没有运气...... 在ScrollView Android中处理触摸事件
经过一夜的可口可乐和调试后,我设法让这个工作.我会分享解决方案以防万一对任何人感兴趣,因为我花了很多时间才能让它运行起来.
我没有设法让它运行getParent().onRequestDisableInterceptTouch(),我很接近,但是当我拦截父母的触摸时,找不到让小部件获取他们滚动所需的MotionEvent的方法,所以即使外部滚动是正确阻止,内部小部件没有滚动.
因此解决方案是interceptTouchEvents 仅在子项中,如果子项是可滚动的(已知属性),并且触摸是ACTION_DOWN,则禁用上面两级的scrollview.如果触摸是ACTION_UP,我们启用scrollview.
要启用/禁用滚动视图,我只是拦截触摸事件,并使用标志过滤事件与否.
我做了三个辅助类,一个用于ScrollView,一个用于容器,一个用于小部件:
这个类包装了每个小部件,如果我调用setNeedsScroll(true),那么将拦截触摸,当它被触摸时,它将(告诉容器)告诉scrollview禁用它自己.触摸释放后,将重新启用滚动视图.
class WidgetWrapperLayout extends FrameLayout {
private boolean mNeedsScroll=false;
public WidgetWrapperLayout(Context context) {
super(context);
}
/** Called anytime, ie, during construction, to indicate that this
* widget uses vertical scroll, so we need to disable its container scroll
*/
public void setNeedsScroll(boolean needsScroll) {
mNeedsScroll=needsScroll;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (mNeedsScroll) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
((SlideLayout)getParent()).setEnableScroll(false);
break;
case MotionEvent.ACTION_UP:
((SlideLayout)getParent()).setEnableScroll(true);
break;
}
return false;
}
return super.onInterceptTouchEvent(ev);
}
}
Run Code Online (Sandbox Code Playgroud)
这是容器,也是唯一的子容器,scrollview并且包含不同的小部件.它只为孩子们提供方法,以便他们可以启用/禁用滚动:
public class ContainerLayout extends FrameLayout {
public ContainerLayout(Context context) {
super(context);
}
public void setEnableScroll(boolean status) {
if (Conf.LOG_ON) Log.d(TAG, "Request enable scroll: "+status);
((StoppableScrollView)getParent()).setScrollEnabled(status);
}
}
Run Code Online (Sandbox Code Playgroud)
最后是一个能够停用的滚动视图.它禁用滚动'old-skool',拦截和阻止事件.
public class StoppableScrollView extends ScrollView {
private String TAG="StoppableScrollView";
private boolean mDisableScrolling=false;
public StoppableScrollView(Context context) {
super(context);
}
/** Enables or disables ScrollView scroll */
public void setScrollEnabled (boolean status) {
if (Conf.LOG_ON) Log.d(TAG, "Scroll Enabled "+status);
mDisableScrolling=!status;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (mDisableScrolling) return false;
return super.onInterceptTouchEvent(ev);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9838 次 |
| 最近记录: |