I want to display an ordered list inside a TextView, for example:
 1) item 1
 2) item 2  
Using the following layout:
         You can use this way instead:
• foo<br/>
• bar<br/>
• baz<br/>
                                                                        Here is a solution I use. You can copy and paste it into an activity to see how it works, but you should change all attributes with variables for production. You can play with the padding parameters to indent it according to your needs. Instead of digits, you can use the bullet char if you want bullet list.
<LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal" >
            <TextView
                android:id="@+id/bullet1"
                android:textStyle="bold"
                android:layout_width="30dp"
                android:gravity="right"
                android:layout_height="wrap_content"
                android:paddingRight="5dp"
                android:text="1"
                android:textSize="20dp" />
            <TextView
                android:id="@+id/bullet1Text"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:paddingBottom="10dp"
                android:text="First bullet. First bullet. First bullet. First bullet. First bullet. First bullet. First bullet. First bullet. "
                android:textSize="15dp" />
        </LinearLayout>
        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal" >
            <TextView
                android:id="@+id/bullet2"
                android:textStyle="bold"
                android:layout_width="30dp"
                android:gravity="right"
                android:layout_height="wrap_content"
                android:paddingRight="5dp"
                android:text="2"
                android:textSize="20dp" />
            <TextView
                android:id="@+id/bullet2Text"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:paddingBottom="10dp"
                android:text="Second bullet. Second bullet. Second bullet. Second bullet. Second bullet. Second bullet. Second bullet. "
                android:textSize="15dp" />
        </LinearLayout>
                                                                        Go to res/values/strings.xml then paste below code
<string name="list">
  <li>1) Item 1</li>\n
  <li>2) Item 2</li>\n
  <li>3) Item 3</li>\n
</string>
Then go to your layout file which contains TextView and replace with below code
<TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="@string/list" />
This class handles numbering in TextView and EditText and scales the number depending on the size of the text:
import android.graphics.Canvas
import android.graphics.Paint
import android.text.Layout
import android.text.Spanned
import android.text.style.AbsoluteSizeSpan
import android.text.style.LeadingMarginSpan
/**
 * Paragraph numbering.
 *
 *
 * Android seems to add the leading margin for an empty paragraph to the previous paragraph
 * (]0, 4][4, 4] --> the leading margin of the second span is added to the ]0, 4] paragraph
 * regardless of the Spanned.flags) --> therefore we ignore the leading margin for the last,
 * empty paragraph unless it's the only one
 */
class NumberSpan(nr: Int, gapWidth: Int, isEmpty: Boolean, isFirst: Boolean, isLast: Boolean)
    : LeadingMarginSpan {
    private val mNr: Int = nr
    private val mGapWidth: Int = gapWidth
    private val mIgnoreSpan: Boolean = isEmpty && isLast && !isFirst
    private var mWidth: Float = 0.toFloat()
    val value: Boolean?
        get() = java.lang.Boolean.TRUE
    override fun getLeadingMargin(first: Boolean): Int {
        return if (mIgnoreSpan) 0 else Math.max(Math.round(mWidth + 2), mGapWidth)
    }
    override fun drawLeadingMargin(c: Canvas, p: Paint, x: Int, dir: Int, top: Int, baseline: Int, bottom: Int,
                                   text: CharSequence, start: Int, end: Int, first: Boolean, l: Layout) {
        val spanned = text as Spanned
        if (!mIgnoreSpan && spanned.getSpanStart(this) == start) {
            // set paint
            val oldStyle = p.style
            val oldTextSize = p.textSize
            p.style = Paint.Style.FILL
            val textSize = determineTextSize(spanned, start, end, oldTextSize)
            p.textSize = textSize
            mWidth = p.measureText(mNr.toString() + ".")
            // draw the number
            c.drawText(mNr.toString() + ".", x.toFloat(), baseline.toFloat(), p)
            // restore paint
            p.style = oldStyle
            p.textSize = oldTextSize
        }
    }
    private fun determineTextSize(spanned: Spanned, start: Int, end: Int, defaultTextSize: Float): Float {
        // If the text size is different from default use that to determine the indicator size
        // That is determined by finding the first visible character within the list item span
        // and checking its size
        val position = firstVisibleCharIndex(spanned, start, end)
        if (position >= 0) {
            val absoluteSizeSpans = spanned.getSpans(position, position, AbsoluteSizeSpan::class.java)
            if (absoluteSizeSpans.isNotEmpty()) {
                val absoluteSizeSpan = absoluteSizeSpans[absoluteSizeSpans.size - 1]
                return absoluteSizeSpan.size.toFloat()
            }
        }
        // If there are no spans or no visible characters yet use the default calculation
        return defaultTextSize
    }
    private fun firstVisibleCharIndex(spanned: Spanned, start: Int, end: Int): Int {
        var newStart = start
        while (newStart < end) {
            if (isVisibleChar(spanned[newStart])) {
                return newStart
            }
            newStart++
        }
        return -1
    }
    private fun isVisibleChar(c: Char): Boolean {
        return when (c) {
            '\u200B', '\uFFEF' -> false
            else -> true
        }
    }
}
The code is from this library https://github.com/1gravity/Android-RTEditor (translated from Java to Kotlin). I'm the author of that library.
We can use LeadingMarginSpan directly
for example
String[] textArray = {
    "dfsdljjlfsdsdfjsdjldssdfidfsjdljasdfjfds\n",
    "sdfjdfjlkfdjdfkfjiwejojodljfldsjodsjfsdjdlf\n",
    "djsdfjsdffjdflljfjsadfdjfldfjl"
};
SpannableStringBuilder content = new SpannableStringBuilder();
int number = 1;
for (String t1 : textArray) {
    int contentStart = content.length();
    String leadingString = number + ". ";
    content.append(leadingString);
    content.append(t1);
    int contentEnd = content.length();
    content.setSpan(
            new LeadingMarginSpan.Standard(0, 66),
            contentStart,
            contentEnd,
            Spannable.SPAN_INCLUSIVE_EXCLUSIVE
    );
    number++;
}
                                                                        I think you have to do this in code. I had to subclass LeadingMarginSpan to get this to work. Here is how I did it.
private class NumberIndentSpan implements LeadingMarginSpan {
    private final int gapWidth;
    private final int leadWidth;
    private final int index;
    public NumberIndentSpan(int leadGap, int gapWidth, int index) {
        this.leadWidth = leadGap;
        this.gapWidth = gapWidth;
        this.index = index;
    }
    public int getLeadingMargin(boolean first) {
        return leadWidth + gapWidth;
    }
    public void drawLeadingMargin(Canvas c, Paint p, int x, int dir, int top, int baseline, int bottom, CharSequence text, int start, int end, boolean first, Layout l) {
        if (first) {
            Paint.Style orgStyle = p.getStyle();
            p.setStyle(Paint.Style.FILL);
            float width = p.measureText("4.");
            c.drawText(index + ".", (leadWidth + x - width / 2) * dir, bottom - p.descent(), p);
            p.setStyle(orgStyle);
        }
    }
}
Get hold of your view, and use it like this:
SpannableStringBuilder ssb = new SpannableStringBuilder();
for(String text : list) {
    int contentStart = content.length();
    content.append(text);
    content.setSpan(new NumberIndentSpan(15, 15, number), contentStart, content.length(), 0);
}
TextView view = findViewById(R.id.....);
view.setText(ssb);
Hope this helps others looking for this :-)