当我添加更多文本行时,如何使TextView自动滚动?

时间:2013-11-07 02:07:35

标签: android user-interface scroll textview

所以,我有一个像这样的TextView:

<TextView
    android:layout_width="fill_parent"
    android:layout_height="140.7dp"
    android:id="@+id/terminalOutput"
    android:layout_marginBottom="0.0dp"
    android:scrollbars="vertical"
    android:scrollbarAlwaysDrawVerticalTrack="true"
    android:maxLines="8" />

我将它用作一种运行日志,显示给用户,以便他们可以监控大约需要3分钟的任务进度。但是,一旦我超过8行,文本就会消失。这对用户来说是不直观的,因为除了通过向下滚动手动轮询之外,他们无法知道它已经离开了屏幕。

我怎样才能使每次向TextView添加一些文本时使其向下滚动到最低限度?

此外,这是在Xamarin Android中,但我不认为它是相关的。在它和Java之间进行翻译很容易

9 个答案:

答案 0 :(得分:69)

从您的代码中,有两个步骤:

第1步

虽然您在Xamarin Android中编码,但在xxxActivity.java中用于 terminalOutput 的Java中调用必须像这样

TextView outputText = (TextView) findViewById(R.id.terminalOutput);
outputText.setMovementMethod(new ScrollingMovementMethod());

方法setMovementMethod()通过参数ScrollingMovementMethod()是噱头。

第2步

在Java-Android中的布局中,如上面的TextView声明的activity_xxx.xml中必须要添加此

android:gravity="bottom"

  
    
      

将新行添加到outputText中时,如此

    
  
outputText.append("\n"+"New text line.");
  
    
      

它将自动滚动到最后一行,       这些都是你需要的魔力。

    
  

答案 1 :(得分:33)

根据这里的答案Making TextView Scrollable in Android

  

您实际上不需要使用ScrollView。

     

只需设置

即可      

android:maxLines = "AN_INTEGER"

     

android:scrollbars =“vertical”   布局的xml文件中TextView的属性。

     

然后使用:

     

yourTextView.setMovementMethod(new ScrollingMovementMethod());

     

代码。

那会有用..

答案 2 :(得分:6)

有同样的问题。从这个和类似的讨论中尝试了几个决定,没有任何效果。解决这个问题:

edtConsoleText.setSelection(edtConsoleText.getText().length());

.append()之后。

答案 3 :(得分:6)

这些答案都不是我想要的,所以我提出了这个。

textView.append(log);

while (textView.canScrollVertically(1)) {
    textView.scrollBy(0, 10);
}

不要忘记在滚动之前设置移动方法

textView.setMovementMethod(new ScrollingMovementMethod());

答案 4 :(得分:5)

您可以尝试2种解决方案:

  1. 将TextView放入ScrollView

    <ScrollView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
            <TextView
            android:id="@+id/TextView01"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Your Text" >
        </TextView>
    </ScrollView>
    
  2. 使用自定义滚动TextView(与传统TextView相同,但可以滚动)

    import android.content.Context;
    import android.graphics.Rect;
    import android.text.TextPaint;
    import android.util.AttributeSet;
    import android.view.animation.LinearInterpolator;
    import android.widget.Scroller;
    import android.widget.TextView;
    
     public class ScrollTextView extends TextView {
    
    
        // scrolling feature
        private Scroller mSlr;
    
        // milliseconds for a round of scrolling
        private int mRndDuration = 250;
    
        // the X offset when paused
        private int mXPaused = 0;
    
        // whether it's being paused
        private boolean mPaused = true;
    
        /*
         * constructor
         */
        public ScrollTextView(Context context) {
            this(context, null);
            // customize the TextView
            setSingleLine();
            setEllipsize(null);
            setVisibility(INVISIBLE);
        }
    
        /*
         * constructor
         */
        public ScrollTextView(Context context, AttributeSet attrs) {
            this(context, attrs, android.R.attr.textViewStyle);
            // customize the TextView
            setSingleLine();
            setEllipsize(null);
            setVisibility(INVISIBLE);
        }
    
        /*
         * constructor
         */
        public ScrollTextView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
            // customize the TextView
            setSingleLine();
            setEllipsize(null);
            setVisibility(INVISIBLE);
        }
    
        /**
         * begin to scroll the text from the original position
         */
        public void startScroll() {
            // begin from the very right side
            mXPaused = -1 * getWidth();
            // assume it's paused
            mPaused = true;
            resumeScroll();
        }
    
        /**
         * resume the scroll from the pausing point
         */
        public void resumeScroll() {
    
            if (!mPaused)
                return;
    
            // Do not know why it would not scroll sometimes
            // if setHorizontallyScrolling is called in constructor.
            setHorizontallyScrolling(true);
    
            // use LinearInterpolator for steady scrolling
            mSlr = new Scroller(this.getContext(), new LinearInterpolator());
            setScroller(mSlr);
    
            int scrollingLen = calculateScrollingLen();
            int distance = scrollingLen - (getWidth() + mXPaused);
            int duration = (new Double(mRndDuration * distance * 1.00000
                    / scrollingLen)).intValue();
    
            setVisibility(VISIBLE);
            mSlr.startScroll(mXPaused, 0, distance, 0, duration);
            mPaused = false;
        }
    
        /**
         * calculate the scrolling length of the text in pixel
         * 
         * @return the scrolling length in pixels
         */
        private int calculateScrollingLen() {
            TextPaint tp = getPaint();
            Rect rect = new Rect();
            String strTxt = getText().toString();
            tp.getTextBounds(strTxt, 0, strTxt.length(), rect);
            int scrollingLen = rect.width() + getWidth();
            rect = null;
            return scrollingLen;
        }
    
        /**
         * pause scrolling the text
         */
        public void pauseScroll() {
            if (null == mSlr)
                return;
    
            if (mPaused)
                return;
    
            mPaused = true;
    
            // abortAnimation sets the current X to be the final X,
            // and sets isFinished to be true
            // so current position shall be saved
            mXPaused = mSlr.getCurrX();
    
            mSlr.abortAnimation();
        }
    
        @Override
        /*
         * override the computeScroll to restart scrolling when finished so as that
         * the text is scrolled forever
         */
        public void computeScroll() {
            super.computeScroll();
    
            if (null == mSlr)
                return;
    
            if (mSlr.isFinished() && (!mPaused)) {
                this.startScroll();
            }
        }
    
        public int getRndDuration() {
            return mRndDuration;
        }
    
        public void setRndDuration(int duration) {
            this.mRndDuration = duration;
        }
    
        public boolean isPaused() {
            return mPaused;
        }
     }
    
  3. 使用方法:

    ScrollTextView scrolltext = (ScrollTextView) findViewById(R.id.YourTextView);
    

    (ScrollTextView类源:http://bear-polka.blogspot.com/2009/01/scrolltextview-scrolling-textview-for.html

答案 5 :(得分:2)

来自“How to scroll to bottom in a ScrollView on activity startup”:

final ScrollView scrollview = ((ScrollView) findViewById(R.id.scrollview));
scrollview.post(new Runnable() {
  @Override
  public void run() {
    scrollview.fullScroll(ScrollView.FOCUS_DOWN);
  }
});

您需要的是在追加操作后放置fullScroll()

答案 6 :(得分:2)

我正在使用Xmarin。

我的解决方案就像许多人提到的那样,在ScrollView中的textView。

如果要在视图底部看到新行,请使用

android:layout_gravity="bottom"

这会将新行保留在底部,直到您滚动视图。视图保留在您滚动的任何位置。

无需代码。

但是,如果你希望在追加后内容总是在底部,你需要在append()之后添加代码:

myText.Append(...);

myscroll.FullScroll(FocusSearchDirection.Down);

答案 7 :(得分:0)

对我来说,除了这两者的组合之外,没有什么能够完美地运作: -

  • 在java类中设置scroller.scrollTo(0, 70);。在设置textview之前但在追加该字符串之后使用它。 52 dp是我的设备的高度。你可以使用scroller.getBottom())找到它。所以我用70来调整滚动视图。
  • 在文字视图中设置android:scrollY="30dp"

答案 8 :(得分:0)

就我而言,起初没有任何作用,因为我显然试图在UI线程外对UI进行更改(添加看不见的文本后自动向上滚动)。这些单词将显示,但不会自动滚动。更正后,setText将起作用,但不能追加。

我的自动滚动调用不在UI线程中,因为我将调用编码为响应套接字onMessage调用。我在自己的线程上运行。因此,我必须在函数调用中加上以下代码,一切正常。

 runOnUiThread(new Runnable() {
                 @Override
                 public void run() {

                     // Stuff that updates the UI

                 }
             });

我确信只要您在UI线程上运行所有方法,它们都会以某种方式起作用。但是,要实现“聊天室”的自动滚动效果,即在聊天窗口顶部添加新文本,但是当文本量大于窗口时-将新消息自动滚动到视图中,我只使用了... fullScroll(View .FOCUS_DOWN)...方法。