Android: ScrollView 无意中滚动到顶部
Android: ScrollView scrolls to the top inadvertently
我有这样的布局:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ScrollView
android:id="@+id/scroll_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:fillViewport="true" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
...
other views
...
<TextView
android:id="@+id/text_view_that_can_change"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</RelativeLayout>
</ScrollView>
<include
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
layout="@layout/btns_ok_cancel" />
</RelativeLayout>
问题是当我将文本添加到最初为空时text_view_that_can_change
- 我的ScrollView
滚动到顶部.
当我在 ScrollView/RelativeLayout.
中设置某些视图的可见性时,会发生同样的问题
我可以使用 scrollView.scrollTo(0, yScroll)
将它向后滚动,但它给整个内容带来了可见的,我必须说,丑陋的混蛋。
有什么办法可以防止这种行为吗?
花了几个小时,这是我的发现。
滚动到顶部是因为内容更改导致内部 RelativeLayout
正在重新布局。
您应该添加几行来控制这种情况:
1) 声明 class 将保持滚动位置的成员:
int mSavedYScroll;
2)在主视图中添加GlobalLayoutListener(这里是fragment的主视图,无所谓):
public View onCreateView(...) {
mView = inflater.inflate(...);
...
mView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (mSavedYScroll != 0) {
mScrollContainer.scrollTo(0, mSavedYScroll);
mSavedYScroll = 0;
}
}
});
}
3) 当您执行某些操作(在您的代码中的任何位置)时可能会更改 ScrollView 的内容 - 只需保存当前滚动位置:
mSavedYScroll = mScrollContainer.getScrollY();
//DO SOMETHING THAT MAY CHANGE CONTENT OF mScrollContainer:
...
就是这样!
我有这样的布局:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ScrollView
android:id="@+id/scroll_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:fillViewport="true" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
...
other views
...
<TextView
android:id="@+id/text_view_that_can_change"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</RelativeLayout>
</ScrollView>
<include
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
layout="@layout/btns_ok_cancel" />
</RelativeLayout>
问题是当我将文本添加到最初为空时text_view_that_can_change
- 我的ScrollView
滚动到顶部.
当我在 ScrollView/RelativeLayout.
中设置某些视图的可见性时,会发生同样的问题
我可以使用 scrollView.scrollTo(0, yScroll)
将它向后滚动,但它给整个内容带来了可见的,我必须说,丑陋的混蛋。
有什么办法可以防止这种行为吗?
花了几个小时,这是我的发现。
滚动到顶部是因为内容更改导致内部 RelativeLayout
正在重新布局。
您应该添加几行来控制这种情况:
1) 声明 class 将保持滚动位置的成员:
int mSavedYScroll;
2)在主视图中添加GlobalLayoutListener(这里是fragment的主视图,无所谓):
public View onCreateView(...) {
mView = inflater.inflate(...);
...
mView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (mSavedYScroll != 0) {
mScrollContainer.scrollTo(0, mSavedYScroll);
mSavedYScroll = 0;
}
}
});
}
3) 当您执行某些操作(在您的代码中的任何位置)时可能会更改 ScrollView 的内容 - 只需保存当前滚动位置:
mSavedYScroll = mScrollContainer.getScrollY();
//DO SOMETHING THAT MAY CHANGE CONTENT OF mScrollContainer:
...
就是这样!