Search code examples
javaandroidandroid-recyclerviewtextviewspannable

Improving spanned/spannable performance in setting TextView RecylcerView


I have a RecyclerView with a number of TextViews. One of these TextViews is populated with a Spanned, via a marked up String taken from an ArrayList<Object>. After reading this tutorial by Florina Muntenescu, I realize I can likely improve my performance by using Spannable Factory. My biggest problem is that her code is written in Kotlin (and I'm not quite there yet).

As far as I can tell, this is the key information,

Let’s say that we want to reuse a TextView and set the text multiple times, like in a RecyclerView.ViewHolder...

val spannableFactory = object : Spannable.Factory() {
    override fun newSpannable(source: CharSequence?): Spannable {
        return source as Spannable
    }
}`

Set the Spannable.Factory object once right after you get a reference to your TextView. If you’re using a RecyclerView, do this when you first inflate your views.

textView.setSpannableFactory(spannableFactory)

So, suppose I have this simple RecyclerView adapter setting a single Spanned TextView.

@Override
public void onBindViewHolder(RecyclerViewHolder rvh, int position){

    String string =arrayList.get(position).getValue();
    Spanned spanned = getSpannedValue(string);
    rvh.tv.setText(spanned);
}

How can I change my code to utilize the recommendation from Florina?


Solution

  • In java you should just override method newSpannable, in its implementation cast source (CharSequence) to Spannable and set this factory to TextView (tvText in my case)

           tvText.setSpannableFactory(new Spannable.Factory(){
                @Override
                public Spannable newSpannable(CharSequence source) {
                    return (Spannable) source;
                }
            });
    

    Keep in mind, it should be set from ViewHolder's constructor, not onBindViewHolder. When you get reference to it by findViewById.