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

发布于 2024-10-20 12:07:01 字数 176 浏览 5 评论 0原文

我在 Android 应用程序中有一个包含文本视图的滚动视图。此文本视图将按设定的时间间隔连续附加文本。滚动有效并且文本添加得很好,但我想做的是在添加文本时让滚动视图自动向下滚动。当新文本添加到底部时,它会自动向下滚动以匹配,而旧文本会在顶部被推到看不见的地方。更好的方法是将文本添加到滚动视图的底部,并将旧文本向上推,但一次只做一件事。

I have a scrollview containing a textview in an Android app. This textview will have text appended to it continuously at set intervals. Scrolling works and the text adds just fine, but what I'd like to do is have the scrollview autoscroll down as text is added. As new text is appended at the bottom, it automatically scrolls down to match and old text is pushed out of sight at the top. What would be even better is to add text to the bottom of the scrollview and have it push older text upward, but one thing at a time.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

油饼 2024-10-27 12:07:01
<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>
<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>
时光是把杀猪刀 2024-10-27 12:07:01

我已经尝试了重力解决方案,但结果是滚动到底部时实际文本下有很多空白空间。

所以这是另一种方式。您可以将 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
        }

    }) }

实际上,我现在注意到应用程序会在每次更改文本时滚动,而不仅仅是添加文本。然而它对我来说效果很好。

I've tried the solution with gravity but result was a lot of empty space under actual text when scroll to bottom.

So that is another way. You can place your TextView inside of 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>

And define 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
        }

    }) }

Actually i noticed right now that the application will scroll every time the text is changed, not just added. However it works just fine for me.

眼眸里的那抹悲凉 2024-10-27 12:07:01

添加文本时,您只需将整个 ScrollView 滚动到底部即可。

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

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

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

You can simply scroll the whole ScrollView to the bottom when text is added.

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

As @RaphaelRoyer-Rivard suggested in his comment, you can get more solid result with post:

textView.append(text);
scrollView.post(() -> scrollView.fullScroll(View.FOCUS_DOWN));
夕嗳→ 2024-10-27 12:07:01

如果您正在寻找一种更通用的自动滚动到 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

If you're looking for a more generic way of auto-scrolling to the bottom of a ScrollView, you could try the snippet below. It has the advantage that you don't need to post a Runnable to make sure you're in the UI thread. It has the disadvantage that I'm not sure what things this could break.

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);
    }
}

Another candidat to override might be onLayout.

临走之时 2024-10-27 12:07:01
textView.append(text);
scroll.fullScroll(View.FOCUS_DOWN)

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

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

this will give problem, it won't scroll upto extreme top, due to android:layout_gravity="bottom"

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文