如何通过编程将ScrollView滚动到底部

64

我遇到一个无法解决的问题:在ScrollView中,我只有一个LinearLayout。通过用户操作,我在这个LinearLayout上编程添加了2个TextView,但默认情况下滚动条保持在顶部。 由于我控制用户操作,因此应该很容易用类似以下方式向底部滚动:

ScrollView scroll = (ScrollView) this.findViewById(R.id.scroll);
scroll.scrollTo(0, scroll.getBottom());

实际上不是这样的。因为在添加这两个新元素之后,getBottom()仍然返回先前的两个元素。我尝试调用refreshDrawableState()来刷新状态,但它并没有起作用。

你知道如何在添加一些元素后获取ScrollView的实际底部吗?


实际上,ScrollView可能会更改或不更改其高度(它是LinearLayout的容器)。尝试使用ScrollView的第一个(也是唯一的)子LinearLayout的getBottom()方法。 - Olsavage
两个容器(ScrollView和LinearLayout)看起来都有同样的问题:底部位置不反映最后添加的项目 :-/ - wikier
请发布您添加新元素的代码。没有您的代码很难说。我认为可能是权重问题或其他原因。 - Olsavage
7个回答

147

你需要使用消息队列,否则它将无法工作。尝试这样做:

scrollView.post(new Runnable() {
    @Override
    public void run() {
        scrollView.fullScroll(ScrollView.FOCUS_DOWN);
    }
});

这就是对我有用的。


6
这对于NestedScrollView也适用,我尝试过了。谢谢。 - ashishdhiman2007
这是建议使用的完整滚动方式,scrollTo() 方法无法滚动到完全顶部。 - Sadda Hussain

84

这并不真正回答你的问题。 但这是一个几乎做同样事情的替代方法。

与其滚动到屏幕底部,不如将焦点更改为位于屏幕底部的视图。

也就是说,替换:

scroll.scrollTo(0, scroll.getBottom());

使用:

Footer.requestFocus();

确保你指定了视图,比如说 'Footer' 是可聚焦的。

android:focusable="true"
android:focusableInTouchMode="true"

这个可聚焦属性非常适合在具有复杂布局的情况下使用...谢谢。 - Kushal
我发现很难在屏幕底部得到视图。我有一个包含TextView的ListView。我已经尝试了listView.getItemAtPosition(elementCount -1)来获取那个TextView,但它返回的是一个字符串而不是一个视图。我怀疑在这种情况下我需要制作一个自定义的ArrayAdapter。 - kiwicomb123
当底部有一个按钮时,按钮会显示涟漪效果,这使得它看起来很奇怪! - Kishan Solanki
如果您正在进行ShowCaseView,则它可以完美地工作。 - Vijay
如果你多次调用footer.requestFocus(),不要忘记移除焦点!使用footer.clearFocus()或者another_edit_text.requestFocus()然后再调用footer.requestFocus() - CoolMind

21

这将是可以的

scrollView.post(new Runnable() {
    @Override

    public void run() {

        scroll.scrollTo(0, scroll.getBottom());

    }
});

5
你尝试过使用scroll.fullScroll(View.FOCUS_DOWN)吗?它可以滚动到底部。

5
我尝试了scroll.fullScroll(View.FOCUS_DOWN),但它没起作用。 - wikier

2

因为我也使用了隐藏键盘,所以以下代码延迟200毫秒的效果更好。 注意:我只是用上面的示例中的post()替换为postDelayed():

    final ScrollView scrollView_main = (ScrollView) findViewById(R.id.scrollView_main);
    scrollView_main.postDelayed(new Runnable() {
        @Override
        public void run() {
            scrollView_main.fullScroll(View.FOCUS_DOWN);
        }
    }, 200);

1
这是从另一个答案中复制的。 - Vijay
1
我已经添加了注释。 注意:我刚刚从上面的示例中将post()替换为postDelayed()。 我的问题是,我还在使用隐藏键盘。因此,post()对我没有帮助。对我来说,“200毫秒”的延迟起了魔法作用。 - Sunny Jha

0

你也可以应用这个

 mScrollviewHomepage.setScrollY(View.FOCUS_DOWN);

-1

我希望它能够工作

试试这个:

nsscroll.post(new Runnable() { @Override

                    public void run() {

                        nsscroll.scrollTo(0, nsscroll.getBottom());

                    }
                });

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