Android滚动视图在添加文本时的自动滚动

24

我在一个Android应用程序中有一个包含TextView的ScrollView。这个TextView将不断地按照设定的时间间隔添加文本。滚动工作正常,文本也能够正确地添加,但我想要做的是让ScrollView随着文本的添加自动向下滚动。当新文本添加到底部时,它会自动滚动到匹配的位置,并且旧文本会被推到顶部看不见。更好的方法是将文本添加到ScrollView的底部,使其向上推动旧文本,但是一步一步来。


2
好的...忽略那个。傻我一开始没有将TextView(而不是ScrollView)的重力设置为“底部”。这样做可以将新文本保持在底部并滚动以满足新文本。耶! - AndroidHopeful
3
您可以在回答中介绍您的解决方案,然后将其标记为已选择。这样,当其他人遇到相同的问题时,他们就会看到有一个解决方案。 - Shade
2
那是一个很棒的解决方案,你应该将其发布为答案。 - dylan murphy
5个回答

18
<ScrollView
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:fillViewport="true"
    >
    <TextView
        android:id="@+id/statusText"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom" />
</ScrollView>

10

我尝试了使用重力的解决方案,但当滚动到底部时,实际文本下面出现了很多空白空间。

所以这是另一种方法。您可以将TextView放在ScrollView中:

<ScrollView
    android:id="@+id/scrollView1"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1"
    android:fillViewport="true" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</ScrollView>

定义 addTextChangedListener

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {

            //some code here

        ScrollView scrollView1 = (ScrollView) findViewById(R.id.scrollView1);
        TextView textView1 = (TextView) findViewById(R.id.textView1);
        textView1.addTextChangedListener(new TextWatcher() {

        @Override
        public void afterTextChanged(Editable arg0) {
            scrollView1.fullScroll(ScrollView.FOCUS_DOWN);
            // you can add a toast or whatever you want here
        }

        @Override
        public void beforeTextChanged(CharSequence arg0, int arg1,
                int arg2, int arg3) {
            //override stub
        }

        @Override
        public void onTextChanged(CharSequence arg0, int arg1, int arg2,
                int arg3) {
            //override stub
        }

    }) }

实际上,我现在注意到每当文本被更改时,应用程序都会滚动,而不仅仅是添加。不过对我来说,它完全正常。


这个是唯一对我有效的(API 23)。android:layout_gravity="bottom" 的技巧让我无法手动向上滚动,并在文本下方添加了大量空白。这个不会添加任何空白,并允许正常滚动。 - Shlublu

3

当文本被添加时,您可以简单地将整个ScrollView向下滚动到底部。

textView.append(text);
scrollView.fullScroll(View.FOCUS_DOWN);

就像@RaphaelRoyer-Rivard在他的评论中建议的那样,您可以使用post获得更可靠的结果:

textView.append(text);
scrollView.post(() -> scrollView.fullScroll(View.FOCUS_DOWN));

2
不要忘记在scroll.post调用中调用fullScroll。 - Raphael Royer-Rivard

0

如果你正在寻找一个更通用的自动滚动到ScrollView底部的方法,可以尝试下面的代码片段。它的优点是不需要发布Runnable以确保在UI线程中运行。缺点是我不确定这可能会破坏什么。

public class AutoScroller extends ScrollView {
    public boolean autoscroll = true;

    public AutoScroller(Context context) {super(context);}
    public AutoScroller(Context context, AttributeSet attrs) {super(context,attrs);}
    public AutoScroller(Context context, AttributeSet attrs, int defStyleAttr){super(context, attrs, defStyleAttr);}
    public AutoScroller(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {super(context, attrs, defStyleAttr, defStyleRes);}


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        if(autoscroll) {
           scrollTo(getScrollX(), getChildAt(getChildCount()-1).getBottom() - getHeight());
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
}

另一个可能需要重写的候选是onLayout


-1
textView.append(text);
scroll.fullScroll(View.FOCUS_DOWN)

这会有问题,由于 android:layout_gravity="bottom",它不能滚动到最顶部。


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