滚动型的儿童观,如何有条件地拦截滚动 [英] ScrollView with children view, how to intercept scroll conditionally
问题描述
我有一个容器的ViewGroup
,让我们把它叫做屏幕在滚动型
。这种容器视图举办一些其他的浏览
我们姑且称之为控件,其中一些有兴趣的$ P $从滚动pventing的滚动型和使用MotionEvent过问(例如pannable图像)
I have a container ViewGroup
, lets call it screen inside a ScrollView
. This container view hosts a number of other Views
let's call them widgets, and some of them are interested in preventing the ScrollView from scrolling and using the MotionEvent theirselves (for example a pannable image)
我想不出合适的情况下拦截策略来使用。 滚动型
总是处理事件前的孩子,或者孩子们处理该事件,但滚动视图
是禁用的。
I can't figure out the proper event intercept strategy to use. ScrollView
always processes the event before the children, or the children process the event but scrollview
is disabled.
我读到发布的getParent()。requestDisableInterceptTouchEvent()
在孩子的意见,如果这个观点要捕获事件,但他们的的onTouchEvent
不叫,我想是因为滚动型
已提前席卷了事件。我想的是,我有2个水平层(容器+部件)prevents这从工作,我想容器的ViewGroup
已经在这里发挥重要的作用,但我不能找出哪一个?
I read about issuing getParent().requestDisableInterceptTouchEvent()
in the child views if this view wants to capture the event, but their onTouchEvent
is not called, I suppose because ScrollView
has engulfed the event beforehand. I guess the fact that I have 2 levels of layers (container + widgets) prevents this from working, I suppose the container ViewGroup
has to play an important part here, but I can't figure out which one...
我可以知道,在滚动型的
onInterceptTouchEvent
的水平,这插件的容器 ViewGroup中
已经触碰来决定,如果我要截取或不?
Can I know, at the ScrollView's
onInterceptTouchEvent
level, which widget on the container viewGroup
has been touched to decide if I should intercept or not?
或
如何才能使小部件层的的的ViewGroup
之前滚动型
这样我就可以叫的getParent()。onRequestDisableInterceptTouch()
...或者是的getParent()的getParent()。onRequestDisableInterceptTouch()
?
How can the 'widget' layers in the ViewGroup
get the event before ScrollView
so I can call getParent().onRequestDisableInterceptTouch()
... or is it getParent().getParent().onRequestDisableInterceptTouch()
?
在此先感谢
我看过相关的问题,但没有运气... 在处理触摸事件滚动型的Android
I've read related questions but no luck ... Handle touch events in ScrollView Android
推荐答案
可口可乐和放大器经过一夜好;调试我设法得到这个工作。我同意的解决方案,以防万一有兴趣的人,因为我花了相当多的时间来运行它。
Well after a night of coca cola & debugging I managed to get this to work. I share the solution just in case it is of interest to anyone, because it took me quite a lot of time to get it running.
我没把它与的getParent()运行。onRequestDisableInterceptTouch()
,我很接近,但无法找到一种方法为孩子小部件得到他们所需要的滚动一次MotionEvents我拦截父的触摸,所以尽管外周涡旋是prevented正确,内部部件不滚动。
I didn't manage to get it running with getParent().onRequestDisableInterceptTouch()
, I was close, but couldn't find a way for the child widgets to get the MotionEvents they need for scrolling once I intercepted the touch on the parent, so even though the outer scroll was prevented correctly, the inner widgets didn't scroll.
所以,解决的办法就是 interceptTouchEvents
在孩子只有,然后如果孩子是滚动(称为属性),和触摸是ACTION_DOWN ,然后禁用滚动型两级以上。如果触摸是ACTION_UP,我们启用了滚动视图。
So the solution is to interceptTouchEvents
in the children ONLY, and if the children is scrollable (known property), and the touch is ACTION_DOWN, then disable the scrollview two levels above. If the touch is ACTION_UP, we enable the scrollview.
要启用/禁用滚动视图我刚拦截触摸事件,并与一个标志筛选事件或不
To enable/disable the scrollview I just intercept the touch event and with a flag filter the event or not.
我做了三个辅助类,一个是滚动型,一为容器,一个用于小部件:
I did three auxiliary classes, one for the ScrollView, one for the Container, One for the widgets:
本类包装每一个部件,如果我叫setNeedsScroll(真),那么倒是会被拦截,当它被触摸,它会(告诉容器)告诉滚动视图禁用本身。当触摸被释放时,它将重新启用滚动视图。
This class wraps every widget and, if I call setNeedsScroll(true) , then touches will be intercepted, and when it is touched, it will (tell the container to) tell the scrollview to disable itself. When the touch is released, it will re-enable the 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);
}
}
这是容器,独生子女滚动视图
,并拥有不同的小部件。它只是提供了对孩子的方法,使他们能启用/禁用滚动:
This is the container, only child of the scrollview
, and holds the different widgets. It just provides methods for the children so they can enable/disable the scroll:
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);
}
}
和最后一个滚动视图能够失活。它禁用滚动老斯库尔,拦截和阻断事件。
and finally a scrollview capable of deactivation. It disables the scroll 'old-skool', intercepting and blocking events.
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);
}
}
这篇关于滚动型的儿童观,如何有条件地拦截滚动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!