您似乎遇到了系统限制 - 系统按照在您的 XML 中声明的顺序绘制视图。
因此,当您抛出第一个声明的ScrollView 时,第二个会更新,但第一个不会再次更新。但是,当您抛出第二个时,第一个会更新,然后第二个会更新,更改会反映到第一个并再次更新。
我不确定上述描述是否 100% 准确,但大致是这样的。
我创建了一个测试用例来检查我的假设,用以下内容代替main.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/main_layout">
<View android:id="@+id/separator_view"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_centerHorizontal="true"
android:visibility="invisible"/>
<com.example.www.syncscrollviewtesting_stackoverflow.ObservableScrollView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_alignParentEnd="true"
android:layout_toEndOf="@id/separator_view"
android:background="@android:color/holo_green_light"
android:id="@+id/left_scrollview">
<com.example.www.syncscrollviewtesting_stackoverflow.Container
android:layout_width="match_parent"
android:layout_height="100000dp"
android:minHeight="100000dp"
android:id="@+id/left_container"/>
</com.example.www.syncscrollviewtesting_stackoverflow.ObservableScrollView>
<com.example.www.syncscrollviewtesting_stackoverflow.ObservableScrollView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_alignParentStart="true"
android:layout_toStartOf="@id/separator_view"
android:background="@android:color/holo_red_dark"
android:id="@+id/right_scrollview">
<com.example.www.syncscrollviewtesting_stackoverflow.Container
android:layout_width="match_parent"
android:layout_height="100000dp"
android:minHeight="100000dp"
android:id="@+id/right_container"/>
</com.example.www.syncscrollviewtesting_stackoverflow.ObservableScrollView>
</RelativeLayout>
上述 XML 允许您将两个 ScrollViews 定位在 separator_view 的两侧。我发现无论你如何定位它们,带有红色背景(声明为第二个)的ScrollView 总是会导致“滞后”,而带有绿色背景的ScrollView 则可以正常工作。
我还尝试通过将其添加到他们的代码中来防止对ScrollViews 进行不必要的更新:
@Override
protected void onScrollChanged(int x, int y, int oldx, int oldy) {
super.onScrollChanged(x, y, oldx, oldy);
if (!mIsDisabled && scrollViewListener != null) {
scrollViewListener.onScrollChanged(this, x, y, oldx, oldy);
}
}
public void setDisabled(boolean isDisabled) {
mIsDisabled = isDisabled;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
if (mIsDisabled)
return false; // Ignore touch event when disabled
else
return super.onTouchEvent(ev);
}
...这是Activity的:
@Override
public void onScrollChanged(ObservableScrollView scrollView, int x, int y, int oldx, int oldy) {
if (scrollView == mRightScrollView) {
mLeftScrollView.setDisabled(true);
mLeftScrollView.setScrollY(y);
mLeftScrollView.setDisabled(false);
} else {
mRightScrollView.setDisabled(true);
mRightScrollView.setScrollY(y);
mRightScrollView.setDisabled(false);
}
}
但它也没有帮助......
所以,我想,您最好找到另一种不涉及重绘大量Views 的方法,或者只是接受“滞后”。
解决方案:
这个解决方案是OP自己提供的,根据我对情况的分析:触摸事件可以从右边ScrollView(在XML中声明为第二个)转发到左边ScrollView。这样一来,鉴于左侧ScrollView 的弹跳不会导致延迟,所有触摸事件都被视为由第一个声明的ScrollView 发起,从而避免了延迟。