13

I have a TextView with a lot of text. This TextView has maxLines set, so it only shows the first 8 or so lines. I also have a "Read More" button so I handle expanding the TextView on my own.

My problem is that sometimes the TextView scrolls a little (just half a line at a time), even though I never specified any scroll bars. This issue is made worse because the TextView is inside a ListView, so when the user scrolls the main ListView, the TextView sometimes scrolls a little, like this:

blahblah

How do I prevent the TextView from scrolling?

5 Answers5

30

I have the same problem,My solution is create a NoScrollTextView extends TextView like this

 public class NoScrollTextView extends TextView {
    public NoScrollTextView(Context context) {
        super(context);
    }

    public NoScrollTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public NoScrollTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public NoScrollTextView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @Override
    public void scrollTo(int x, int y) {
        //do nothing
    }
}

set scrollTo do nothing

In Kotlin:

class NonScrollingTextView : TextView {
    constructor(context: Context) : super(context) {}
    constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {}
    constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {}
    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes) {
    }

    override fun scrollTo(x: Int, y: Int) {
        //do nothing
    }
}
Seop Yoon
  • 2,429
  • 3
  • 14
  • 18
geass code
  • 316
  • 3
  • 4
2

So I did a little research and I don't think it's as simple as just disabling scrolling, but there are a few things you can do/try.

The first is setEnabled(false) but this will disable links and alter the text color.

The second, which I suggest trying, is using the scrollTo(int x, int y) method. Just scrollTo(0,0) after setting the text of the TextView, my guess is the large text is the only thing causing the scrolling so this should be able to take care of it.

The third answer I found that you can try is a bit more complicated and not exactly your question but it may work for you can be found here.

public class LinkMovementMethodOverride implements View.OnTouchListener{

@Override
public boolean onTouch(View v, MotionEvent event) {
    TextView widget = (TextView) v;
    Object text = widget.getText();
    if (text instanceof Spanned) {
        Spanned buffer = (Spanned) text;

        int action = event.getAction();

        if (action == MotionEvent.ACTION_UP
                || action == MotionEvent.ACTION_DOWN) {
            int x = (int) event.getX();
            int y = (int) event.getY();

            x -= widget.getTotalPaddingLeft();
            y -= widget.getTotalPaddingTop();

            x += widget.getScrollX();
            y += widget.getScrollY();

            Layout layout = widget.getLayout();
            int line = layout.getLineForVertical(y);
            int off = layout.getOffsetForHorizontal(line, x);

            ClickableSpan[] link = buffer.getSpans(off, off,
                    ClickableSpan.class);

            if (link.length != 0) {
                if (action == MotionEvent.ACTION_UP) {
                    link[0].onClick(widget);
                } else if (action == MotionEvent.ACTION_DOWN) {                             
                    // Selection only works on Spannable text. In our case setSelection doesn't work on spanned text
                    //Selection.setSelection(buffer, buffer.getSpanStart(link[0]), buffer.getSpanEnd(link[0]));
                }
                return true;
            }
        }

    }

    return false;
}

}

"After that apply it to the target textview as touch listener: -

textview.setOnTouchListener(new LinkMovementMethodOverride());"

Community
  • 1
  • 1
Dave S
  • 3,378
  • 1
  • 20
  • 34
0

I needed feature like see more in my project and I used ellipsizing textview from this SO post. It works like a charm and also provides an interface for checking if the text was ellipsized. This should do the trick.

Community
  • 1
  • 1
Illegal Argument
  • 10,090
  • 2
  • 44
  • 61
  • Okay I'll look into this if there's nothing else, but I already implemented the whole "read more" mechanism, so I'd rather not significantly change it. –  Jun 04 '14 at 01:20
0

Just use setMinLines() to always display whole text

Syan Law
  • 37
  • 7
-1

Try these lines of code in xml

android:isScrollContainer="false"
android:ellipsize="end"
micnubinub
  • 116
  • 1
  • 8
  • How about this : android:scrollY="0px" – micnubinub Jun 04 '14 at 01:27
  • Just tried that, it also doesn't work. The Javadoc lists that as "The *initial* vertical scroll offset, in pixels." –  Jun 04 '14 at 01:30
  • post your xml, so i can get a better picture of whats going on – micnubinub Jun 04 '14 at 01:33
  • I think i know whats going on here, you probably have a set height for either the textview, or the layout containing it. Changing the height to wrap_content instead will fix it, if that is indeed whats going on – micnubinub Jun 04 '14 at 01:40
  • Okay, I'll check/post the xml when I get to my computer. –  Jun 04 '14 at 02:05
  • But I don't think that's what going on... The whole parent view does change size depending on how much text is there. –  Jun 04 '14 at 02:06