918

I am displaying text in a TextView that appears to be too long to fit into one screen. I need to make my TextView scrollable. How can I do that?

Here is the code:

final TextView tv = new TextView(this);
tv.setBackgroundResource(R.drawable.splash);
tv.setTypeface(face);
tv.setTextSize(18);
tv.setTextColor(R.color.BROWN);
tv.setGravity(Gravity.CENTER_VERTICAL| Gravity.CENTER_HORIZONTAL);
tv.setOnTouchListener(new OnTouchListener() {
    public boolean onTouch(View v, MotionEvent e) {
        Random r = new Random();
        int i = r.nextInt(101);
        if (e.getAction() == e.ACTION_DOWN) {
            tv.setText(tips[i]);
            tv.setBackgroundResource(R.drawable.inner);
        }
        return true;
    }
});
setContentView(tv);
0

32 Answers 32

2018

You don't need to use a ScrollView actually.

Just set the

android:scrollbars = "vertical"

properties of your TextView in your layout's xml file.

Then use:

yourTextView.setMovementMethod(new ScrollingMovementMethod());

in your code.

Bingo, it scrolls!

29
  • 106
    But surely maxLines requires you to enter an arbitrary number; this isn't something that will work for every screen size and font size? I find it simpler to just wrap it with a ScrollView, meaning I don't have to add any further XML attributes or code (like setting the movement method). Commented Dec 19, 2010 at 22:57
  • 14
    @Christopher, ScrollView requires 'android:layout_height' too. Commented Mar 4, 2011 at 16:39
  • 12
    @Regex: Well yes. Either you let the ScrollView take up as much space as it needs (e.g. via the android:fillViewport attribute), or you set the specific size you want. Using maxLines should not be used to set sizes of UI elements, so that is no solution. Commented Mar 5, 2011 at 12:18
  • 65
    you dont need to define maxlines. just the rest.
    – Stevanicus
    Commented Jun 8, 2011 at 13:38
  • 27
    To clarify what everyone is saying about "smooth" scrolling: If you use this method scrolling is actually "smooth" (in that you can scroll pixel by pixel), however it is not kinetic. As soon as you remove your finger it stops scrolling instantly - there is no flicking. This is pretty unacceptable for a modern UI so I'm going to edit the answer to make sure other people don't waste time on this "solution".
    – Timmmm
    Commented Nov 9, 2015 at 15:39
341

This is how I did it purely in XML:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <ScrollView
        android:id="@+id/SCROLLER_ID"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:scrollbars="vertical"
        android:fillViewport="true">

        <TextView
            android:id="@+id/TEXT_STATUS_ID"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:layout_weight="1.0"/>
    </ScrollView>
</LinearLayout>

NOTES:

  1. android:fillViewport="true" combined with android:layout_weight="1.0" will make the textview take up all available space.

  2. When defining the Scrollview, DO NOT specify android:layout_height="fill_parent" otherwise the scrollview doesn't work! (this has caused me to waste an hour just now! FFS).

PRO TIP:

To programmatically scroll to the bottom after appending text, use this:

mTextStatus = (TextView) findViewById(R.id.TEXT_STATUS_ID);
mScrollView = (ScrollView) findViewById(R.id.SCROLLER_ID);

private void scrollToBottom()
{
    mScrollView.post(new Runnable()
    {
        public void run()
        {
            mScrollView.smoothScrollTo(0, mTextStatus.getBottom());
        }
    });
}
6
  • 13
    There's no need to use mTextView.getBottom(), just use the method mScrollView.fullScroll(View.FOCUS_DOWN) as it is a part of the ScrollView API. See here and here for more info.
    – ChuongPham
    Commented Sep 11, 2013 at 19:59
  • 9
    Android warns that either the LinearLayout or the ScrollView may be useless in this example (I removed the LinearLayout completely). It also warns that for the TextView, it should be android:layout_height="wrap_content" to match the ScrollView. These warnings may be due to the 3 years that have passed since this answer was posted. Regardless, this answer supports smooth scrolling and flicking...+1
    – nikodaemus
    Commented Dec 30, 2014 at 23:43
  • Adding <!--suppress AndroidLintUselessParent --> above the ScrollView in the xml file will take care of those warnings. Commented Aug 12, 2015 at 20:10
  • The "pro tip" doesn't work for me, in Android API level 9. The textview stays scrolled to the top after appending text.
    – LarsH
    Commented Apr 21, 2016 at 19:14
  • This approach is much better using the accepted answer approach will not produce a smooth user experience.
    – smrf
    Commented Oct 12, 2019 at 7:13
120

All that is really necessary is the setMovementMethod(). Here's an example using a LinearLayout.

File main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<TextView
    android:id="@+id/tv1"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:text="@string/hello"
    />
</LinearLayout>

File WordExtractTest.java

public class WordExtractTest extends Activity {

    TextView tv1;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        tv1 = (TextView)findViewById(R.id.tv1);

        loadDoc();
    }

    private void loadDoc() {

        String s = "";

        for(int x=0; x<=100; x++) {
            s += "Line: " + String.valueOf(x) + "\n";
        }

        tv1.setMovementMethod(new ScrollingMovementMethod());

        tv1.setText(s);
    }
}
7
  • 3
    Is there any way to set this property in XML? I wonder why they would leave out that option.
    – Thalur
    Commented Nov 22, 2011 at 16:16
  • It works but Is der any way to refresh it after scrolling? i mean after scrolling the TextView i am going to change text on it, but its position remains scrolled even if it is not required. its bcose previously i had applied scroll... Commented Nov 23, 2011 at 10:03
  • 10
    no scroll bars, and scrolling is clunky compared to the ScrollView method. Commented Sep 14, 2012 at 21:59
  • 1
    Use a StringBuilder instead of a String... what you have is a little wasteful. Commented Oct 7, 2012 at 5:36
  • 4
    this works but the scrolling is not smooth. Still works though thanks. Commented Jul 15, 2014 at 14:36
51

Make your textview just adding this

TextView textview= (TextView) findViewById(R.id.your_textview_id);
textview.setMovementMethod(new ScrollingMovementMethod());
4
  • 17
    This does not do kinetic scrolling. Do not use this.
    – Timmmm
    Commented Nov 10, 2015 at 14:26
  • 3
    @Timmmm how to get the kinetic scroll? Commented Feb 5, 2016 at 21:29
  • 2
    You don't want "kinetic scrolling" for a text that has to be read. Commented Mar 20, 2018 at 9:57
  • @TheincredibleJan yes, you sometimes do
    – Chisko
    Commented Sep 11, 2023 at 20:48
47

It is not necessary to put in

android:Maxlines="AN_INTEGER"`

You can do your work by simply adding:

android:scrollbars = "vertical"

And, put this code in your Java class:

textview.setMovementMethod(new ScrollingMovementMethod());
3
  • Much better solution than the accepted one, as the scrollbar size exactly fits the text and you don't waste space.
    – FractalBob
    Commented Apr 5, 2017 at 1:02
  • when i am using ScrollView as parent, that time its not working Commented Jul 12, 2018 at 12:20
  • i wonder if the textview is vertically loong... just like the discussion here. But what if we want to focus (display) to the specific location of the text located at ...? is it available just like in html with ID #anchoring...? in android... textview is that possible? @AhsanRaza
    – gumuruh
    Commented Apr 11, 2022 at 8:17
30

The best way I found:

Replace the TextView with an EditText with these extra attributes:

android:background="@null"
android:editable="false"
android:cursorVisible="false"

There is no need for wrapping in a ScrollView.

7
  • 4
    Easily the best and most appropriate answer, especially considering that EditText is a TextView subclass and the question is how to make the textview scrollable, not how to work around the problem. Would vote up twice if I could :) Commented Jul 8, 2012 at 15:38
  • 5
    @JustinBuser Couldn't disagree more. :) It's purely serendipitous that this works, and there's no guarantee it will in future versions of Android. If you want scrolling, use the scrolling tools that Android provides. ScrollView is the correct way to go.
    – Madbreaks
    Commented Oct 24, 2012 at 0:53
  • 1
    @Madbreaks There is nothing "serendipitous" about it, EditText IS a TextView with a few added methods and overrides that is specifically tailored to accommodate varying length text. In particular EditText overrides the return value for the TextView getDefaultMovementMethod function. The default implementation returns NULL, EditText basically does the same thing all these other answers are suggesting. As far as using the tools that Android provides is concerned, the EditText class is far less likely to become deprecated than any of the other methods found in these answers. Commented Oct 27, 2012 at 14:32
  • 4
    @JustinBuser My problem with that though is you're depending on the default behavior of EditText, that is what I meant may very well change down the road (not at all that EditText would be deprecated). You can argue that, but again, the idea is to use components and features that are appropriate for the task at hand. ScrollView was explicitly designed to encompass scrolling. I always try to, and always suggest others use the right tool for the job. There are almost always multiple approaches to any given programming problem. Anyway, thanks for the thoughtful response.
    – Madbreaks
    Commented Oct 29, 2012 at 17:57
  • 9 years later still working, so I guess the scenarios in the comments didn't happen (yet)
    – Alberto M
    Commented Jul 21, 2021 at 13:44
29

You can either

  1. surround the TextView by a ScrollView; or
  2. set the Movement method to ScrollingMovementMethod.getInstance();.
21

Simple. This is how I did it:

  1. XML Side:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        tools:context="com.mbh.usbcom.MainActivity">
        <TextView
            android:id="@+id/tv_log"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:scrollbars="vertical"
            android:text="Log:" />
    </RelativeLayout>
    
  2. Java side:

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

Bonus:

To let the text view scroll down as the text fill it, you have to add:

    android:gravity="bottom"

to the TextView xml file. It will scroll down automatically as more text comes in.

Of course you need to add the text using the append function instead of set text:

    tv_log.append("\n" + text);

I used it for Log purpose.

I hope this helps ;)

17

If you use Kotlin , in this way : XML

 <TextView
            android:id="@+id/tvMore"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:maxLines="3"
            android:scrollbars="vertical" />

Activity

tvMore.movementMethod = ScrollingMovementMethod()
1
  • This makes fling scroll impossible. In case the text is very large, scrolling is a pain
    – Chisko
    Commented Sep 11, 2023 at 20:45
15

This is "How to apply ScrollBar to your TextView", using only XML.

First, you need to take a Textview control in the main.xml file and write some text into it ... like this:

<TextView
    android:id="@+id/TEXT"
    android:layout_height="wrap_content"
    android:layout_width="wrap_content"
    android:text="@string/long_text"/>

Next, place the text view control in between the scrollview to display the scroll bar for this text:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_height="wrap_content"
    android:layout_width="fill_parent">

    <ScrollView
        android:id="@+id/ScrollView01"
        android:layout_height="150px"
        android:layout_width="fill_parent">

        <TextView
            android:id="@+id/TEXT"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"
            android:text="@string/long_text"/>

    </ScrollView>
</RelativeLayout>

That's it...

1
  • 7
    Why even write this? This is an almost identical, albeit less correct, version of an answer that was posted over 6 months before you wrote it. Commented Jul 8, 2012 at 14:44
11

This will provide smooth scrolling text with a scroll bar.

ScrollView scroller = new ScrollView(this);
TextView tv = new TextView(this);
tv.setText(R.string.my_text);
scroller.addView(tv);
1
  • Enables blue animation. Best answer here IMO.
    – Griffin
    Commented Apr 22, 2013 at 4:28
11

The "pro tip" above from Someone Somewhere (Making TextView scrollable on Android) works great, however, what if you're dynamically adding text to the ScrollView and would like to automatically scroll to the bottom after an append only when the user is at the bottom of the ScrollView? (Perhaps because if the user has scrolled up to read something you don't want to automatically reset to the bottom during an append, which would be annoying.)

Anyway, here it is:

if ((mTextStatus.getMeasuredHeight() - mScrollView.getScrollY()) <=
        (mScrollView.getHeight() + mTextStatus.getLineHeight())) {
    scrollToBottom();
}

The mTextStatus.getLineHeight() will make it so that you don't scrollToBottom() if the user is within one line from the end of the ScrollView.

11

In kotlin for making the textview scrollable

myTextView.movementMethod= ScrollingMovementMethod()

and also add in xml this property

    android:scrollbars = "vertical"
10

If you want text to be scrolled within the textview, then you can follow the following:

First you should have to subclass textview.

And then use that.

Following is an example of a subclassed textview.

public class AutoScrollableTextView extends TextView {

    public AutoScrollableTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        setEllipsize(TruncateAt.MARQUEE);
        setMarqueeRepeatLimit(-1);
        setSingleLine();
        setHorizontallyScrolling(true);
    }

    public AutoScrollableTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        setEllipsize(TruncateAt.MARQUEE);
        setMarqueeRepeatLimit(-1);
        setSingleLine();
        setHorizontallyScrolling(true);
    }

    public AutoScrollableTextView(Context context) {
        super(context);
        setEllipsize(TruncateAt.MARQUEE);
        setMarqueeRepeatLimit(-1);
        setSingleLine();
        setHorizontallyScrolling(true);
    }

    @Override
    protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
        if(focused)
            super.onFocusChanged(focused, direction, previouslyFocusedRect);
    }

    @Override
    public void onWindowFocusChanged(boolean focused) {
        if(focused)
            super.onWindowFocusChanged(focused);
    }

    @Override
    public boolean isFocused() {
        return true;
    }
}

Now, you have to use that in the XML in this way:

 <com.yourpackagename.AutoScrollableTextView
     android:layout_width="fill_parent"
     android:layout_height="wrap_content"
     android:text="This is very very long text to be scrolled"
 />

That's it.

9

Add the following in the textview in XML.

android:scrollbars="vertical"

And finally, add

textView.setMovementMethod(new ScrollingMovementMethod());

in the Java file.

1
  • 2
    This does not do kinetic scrolling. Do not use it.
    – Timmmm
    Commented Nov 10, 2015 at 14:27
7
yourtextView.setMovementMethod(new ScrollingMovementMethod());

you can scroll it now.

1
6

I didn't find TextView scrolling to support the 'fling' gesture, where it continues scrolling after a flick up or down. I ended up implementing that myself because I didn't want to use a ScrollView for various reasons, and there didn't seem to be a MovementMethod that both allowed me to select text and click on links.

1
  • 6
    soo... how did you add the fling gesture?
    – Lou Morda
    Commented Nov 20, 2014 at 22:59
5

When you are done with scrollable, add this line to the view's last line when you enter anything in the view:

((ScrollView) findViewById(R.id.TableScroller)).fullScroll(View.FOCUS_DOWN);
1
  • dude,tablescroller is a view that was identified by the id attribute from the XML that was processed in .. u just try it.. it ll work fine.. its works fr me.. Commented Jul 9, 2012 at 4:15
4

If you don't want to use the EditText solution then you might have better luck with:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.yourLayout);
    (TextView)findViewById(R.id.yourTextViewId).setMovementMethod(ArrowKeyMovementMethod.getInstance());
}
4

Add this to your XML layout:

android:ellipsize="marquee"
android:focusable="false"
android:marqueeRepeatLimit="marquee_forever"
android:scrollHorizontally="true"
android:singleLine="true"
android:text="To Make An textView Scrollable Inside The TextView Using Marquee"

And in code you have to write the following lines:

textview.setSelected(true);
textView.setMovementMethod(new ScrollingMovementMethod());
3
  • 3
    This does not do kinetic scrolling. Do not use it.
    – Timmmm
    Commented Nov 10, 2015 at 14:28
  • i dont want to ellipsize the end text. how do i do it. Commented Aug 10, 2016 at 4:33
  • @SagarNayak use android:ellipsize="none"
    – Francis
    Commented Nov 5, 2018 at 11:49
3

I had this problem when I was using TextView inside the ScrollView. This solution has worked for me.

scrollView.setOnTouchListener(new View.OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent event) {

                description.getParent().requestDisallowInterceptTouchEvent(false);

                return false;
            }
        });

        description.setOnTouchListener(new View.OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent event) {

                description.getParent().requestDisallowInterceptTouchEvent(true);

                return false;
            }
        });
3

I know this is an older post, but this is how I am handling the issue on the Java side.

    // Allow textView to scroll
    tv.setSingleLine(true);
    tv.setHorizontallyScrolling(true);
    tv.setEllipsize(TextUtils.TruncateAt.MARQUEE);
    tv.setMarqueeRepeatLimit(-1); // Infinite
    // TextView must be 'selected'
    tv.setSelected(true);
    // Padding not necessary, but this helps so the text isn't right
    // up against the side of a screen/layout
    tv.setPadding(10, 0, 10, 0);
2

The code below creates an automatic horizontal scrolling textview:

While adding TextView to xml use

<TextView android:maxLines="1" 
          android:ellipsize="marquee"
          android:scrollHorizontally="true"/>

Set the following properties of TextView in onCreate()

tv.setSelected(true);
tv.setHorizontallyScrolling(true); 
1

Use it like this

<TextView  
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:maxLines = "AN_INTEGER"
    android:scrollbars = "vertical"
/>
2
  • AN_INTEGER' is incompatible with attribute maxLines (attr) integer min=0.
    – Fortran
    Commented Jun 11, 2021 at 19:47
  • what is AN_INTEGER?
    – Fortran
    Commented Jun 11, 2021 at 19:48
1

Put maxLines and scrollbars inside TextView in xml.

<TextView android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:scrollbars="vertical"
    android:maxLines="5" // any number of max line here.
    />

Then in java code.

textView.setMovementMethod(new ScrollingMovementMethod());

1

whenever you need to use the ScrollView as parent, And you also use the scroll movement method with TextView.

And When you portrait to landscape your device that time occur some issue. (like) entire page is scrollable but scroll movement method can't work.

if you still need to use ScrollView as parent or scroll movement method then you also use below desc.

If you do not have any problems then you use EditText instead of TextView

see below :

<EditText
     android:id="@+id/description_text_question"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:background="@null"
     android:editable="false"
     android:cursorVisible="false"
     android:maxLines="6"/>

Here, the EditText behaves like TextView

And your issue will be resolved

1

Here is the answer in the wonderful and happy world of JetPack Compose :

LazyColumn {
        item {
            Text(
                text = "My Long Text"
            )
        }
    }
0

In my case.Constraint Layout.AS 2.3.

Code implementation:

YOUR_TEXTVIEW.setMovementMethod(new ScrollingMovementMethod());

XML:

android:scrollbars="vertical"
android:scrollIndicators="right|end"
0

I struggled with this for over a week and finally figured out how to make this work!

My issue was that everything would scroll as a 'block'. The text itself was scrolling, but as a chunk rather than line by line. This obviously didn't work for me, because it would cut off lines at the bottom. All of the previous solutions did not work for me, so I crafted my own.

Here is the easiest solution by far:

Make a class file called: 'PerfectScrollableTextView' inside a package, then copy and paste this code in:

import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.widget.TextView;

public class PerfectScrollableTextView extends TextView {

    public PerfectScrollableTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        setVerticalScrollBarEnabled(true);
        setHorizontallyScrolling(false);
    }

    public PerfectScrollableTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        setVerticalScrollBarEnabled(true);
        setHorizontallyScrolling(false);
    }

    public PerfectScrollableTextView(Context context) {
        super(context);
        setVerticalScrollBarEnabled(true);
        setHorizontallyScrolling(false);
    }

    @Override
    protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
        if(focused)
            super.onFocusChanged(focused, direction, previouslyFocusedRect);
    }

    @Override
    public void onWindowFocusChanged(boolean focused) {
        if(focused)
            super.onWindowFocusChanged(focused);
    }

    @Override
    public boolean isFocused() {
        return true;
    }
}

Finally change your 'TextView' in XML:

From: <TextView

To: <com.your_app_goes_here.PerfectScrollableTextView

3
  • 1
    100% Perfect answer. I faced the same issue as you mention in the description. apply many solutions but not work perfectly. but your solution working perfectly in every case. save my time man :) Thanks Commented Jan 2, 2020 at 12:27
  • Doesn't work at all for me. No scrolling at all. The only problem the other solutions have is the missing kinetic scrolling. Can't see how your solution fixed that.
    – Lothar
    Commented Dec 28, 2021 at 0:12
  • @Lothar I'm not sure, this was 7 years ago so I'm sure a lot has changed, sorry about that!
    – Petro
    Commented Dec 29, 2021 at 16:39
0

XML - You can use android:scrollHorizontally Attribute

Whether the text is allowed to be wider than the view (and therefore can be scrolled horizontally).

May be a boolean value, such as "true" or "false".

Prigramacaly - setHorizontallyScrolling(boolean)

Not the answer you're looking for? Browse other questions tagged or ask your own question.