Android:嵌套ScrollViews和HorizontalScrollViews,拦截
Android: nested ScrollViews and HorizontalScrollViews, interception
我在 Android 中的 ScrollViews 内部使用 ScrollViews 时遇到问题。我知道这不是最佳做法,但我需要让它发挥作用。
public static void disableScrollOnParentHorizontalScrollView(View v) {
v.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
requestDisallowInterceptTouchEventByDirection(v, true, HorizontalScrollView.class);
break;
case MotionEvent.ACTION_UP:
requestDisallowInterceptTouchEventByDirection(v, false, HorizontalScrollView.class);
break;
}
v.onTouchEvent(event);
return true;
}
});
}
对于垂直滚动视图,我使用与上面相同的方法,并将 ScrollView.class 作为参数。
private static void requestDisallowInterceptTouchEventByDirection(View v, boolean b, Class<?> clazz) {
while (v.getParent() != null && v.getParent() instanceof View) {
if (clazz.isInstance(v.getParent())) {
v.getParent().requestDisallowInterceptTouchEvent(b);
}
v = (View) v.getParent();
}
}
这是一个屏幕截图,我想告诉你到底是什么问题。
- ScrollView 内嵌套的 HorizontalScrollView 应该垂直(父)和水平(自己)滚动。
- HorizontalScrollView 内的嵌套 ScrollView 应该水平(父)和垂直(自己)滚动。
- HorizontalScrollView 和垂直 ScrollView 内部的视图应该滚动两个父视图。
这在大多数情况下都有效。
TextViews 5和9嵌套在ScrollViews中,TextViews 6和10嵌套在HorizontalScrollViews中。
- 视图 #2 垂直滚动 (2),父视图水平滚动 (1)
- 视图 #3 水平滚动 (3),父视图垂直滚动 (2)
- ...
- 视图 #6 水平滚动 (6),父视图垂直滚动 (4)
- 视图 #7 水平滚动父级 (3) 垂直滚动父级 (4)
因此任何视图在其自身不可滚动时都应该滚动它的父视图。
我的问题是垂直滚动视图 (4) 内的垂直滚动视图 (5) 不会滚动外部垂直视图的水平滚动父视图 (3)。
另一个方向的相同问题(视图 #10(水平滚动)不滚动它的父级(8,水平滚动)父级(4,垂直滚动),但视图 #10 的视图右侧滚动,8 (水平)和 4(垂直)。
貌似有些view截取错误了,但是没找到问题
谁能帮帮我?
此致
可能的解决方案
好的,完成这个:我找到了一个糟糕的解决方案,但它有效。
如果有两个嵌套的 HorizontalScrollView,我会搜索第一个(或最里面的)垂直 ScrollView 并禁用拦截。
public static void disableScrollOnParentHorizontalScrollView(View v) {
v.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
requestDisallowInterceptTouchEventByDirection(v, true, HorizontalScrollView.class); //funzt weitgehend
if (isDirectlyHorizontalScrollViewAbove(v)) {
findFirstScrollViewAbove(v).requestDisallowInterceptTouchEvent(false);
findFirstScrollViewAbove(v).getParent().requestDisallowInterceptTouchEvent(true);
}
break;
case MotionEvent.ACTION_UP:
requestDisallowInterceptTouchEventByDirection(v, false, HorizontalScrollView.class);
break;
}
v.onTouchEvent(event);
return true;
}
});
}
private static boolean isDirectlyHorizontalScrollViewAbove(View v) {
while (v.getParent() != null && v.getParent() instanceof View) {
if (v.getParent() instanceof HorizontalScrollView) {
return true;
} else if (v.getParent() instanceof ScrollView) {
return false;
}
v = (View) v.getParent();
}
return false;
}
private static ScrollView findFirstScrollViewAbove(View v) {
while (v.getParent() != null && v.getParent() instanceof View) {
if (v.getParent() instanceof ScrollView) {
return (ScrollView) v.getParent();
}
v = (View) v.getParent();
}
return null;
}
// same method like before
private static void requestDisallowInterceptTouchEventByDirection(View v, boolean b, Class<?> clazz) {
while (v.getParent() != null && v.getParent() instanceof View) {
if (clazz.isInstance(v.getParent())) {
v.getParent().requestDisallowInterceptTouchEvent(b);
}
v = (View) v.getParent();
}
}
如果有人有更好的解决方案(或者发现我截取的问题),请回答:)
此致
我在 Android 中的 ScrollViews 内部使用 ScrollViews 时遇到问题。我知道这不是最佳做法,但我需要让它发挥作用。
public static void disableScrollOnParentHorizontalScrollView(View v) {
v.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
requestDisallowInterceptTouchEventByDirection(v, true, HorizontalScrollView.class);
break;
case MotionEvent.ACTION_UP:
requestDisallowInterceptTouchEventByDirection(v, false, HorizontalScrollView.class);
break;
}
v.onTouchEvent(event);
return true;
}
});
}
对于垂直滚动视图,我使用与上面相同的方法,并将 ScrollView.class 作为参数。
private static void requestDisallowInterceptTouchEventByDirection(View v, boolean b, Class<?> clazz) {
while (v.getParent() != null && v.getParent() instanceof View) {
if (clazz.isInstance(v.getParent())) {
v.getParent().requestDisallowInterceptTouchEvent(b);
}
v = (View) v.getParent();
}
}
这是一个屏幕截图,我想告诉你到底是什么问题。
- ScrollView 内嵌套的 HorizontalScrollView 应该垂直(父)和水平(自己)滚动。
- HorizontalScrollView 内的嵌套 ScrollView 应该水平(父)和垂直(自己)滚动。
- HorizontalScrollView 和垂直 ScrollView 内部的视图应该滚动两个父视图。
这在大多数情况下都有效。
TextViews 5和9嵌套在ScrollViews中,TextViews 6和10嵌套在HorizontalScrollViews中。
- 视图 #2 垂直滚动 (2),父视图水平滚动 (1)
- 视图 #3 水平滚动 (3),父视图垂直滚动 (2)
- ...
- 视图 #6 水平滚动 (6),父视图垂直滚动 (4)
- 视图 #7 水平滚动父级 (3) 垂直滚动父级 (4)
因此任何视图在其自身不可滚动时都应该滚动它的父视图。
我的问题是垂直滚动视图 (4) 内的垂直滚动视图 (5) 不会滚动外部垂直视图的水平滚动父视图 (3)。
另一个方向的相同问题(视图 #10(水平滚动)不滚动它的父级(8,水平滚动)父级(4,垂直滚动),但视图 #10 的视图右侧滚动,8 (水平)和 4(垂直)。
貌似有些view截取错误了,但是没找到问题
谁能帮帮我?
此致
可能的解决方案
好的,完成这个:我找到了一个糟糕的解决方案,但它有效。
如果有两个嵌套的 HorizontalScrollView,我会搜索第一个(或最里面的)垂直 ScrollView 并禁用拦截。
public static void disableScrollOnParentHorizontalScrollView(View v) {
v.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
requestDisallowInterceptTouchEventByDirection(v, true, HorizontalScrollView.class); //funzt weitgehend
if (isDirectlyHorizontalScrollViewAbove(v)) {
findFirstScrollViewAbove(v).requestDisallowInterceptTouchEvent(false);
findFirstScrollViewAbove(v).getParent().requestDisallowInterceptTouchEvent(true);
}
break;
case MotionEvent.ACTION_UP:
requestDisallowInterceptTouchEventByDirection(v, false, HorizontalScrollView.class);
break;
}
v.onTouchEvent(event);
return true;
}
});
}
private static boolean isDirectlyHorizontalScrollViewAbove(View v) {
while (v.getParent() != null && v.getParent() instanceof View) {
if (v.getParent() instanceof HorizontalScrollView) {
return true;
} else if (v.getParent() instanceof ScrollView) {
return false;
}
v = (View) v.getParent();
}
return false;
}
private static ScrollView findFirstScrollViewAbove(View v) {
while (v.getParent() != null && v.getParent() instanceof View) {
if (v.getParent() instanceof ScrollView) {
return (ScrollView) v.getParent();
}
v = (View) v.getParent();
}
return null;
}
// same method like before
private static void requestDisallowInterceptTouchEventByDirection(View v, boolean b, Class<?> clazz) {
while (v.getParent() != null && v.getParent() instanceof View) {
if (clazz.isInstance(v.getParent())) {
v.getParent().requestDisallowInterceptTouchEvent(b);
}
v = (View) v.getParent();
}
}
如果有人有更好的解决方案(或者发现我截取的问题),请回答:)
此致