如何保持ScrollView滚动到底部?

6
我有一个ScrollView,里面有一个LinearLayout,我正在添加TextView。但我总是希望最后添加的TextView可见,因此当添加TextView时,我需要让ScrollView滚动到底部。我不知道为什么,在添加textview后调用scrollto()、scrollby()或fullScroll()时,它只会滚动到倒数第二个textview。
您知道更好的方法吗?
非常感谢!
代码:
我有一个按钮,它调用这个函数:
private void addRound() {
    // TODO Auto-generated method stub
    TextView newRound = new TextView(Stopwatch.this);
    newRound.setText("" + counter + ". - " + timerText());
    newRound.setTextSize(20);
    newRound.setGravity(Gravity.CENTER);
    linlay.addView(newRound);
    counter++;
}

调用这个函数后,我会调用fullScroll()。
addRound();
sv.fullScroll(View.FOCUS_DOWN);

sv是我的ScrollView,linlay是ScrollView内部的LinearLayout。


我能将ListView缩小为布局的一部分吗? - TheBrillowable
1
我们能看到您用来确定滚动位置和实际滚动ScrollView的代码吗? - Henry Thompson
当然,给我一秒钟,我会编辑我的原始帖子。 - TheBrillowable
是的,ListView可以成为其他控件的一部分 - 比如另一个垂直LinearLayout。我猜这些是你在游戏回合中花费时间的轮次。对吗?你应该将这些信息保存在数据库中。首先更新数据库,然后将数据检索到你的ListView中并刷新它。 - Sergey Benner
我需要不止一个TextView,因为它们显示的数据都不同。是的,我正在添加这些TextView,因为我将它们添加到linlay中,而linlay是ScrollView的子项。 - TheBrillowable
显示剩余2条评论
2个回答

11

我认为问题出在当你调用 sv.scrollFull(View.FOCUS_DOWN); 时,ScrollView 还没有完全更新。请尝试以下代码(替换你的第二个代码示例):

addRound();
sv.post(new Runnable() {

   @Override
   public void run() {
     sv.fullScroll(View.FOCUS_DOWN);
   }
});

如果上面的方法不起作用,可以尝试以下方法(虽然不够优雅但可能有效):

addRound();
sv.postDelayed(new Runnable() {

   @Override
   public void run() {
     sv.fullScroll(View.FOCUS_DOWN);
   }
}, 100);

希望这个可以工作!


第一个选项运行良好,似乎没有明显的性能问题,非常感谢! - TheBrillowable
还没有更新。终于解决了我的问题。不需要postDelayed,普通的post就足够了。 - Michel
谢谢,postDelayed代码对我总是有效的,第一段代码只有时而有效。 - user3560827

0
另一种方法是使用ViewTreeObserver.OnGlobalLayoutListener。在onCreate()方法中添加以下代码片段。
    linlay.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            sv.fullScroll(View.FOCUS_DOWN);
        }
    });

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接