Android Read More TextView, Easy Guide

In this article I’m going to show you how to add read more/ less component to android TextView. First, let’s see why the ‘read more component’  is very important for app users.

Why Read More TextView is important?

TextView is commonly using in Android applications to display texts. Text View can expand with the content and adjust it size to accommodate the full content. In some applications, the developer needs to limit the size of the text view due to the limited space for that content. 

One way is limiting the size of the text view by defining the maximum line count. But it clips the content and there are no options for the user to view the rest of the content. Some users may get disappointed because they cannot see the full content event they need to see.

Read more/ less in the android TextView is very important when the full content is not much important for all users but you need a way to allow users to see full content if needed. 

How to create Android Read More TextView?

There are a lot of ways to do it. You may able to find some guides that implement complex custom components to achieve this. But I’m going to show you the simplest way to implement Android Read More TextView. To achieve this I’m not going to do any modification to the TextView component. I’m just tweaking the content of the text view to achieving the Android Read More TextView effect.

Another advantage of this approach is you can limit the text by character length rather limiting by line count.

Please go through the below code first. I will explain to code below.

private fun addReadMore(text: String, textView: TextView) {
  val ss = SpannableString(text.substring(0, 270) + "... read more")
  val clickableSpan: ClickableSpan = object : ClickableSpan() {
    fun onClick(view: View) {
      addReadLess(text, textView)
    }

    fun updateDrawState(ds: TextPaint) {
      super.updateDrawState(ds)
      ds.setUnderlineText(false)
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        ds.setColor(getResources().getColor(R.color.color_primary, getTheme()))
      } else {
        ds.setColor(getResources().getColor(R.color.color_primary))
      }
    }
  }
  ss.setSpan(clickableSpan, ss.length - 10, ss.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
  textView.setText(ss)
  textView.setMovementMethod(LinkMovementMethod.getInstance())
}

private fun addReadLess(text: String, textView: TextView) {
  val ss = SpannableString("$text read less")
  val clickableSpan: ClickableSpan = object : ClickableSpan() {
    fun onClick(view: View) {
      addReadMore(text, textView)
    }

    fun updateDrawState(ds: TextPaint) {
      super.updateDrawState(ds)
      ds.setUnderlineText(false)
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        ds.setColor(getResources().getColor(R.color.color_primary, getTheme()))
      } else {
        ds.setColor(getResources().getColor(R.color.color_primary))
      }
    }
  }
  ss.setSpan(clickableSpan, ss.length - 10, ss.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
  textView.setText(ss)
  textView.setMovementMethod(LinkMovementMethod.getInstance())
 }
}

I added the java code snipet as well.

private void addReadMore(final String text, final TextView textView) {
  SpannableString ss = new SpannableString(text.substring(0, 270) + "... read more");
  ClickableSpan clickableSpan = new ClickableSpan() { 
    @Override
    public void onClick(View view) {
      addReadLess(text, textView);
    }
    @Override
    public void updateDrawState(TextPaint ds) {
      super.updateDrawState(ds);
      ds.setUnderlineText(false);
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        ds.setColor(getResources().getColor(R.color.color_primary, getTheme()));
      } else {
        ds.setColor(getResources().getColor(R.color.color_primary));
      }
    }
  };
  ss.setSpan(clickableSpan, ss.length() - 10, ss.length() , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
  textView.setText(ss);
  textView.setMovementMethod(LinkMovementMethod.getInstance());
}

private void addReadLess(final String text, final TextView textView) {
  SpannableString ss = new SpannableString(text + " read less");
  ClickableSpan clickableSpan = new ClickableSpan() {
    @Override
    public void onClick(View view) {
      addReadMore(text, textView);
    }
    @Override
    public void updateDrawState(TextPaint ds) {
      super.updateDrawState(ds);
      ds.setUnderlineText(false);
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        ds.setColor(getResources().getColor(R.color.color_primary, getTheme()));
      } else {
        ds.setColor(getResources().getColor(R.color.color_primary));
      }
    }
  };
  ss.setSpan(clickableSpan, ss.length() - 10, ss.length() , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
  textView.setText(ss);
  textView.setMovementMethod(LinkMovementMethod.getInstance());
}

How this works?

Here what we do is if the text length exceeds the character limit, split the text and append ClickableSpan with “read more” label. When the user tap on the read more, the Content of the text view switch to the full content and the CliclableSpan changed to “read less“. By tapping on the read less link users can switch to the collapsed state.

Code Sample:

Finally your text view looks like this.

android read more textview

If you experience any slowness in your Android Studio, this guide on “Fine-tune Android Studio with JVM options” may help you.

Happy Coding!