ScrollView .scrollTo无法正常工作?在旋转时保存ScrollView位置

时间:2010-07-16 08:47:50

标签: android

好的..我必须在这里忽略一些非常简单的东西,但我想我正在尝试做一些相当基本的事情。只需保留ScrollView的滚动条位置就方向改变......

这是我的onSaveInstanceState和onRestoreInstanceState的代码。 sView是ScrollView布局的容器。在我的滚动视图中是一个带有大量textview的线性布局。

    @Override 
public void onSaveInstanceState(Bundle outState) 
{
    //---save whatever you need to persist—

    outState.putInt("sViewX",sView.getScrollX());
    outState.putInt("sViewY",sView.getScrollY());

super.onSaveInstanceState(outState);

}

@Override
public void onRestoreInstanceState(Bundle savedInstanceState) 
{
    super.onRestoreInstanceState(savedInstanceState);

    sViewX = savedInstanceState.getInt("sViewX");   
    sViewY = savedInstanceState.getInt("sViewY");

    sView.scrollTo(sViewX, sViewY);

}

如果我在恢复时使用sViewX和sViewY的值设置Toast,则值保持正确。

编辑:我刚尝试做一个sView.scrollTo(0,150);在我的onCreate ..只是为了看看是否会以150px的速度打开活动,但事实并非如此。我认为我的问题与.scrollTo方法有关。

7 个答案:

答案 0 :(得分:118)

我明白了。

由于我在setText中使用了onCreate TextViews,因此调用.scrollTo将无效。

所以现在我正在使用以下内容:

sView.post(new Runnable() {
    @Override
    public void run() {
        sView.scrollTo(sViewX, sViewY);
    } 
});

答案 1 :(得分:1)

onRestoreInstanceState()只是提前滚动视图。 这就是为什么发布新的Runnable会有所帮助,但并非总是如此。有时甚至必须使用postDelayed()让它工作。 对于Fragment,可以使用onViewCreated()代替:

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    sViewX = savedInstanceState.getInt("sViewX");   
    sViewY = savedInstanceState.getInt("sViewY");
    sView.scrollTo(sViewX, sViewY);
}

答案 2 :(得分:1)

这对我有用

@Override
protected void onSaveInstanceState(Bundle outState) {
    outState.putInt(SystemGlobal.SCROLL_Y, mRelativeLayoutMain.getTop());
}

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onRestoreInstanceState(savedInstanceState);
    mRelativeLayoutMain.scrollTo(0, savedInstanceState.getInt(SystemGlobal.SCROLL_Y));
}

答案 3 :(得分:1)

您应该在绘制组件之前开始滚动,因为滚动不起作用,直到没有创建组件:

@Override
public void onWindowFocusChanged(boolean hasFocus) {
    scrollView.scrollTo(.... 

答案 4 :(得分:1)

此代码对我有用,可以动态滚动标签, 也许对你有用

TabHost tabHost;
int currentActiveTab;
HorizontalScrollView tabsHorizontalScrollView;
//some code ...
tabHost = getTabHost();
tabsHorizontalScrollView = findViewById(R.id.tabsHorizontalScrollView);
currentActiveTab = 8;
//some code ...
tabHost.setCurrentTab(currentActiveTab);
tabHost.getTabWidget().getChildAt(currentActiveTab).post(new Runnable() {
  @Override
  public void run() {
    tabsHorizontalScrollView.scrollTo(tabHost.getTabWidget().getChildAt(currentActiveTab).getLeft(), tabsHorizontalScrollView.getScrollY());
  }
});

答案 5 :(得分:0)

对于MVVMCross:

protected override void OnSaveInstanceState(Bundle outState)
{
    base.OnSaveInstanceState(outState);

    ScrollView sv = FindViewById<ScrollView>(Resource.Id.dispatchScrollView);
    int posY = sv.ScrollY;

    outState.PutInt("scrollY", posY);
}

protected override void OnRestoreInstanceState(Bundle savedInstanceState)
{
    base.OnRestoreInstanceState(savedInstanceState);

    ScrollView sv = FindViewById<ScrollView>(Resource.Id.dispatchScrollView);
    int posY = savedInstanceState.GetInt("scrollY");

    sv.Post(new Runnable(new Action(() => sv.ScrollTo(0, posY))));
}

答案 6 :(得分:0)

您可以在全局布局回调中滚动视图,而不是将滚动操作发送到下一个运行循环:

@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    sView.getViewTreeObserver().addOnGlobalLayoutListener(
        new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                sView.scrollTo(sViewX, sViewY);
            }
        }
    );
}