ScrollView的child在触摸child并垂直滚动时无法获取ACTION_MOVE和ACTION_UP事件
ScrollView's child cannot get ACTION_MOVE and ACTION_UP event when touch child and scroll vertically
我在 ScrollView 中有一些视图。问题是当我触摸 child 视图并垂直滚动它时,child 视图只能获得 ACTION_DOWN
和 ACTION_CANCEL
事件。错过了 ACTION_MOVE
和 ACTION_UP
事件。
如果我触摸 child 视图并水平滚动它,child 视图可以按预期获得所有触摸事件。
这是我的代码:
xml 文件:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/sv_test_tv"
android:layout_width="match_parent"
android:layout_height="100dp"
android:gravity="center"
android:text="This is some text."
android:textSize="30sp" />
<View
android:layout_width="match_parent"
android:layout_height="300dp"
android:background="#faa" />
<View
android:layout_width="match_parent"
android:layout_height="300dp"
android:background="#faf" />
</LinearLayout>
</ScrollView>
java代码:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sv_test);
TextView tv = (TextView) findViewById(R.id.sv_test_tv);
tv.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
LogUtils.v("ScrollViewTest", "onTouch:" + getType(event.getAction()));
return true;
}
});
}
private String getType(int type) {
switch (type) {
case MotionEvent.ACTION_DOWN: {
return "ACTION_DOWN";
}
case MotionEvent.ACTION_MOVE: {
return "ACTION_MOVE";
}
case MotionEvent.ACTION_UP: {
return "ACTION_UP";
}
}
return "other:" + type;
}
谁能帮帮我?非常感谢
发生这种情况是因为 ScrollView 拦截了 移动事件,
查看 ScrollView 源代码
onInterceptTouchEvent(MotionEvent ev) 这样会更清楚。
如果您想在 ScrollView 中使用 ScrollView,那么我建议您查看 this answer
您可以将自定义滚动视图添加到布局中。
创建您的自定义 scrollView 并在您的布局中使用它。
public class VerticalScrollview extends ScrollView{
public VerticalScrollview(Context context) {
super(context);
}
public VerticalScrollview(Context context, AttributeSet attrs) {
super(context, attrs);
}
public VerticalScrollview(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
final int action = ev.getAction();
switch (action)
{
case MotionEvent.ACTION_DOWN:
super.onTouchEvent(ev);
break;
case MotionEvent.ACTION_MOVE:
return false; // redirect MotionEvents to ourself
case MotionEvent.ACTION_CANCEL:
super.onTouchEvent(ev);
break;
case MotionEvent.ACTION_UP:
return false;
default: break;
}
return false;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
super.onTouchEvent(ev);
//Log.i("VerticalScrollview", "onTouchEvent. action: " + ev.getAction() );
return true;
}
}
添加 <packagename..VerticalScrollview />
代替 ScrollView。
试试这个
onInterceptTouchEvent only gets ACTION_DOWN
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
MyLog.d(MyLog.DEBUG, "dispatchTouchEvent(): "+event.getAction());
if (isEnabled()) {
MyLog.d(MyLog.DEBUG, "dispatchTouchEvent()2: "+event.getAction());
processEvent(event);//here you get all events include move & up
super.dispatchTouchEvent(event);
return true; //to keep receive event that follow down event
}
return super.dispatchTouchEvent(event);
}
尝试使用这条线
sv_test_tv.setMovementMethod(new ScrollingMovementMethod());
在 Activity 文件中
我在 ScrollView 中有一些视图。问题是当我触摸 child 视图并垂直滚动它时,child 视图只能获得 ACTION_DOWN
和 ACTION_CANCEL
事件。错过了 ACTION_MOVE
和 ACTION_UP
事件。
如果我触摸 child 视图并水平滚动它,child 视图可以按预期获得所有触摸事件。
这是我的代码:
xml 文件:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/sv_test_tv"
android:layout_width="match_parent"
android:layout_height="100dp"
android:gravity="center"
android:text="This is some text."
android:textSize="30sp" />
<View
android:layout_width="match_parent"
android:layout_height="300dp"
android:background="#faa" />
<View
android:layout_width="match_parent"
android:layout_height="300dp"
android:background="#faf" />
</LinearLayout>
</ScrollView>
java代码:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sv_test);
TextView tv = (TextView) findViewById(R.id.sv_test_tv);
tv.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
LogUtils.v("ScrollViewTest", "onTouch:" + getType(event.getAction()));
return true;
}
});
}
private String getType(int type) {
switch (type) {
case MotionEvent.ACTION_DOWN: {
return "ACTION_DOWN";
}
case MotionEvent.ACTION_MOVE: {
return "ACTION_MOVE";
}
case MotionEvent.ACTION_UP: {
return "ACTION_UP";
}
}
return "other:" + type;
}
谁能帮帮我?非常感谢
发生这种情况是因为 ScrollView 拦截了 移动事件, 查看 ScrollView 源代码 onInterceptTouchEvent(MotionEvent ev) 这样会更清楚。 如果您想在 ScrollView 中使用 ScrollView,那么我建议您查看 this answer
您可以将自定义滚动视图添加到布局中。 创建您的自定义 scrollView 并在您的布局中使用它。
public class VerticalScrollview extends ScrollView{
public VerticalScrollview(Context context) {
super(context);
}
public VerticalScrollview(Context context, AttributeSet attrs) {
super(context, attrs);
}
public VerticalScrollview(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
final int action = ev.getAction();
switch (action)
{
case MotionEvent.ACTION_DOWN:
super.onTouchEvent(ev);
break;
case MotionEvent.ACTION_MOVE:
return false; // redirect MotionEvents to ourself
case MotionEvent.ACTION_CANCEL:
super.onTouchEvent(ev);
break;
case MotionEvent.ACTION_UP:
return false;
default: break;
}
return false;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
super.onTouchEvent(ev);
//Log.i("VerticalScrollview", "onTouchEvent. action: " + ev.getAction() );
return true;
}
}
添加 <packagename..VerticalScrollview />
代替 ScrollView。
试试这个
onInterceptTouchEvent only gets ACTION_DOWN
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
MyLog.d(MyLog.DEBUG, "dispatchTouchEvent(): "+event.getAction());
if (isEnabled()) {
MyLog.d(MyLog.DEBUG, "dispatchTouchEvent()2: "+event.getAction());
processEvent(event);//here you get all events include move & up
super.dispatchTouchEvent(event);
return true; //to keep receive event that follow down event
}
return super.dispatchTouchEvent(event);
}
尝试使用这条线
sv_test_tv.setMovementMethod(new ScrollingMovementMethod());
在 Activity 文件中