我想要一个ScrollView从底部开始。任何方法吗?


当前回答

这里有一些滚动到底部的其他方法

fun ScrollView.scrollToBottom() {
    // use this for scroll immediately
    scrollTo(0, this.getChildAt(0).height) 

    // or this for smooth scroll
    //smoothScrollBy(0, this.getChildAt(0).height)

    // or this for **very** smooth scroll
    //ObjectAnimator.ofInt(this, "scrollY", this.getChildAt(0).height).setDuration(2000).start()
}

使用

如果你的滚动视图已经布局

my_scroll_view.scrollToBottom()

如果你的滚动视图没有完成布局(例如:你滚动到底部的活动onCreate方法…)

my_scroll_view.post { 
   my_scroll_view.scrollToBottom()          
}

其他回答

我增加工作完美。

    private void sendScroll(){
        final Handler handler = new Handler();
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {Thread.sleep(100);} catch (InterruptedException e) {}
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        scrollView.fullScroll(View.FOCUS_DOWN);
                    }
                });
            }
        }).start();
    }

Note

这个答案是一个非常老版本的android的变通方案。今天postDelayed已经没有这个bug了,你应该使用它。

最适合我的是

scroll_view.post(new Runnable() {
     @Override
     public void run() {
         // This method works but animates the scrolling 
         // which looks weird on first load
         // scroll_view.fullScroll(View.FOCUS_DOWN);

         // This method works even better because there are no animations.
         scroll_view.scrollTo(0, scroll_view.getBottom());
     }
});

有人说scrollView。Post没用。

如果你不想用scrollView。postDelayed,另一种选择是使用侦听器。下面是我在另一个用例中所做的:

ViewTreeObserver.OnPreDrawListener viewVisibilityChanged = new ViewTreeObserver.OnPreDrawListener() {
    @Override
    public boolean onPreDraw() {
        if (my_view.getVisibility() == View.VISIBLE) {
            scroll_view.smoothScrollTo(0, scroll_view.getHeight());
        }
        return true;
    }
};

你可以这样把它添加到视图中:

my_view.getViewTreeObserver().addOnPreDrawListener(viewVisibilityChanged);

这里有一些滚动到底部的其他方法

fun ScrollView.scrollToBottom() {
    // use this for scroll immediately
    scrollTo(0, this.getChildAt(0).height) 

    // or this for smooth scroll
    //smoothScrollBy(0, this.getChildAt(0).height)

    // or this for **very** smooth scroll
    //ObjectAnimator.ofInt(this, "scrollY", this.getChildAt(0).height).setDuration(2000).start()
}

使用

如果你的滚动视图已经布局

my_scroll_view.scrollToBottom()

如果你的滚动视图没有完成布局(例如:你滚动到底部的活动onCreate方法…)

my_scroll_view.post { 
   my_scroll_view.scrollToBottom()          
}

所有答案的组合对我来说很管用:

扩展函数PostDelayed

private fun ScrollView.postDelayed(
    time: Long = 325, // ms
    block: ScrollView.() -> Unit
) {
    postDelayed({block()}, time)
}

扩展函数measureScrollHeight

fun ScrollView.measureScrollHeight(): Int {
    val lastChild = getChildAt(childCount - 1)
    val bottom = lastChild.bottom + paddingBottom
    val delta = bottom - (scrollY+ height)
    return delta
}

扩展函数滚动底部

fun ScrollView.scrollToBottom() {
    postDelayed {
        smoothScrollBy(0, measureScrollHeight())
    }
}

注意,最小延迟应该至少325毫秒,否则滚动将会有bug(不是滚动到整个底部)。当前高度和底部之间的增量越大,延迟时间就应该越大。