• 7
name

A PHP Error was encountered

Severity: Notice

Message: Undefined index: userid

Filename: views/question.php

Line Number: 191

Backtrace:

File: /home/prodcxja/public_html/questions/application/views/question.php
Line: 191
Function: _error_handler

File: /home/prodcxja/public_html/questions/application/controllers/Questions.php
Line: 433
Function: view

File: /home/prodcxja/public_html/questions/index.php
Line: 315
Function: require_once

So, I have a TextView like so:

<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" />

I use it as a sort of running log, displayed to the user so they can monitor progress of a task that takes about 3 minutes. However, once I go over 8 lines, the text goes off screen. This is unintuitive to the user because they have no way of knowing that it went off screen, other than to manually poll by trying scroll down.

How can I make it so that every time I add some text to this TextView I make it scroll down as low as it can go?

Also, this is in Xamarin Android, but I don't think it's relevant. It's easy to translate between it and Java

From your Code, two steps have to do:

Step 1

Although you code in Xamarin Android, but as in Java in the xxxActivity.java for terminalOutput invoke must be like this

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

Method setMovementMethod() by parameter ScrollingMovementMethod() is the gimmick.

Step 2

And in the layout as in Java-Android also in activity_xxx.xml for the TextView Declaration as above must have to add this

android:gravity="bottom"

When you add new line into the outputText like this

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

It will scroll to the last line automatically, and these all the magic for your need.

  • 72
Reply Report

As per answer here Making TextView Scrollable in Android

You don't need to use a ScrollView actually.

Just set the

android:maxLines = "AN_INTEGER"

android:scrollbars = "vertical" properties of your TextView in your layout's xml file.

Then use:

yourTextView.setMovementMethod(new ScrollingMovementMethod());

in your code.

That will work..

  • 33
Reply Report
      • 2
    • I know the other answer is probably more general purpose and useful across more situations, but this answer was extremely simple and worked good enough for me
      • 1
    • Be careful to have a non-zero height for the TextView. If you set layout_height to 0dp as Android studio suggests for performance, auto-scroll will not work

None of these answers were quite what I wanted, so I came up with this.

textView.append(log);

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

Do not forget to set movement method before scrolling

textView.setMovementMethod(new ScrollingMovementMethod());
  • 7
Reply Report

Had the same question. Tried several decisions from this and similar discussions, nothing worked. Solved it this way:

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

after every .append() .

  • 6
Reply Report

You can try in 2 solutions:

  1. Put TextView in a 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. Use custom scroll TextView (same as traditional TextView but it can scroll)

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

How to use:

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

(ScrollTextView class source: http://bear-polka.blogspot.com/2009/01/scrolltextview-scrolling-textview-for.html)

  • 5
Reply Report

I am using Xmarin.

My solution is as many people mentioned, to textView inside a ScrollView.

If you want to see the new line at the bottom of the view, use

android:layout_gravity="bottom"

This keeps the new line at the bottom until you scroll the view. The view stays wherever you have scrolled.

No code is needed.

However, if you want the contents is always at bottom after appending, you need to add code after append():

myText.Append(...);

myscroll.FullScroll(FocusSearchDirection.Down);
  • 2
Reply Report

For me nothing worked perfectly except a combination of these two :-

  • Setting scroller.scrollTo(0, 70); in your java class.Use it before setting your textview but after appending that String. 52 dp is the height of my device.You can find it out using scroller.getBottom()); So I used 70 to adjust for the scroll view.
  • Setting android:scrollY="30dp" in your textview.
  • 0
Reply Report

In my case, nothing worked at first because I was apparently attempting to make changes to the UI (auto scrolling up after adding text that is out of view), outside of the UI thread. The words would display but with no auto scroll. Correction, setText would work but not append.

My call for auto scroll was not in a UI thread because I coded the call to be made in response to a socket onMessage call; which I run on its own thread. So, I had to enclose my function call with the following code and everything worked.

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

                     // Stuff that updates the UI

                 }
             });

I'm sure all of the methods would work in someway so long as you are running it on a UI thread. But, to achieve the autoscroll effect for a "chat room" i.e. new text at top of chat window but when amount of text is longer than the window - autoscroll up the new messages into view, i just used the ... fullScroll(View.FOCUS_DOWN) ... method.

  • 0
Reply Report