【问题标题】:How can I make a TextView automatically scroll as I add more lines of text?添加更多文本行时,如何使 TextView 自动滚动?
【发布时间】:2013-11-18 13:15:42
【问题描述】:

所以,我有一个这样的 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 之间的转换很容易

【问题讨论】:

  • 我不确定,但请尝试添加android:gravity="bottom"?
  • 更改:android:layout_marginBottom="10dp" 并将重力设置为底部
  • 好吧,您的 TextView 中确实有 android:maxLines="8" 作为一行。
  • @antimo 将重力设置为底部似乎对我来说足够好
  • @AndrewT。 : 重力成功了,你为什么不把它作为一个答案。还是谢谢。

标签: android user-interface scroll textview


【解决方案1】:

从您的代码中,必须执行两个步骤:

步骤 1

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

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

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

第二步

并且在 Java-Android 中的布局中,同样在 activity_xxx.xml 中的 TextView 声明必须添加这个

android:gravity="bottom"

当您像这样在 outputText 中添加新行时:

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

它会自动滚动到最后一行, 这些都是您需要的魔法。

【讨论】:

  • ScrollingMovementMethod() 是一个真正的噱头,但是在顶部或底部没有这些 Android“终结符”的滚动文本。
  • 谢谢你帮了我很多!我的 layout_height 也设置为 android:layout_height="wrap_content"
  • 这个可行,但是手机从纵向旋转到横向后,textview内容被隐藏了。
  • 谢谢。做 outputText.setText 而不是 outputText.append,是我的罪魁祸首。
【解决方案2】:

这里的回答Making TextView Scrollable in Android

您实际上不需要使用 ScrollView。

只需设置

android:maxLines = "AN_INTEGER"

android:scrollbars = "垂直" 布局的 xml 文件中 TextView 的属性。

然后使用:

yourTextView.setMovementMethod(new ScrollingMovementMethod());

在您的代码中。

这会起作用..

【讨论】:

  • 我知道另一个答案可能更通用,并且在更多情况下有用,但是这个答案非常简单,对我来说已经足够好了
  • 很高兴能帮到你。 :)
  • 这个答案不正确,问题指的是“自动滚动”。答案如下,使用重力。
  • 注意 TextView 的高度不为零。如果您按照 Android Studio 建议的性能将 layout_height 设置为 0dp,则自动滚动将不起作用
【解决方案3】:

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

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

在每个 .append() 之后。

【讨论】:

    【解决方案4】:

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

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

    滚动前不要忘记设置移动方式

    textView.setMovementMethod(new ScrollingMovementMethod());
    

    【讨论】:

    • 如果您可以控制文本的附加位置,就像在您的示例中一样,您可以简单地跟随textView.append(log)textView.bringPointIntoView(textView.length())
    • @AlexCohn 这正是我想要的。文本从顶部开始,然后向下滚动,因为它被附加到底部,否则会离开屏幕。
    【解决方案5】:

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

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

    使用方法:

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

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

    【讨论】:

      【解决方案6】:

      来自“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()

      【讨论】:

        【解决方案7】:

        我正在使用 Xmarin。

        我的解决方案和很多人提到的一样,在 ScrollView 中使用 textView。

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

        android:layout_gravity="bottom"
        

        这会使新行保持在底部,直到您滚动视图。无论您滚动到哪里,该视图都将保持不变。

        不需要代码。

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

        myText.Append(...);
        
        myscroll.FullScroll(FocusSearchDirection.Down);
        

        【讨论】:

          【解决方案8】:

          对我来说,除了这两者的结合之外,没有什么是完美的:-

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

          【讨论】:

            【解决方案9】:

            就我而言,起初没有任何效果,因为我显然是在尝试在 UI 线程之外对 UI 进行更改(添加看不见的文本后自动向上滚动)。文字会显示,但不会自动滚动。更正, setText 可以工作但不能追加。

            我对自动滚动的调用不在 UI 线程中,因为我编写了响应套接字 onMessage 调用的调用;我在自己的线程上运行。所以,我不得不用下面的代码封装我的函数调用,一切正常。

             runOnUiThread(new Runnable() {
                             @Override
                             public void run() {
            
                                 // Stuff that updates the UI
            
                             }
                         });
            

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

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2018-07-20
              • 1970-01-01
              • 1970-01-01
              • 2014-04-01
              相关资源
              最近更新 更多