0

I have a ScrollView with a TextView as it's child view, which changes it's span every second in Runnable called by MainActivity:

MainActivity:

// MainActivity's private members
private ConstraintLayout m_mainLayout;
private UnderlineSpan m_underlineSpan; 
private SpannableStringBuilder m_spannableStringBuilder;
private Spannable m_spannableText;
private TextView m_textView;
private ScrollView m_scrollView;
private Runnable onUpdateTime = new Runnable()
{
    @Override
    public void run()
    {
        changeTextViewSpan();

        m_mainLayout.postDelayed(onUpdateTime, 1000);
    }
};

@Override
protected void onCreate(Bundle savedInstanceState) 
{
    m_textView = new TextView(this);
    m_textView.setLayoutParams(
            new ViewGroup.LayoutParams(
                    ViewGroup.LayoutParams.WRAP_CONTENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT));
    m_scrollView.addView(m_textView );
    m_spannableStringBuilder = new SpannableStringBuilder(Html.fromHtml(html)); // load long text from HTML file
    m_textView.setText(m_spannableStringBuilder, TextView.BufferType.SPANNABLE);
    m_spannableText = (Spannable) m_textView.getText();
}

private void changeTextViewSpan()
{
    m_spannableText.setSpan(
            m_underlineSpan,
            startIndex,
            endIndex,
            Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}

MainActivity layout:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/mainLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <ScrollView
        android:id="@+id/largeTextScrollView"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginBottom="8dp">
    </ScrollView>
<SeekBar
    android:id="@+id/playbackSeekBar"
    android:layout_width="251dp"
    android:layout_height="30dp"
    android:layout_marginBottom="8dp"
    android:layout_marginEnd="8dp"
    android:layout_marginLeft="8dp"
    android:layout_marginRight="8dp"
    android:layout_marginStart="8dp"
    app:layout_constraintBottom_toTopOf="@+id/playbackControlButton"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toEndOf="@+id/durationTextView" />

<ImageButton
    android:id="@+id/playbackControlButton"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginBottom="16dp"
    android:layout_marginLeft="8dp"
    android:layout_marginStart="8dp"
    android:onClick="onClick"
    android:src="@drawable/ic_play_arrow_black_42dp"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintStart_toStartOf="parent" />

<ImageButton
    android:id="@+id/volumeImageView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginBottom="8dp"
    android:layout_marginTop="8dp"
    android:src="@drawable/ic_volume_up_black_24dp"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toStartOf="@+id/volumeBar"
    app:layout_constraintTop_toBottomOf="@+id/playbackSeekBar" />

<SeekBar
    android:id="@+id/volumeBar"
    android:layout_width="94dp"
    android:layout_height="0dp"
    android:layout_marginBottom="16dp"
    android:layout_marginEnd="8dp"
    android:layout_marginRight="8dp"
    android:layout_marginTop="16dp"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/playbackSeekBar" />

<TextView
    android:id="@+id/currentPositionTextView"
    android:layout_width="40dp"
    android:layout_height="wrap_content"
    android:layout_marginBottom="8dp"
    android:layout_marginLeft="8dp"
    android:layout_marginStart="8dp"
    android:layout_marginTop="8dp"
    android:text="0:00"
    app:layout_constraintBottom_toTopOf="@+id/playbackControlButton"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/transcriptScrollView" />

<TextView
    android:id="@+id/slashTextView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginBottom="8dp"
    android:layout_marginTop="8dp"
    android:text="/"
    app:layout_constraintBottom_toTopOf="@+id/playbackControlButton"
    app:layout_constraintStart_toEndOf="@+id/currentPositionTextView"
    app:layout_constraintTop_toBottomOf="@+id/transcriptScrollView" />

<TextView
    android:id="@+id/durationTextView"
    android:layout_width="40dp"
    android:layout_height="wrap_content"
    android:layout_marginBottom="8dp"
    android:layout_marginTop="8dp"
    android:text="0:00"
    app:layout_constraintBottom_toTopOf="@+id/playbackControlButton"
    app:layout_constraintStart_toEndOf="@+id/slashTextView"
    app:layout_constraintTop_toBottomOf="@+id/transcriptScrollView" />

<ImageButton
    android:id="@+id/trackImageButton"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginBottom="8dp"
    android:layout_marginTop="8dp"
    android:onClick="onClick"
    android:src="@drawable/ic_visibility_off_black_24dp"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toStartOf="@+id/volumeImageView"
    app:layout_constraintTop_toBottomOf="@+id/playbackSeekBar" />
</android.support.constraint.ConstraintLayout>

Now, whenever I change TextView's span, the ScrollView stops scrolling, and after span is changed, ScrollView works correctly.

What I'm trying to achieve is to change the UnderlineSpan position of the long text which is loaded from the HTML file. The size of the text don't change, but it's long enough to put it into ScrollView.

Does anyone know what to do to make it scroll smoothly?

Thanks!

arek
  • 61
  • 1
  • 5

1 Answers1

0

I am not really sure what you want to achieve.
But if you want a smooth scroll, you must set the height of your textview to a fixed size.
Then you can change textview content without changing its size every seconds.
This way the scroll must be smoothed.

  • I've added some more information to my question. The size of the text isn't changing. I use UnderlineSpan to move the underline across HTML text. The position of the underline changes every second, so when I'm scrolling text, there is a scroll lag every second. I hope everything is clear now. – arek May 28 '18 at 10:01