Muhammad Maqsoodur Rehman
Muhammad Maqsoodur Rehman

Reputation: 34257

Making TextView scrollable on Android

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

Upvotes: 920

Views: 731720

Answers (30)

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

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

Upvotes: 1

FoxDonut
FoxDonut

Reputation: 466

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

Upvotes: 3

Mori
Mori

Reputation: 4611

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()

Upvotes: 17

l3l_aze
l3l_aze

Reputation: 613

For a vertically or horizontally scrollable TextView some of the other answers help, but I needed to be able to scroll both ways.

What finally worked is a ScrollView with a HorizontalScrollView inside of it, and a TextView inside the HSV. It's very smooth and can easily go side to side or top to bottom in one swipe. It also only allows scrolling in one direction at a time so there's none of the jumping side to side while scrolling up or down.

An EditText with editing and cursor disabled works, but it feels terrible. Each attempt to scroll moves the cursor and it requires many swipes to go top to bottom or side to side in even a ~100-line file.

Using setHorizontallyScrolling(true) can work, but there's no similar method to allow vertical scrolling, and it doesn't work inside of a ScrollView as far as I can tell (just learning though, could be wrong).

Upvotes: 0

Exutic
Exutic

Reputation: 121

yourtextView.setMovementMethod(new ScrollingMovementMethod());

you can scroll it now.

Upvotes: 7

Raluca Lucaci
Raluca Lucaci

Reputation: 2153

In kotlin for making the textview scrollable

myTextView.movementMethod= ScrollingMovementMethod()

and also add in xml this property

    android:scrollbars = "vertical"

Upvotes: 11

mohamad sheikhi
mohamad sheikhi

Reputation: 394

Try this:

android:scrollbars = "vertical"

Upvotes: 0

hash
hash

Reputation: 5406

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)

Upvotes: 0

Amit Chintawar
Amit Chintawar

Reputation: 20688

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!

Upvotes: 2020

Prince Dholakiya
Prince Dholakiya

Reputation: 3391

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

Upvotes: 1

Rohit Mandiwal
Rohit Mandiwal

Reputation: 10462

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

Upvotes: 3

Khemraj Sharma
Khemraj Sharma

Reputation: 58934

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

Upvotes: 1

Kamil Ibadov
Kamil Ibadov

Reputation: 710

Use it like this

<TextView  
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:maxLines = "AN_INTEGER"
    android:scrollbars = "vertical"
/>

Upvotes: 1

MBH
MBH

Reputation: 16609

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

Upvotes: 21

Ahsan Raza
Ahsan Raza

Reputation: 495

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

Upvotes: 47

Petro
Petro

Reputation: 3642

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

Upvotes: 0

user3921740
user3921740

Reputation: 550

Add the following in the textview in XML.

android:scrollbars="vertical"

And finally, add

textView.setMovementMethod(new ScrollingMovementMethod());

in the Java file.

Upvotes: 9

Ritesh
Ritesh

Reputation: 105

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

Upvotes: 4

Dipendra
Dipendra

Reputation: 1557

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.

Upvotes: 10

Rahul Baradia
Rahul Baradia

Reputation: 11951

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

Upvotes: 5

mOmO
mOmO

Reputation: 186

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...

Upvotes: 15

Valentin Galea
Valentin Galea

Reputation: 1094

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.

Upvotes: 30

Someone Somewhere
Someone Somewhere

Reputation: 23787

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

Upvotes: 341

EddieB
EddieB

Reputation: 5001

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

Upvotes: 120

Samuh
Samuh

Reputation: 36484

You can either

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

Upvotes: 29

Sasha_NY
Sasha_NY

Reputation: 1

In my case.Constraint Layout.AS 2.3.

Code implementation:

YOUR_TEXTVIEW.setMovementMethod(new ScrollingMovementMethod());

XML:

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

Upvotes: 0

whitepearl
whitepearl

Reputation: 644

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

Upvotes: 2

Mark Cramer
Mark Cramer

Reputation: 2854

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.

Upvotes: 11

matasoy
matasoy

Reputation: 696

Make your textview just adding this

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

Upvotes: 51

IT-Dan
IT-Dan

Reputation: 565

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

Upvotes: 11

Related Questions