Order and Un Order List in Android Textview Kotlin

Published January 22, 2021

Display items in list is most common scenario in any application. This list can be an Order List or Un Order List.

How we will achieve this order or un order list in Android TextView.

This post we will cover how to achieve order/un order list with TextView.

 

Bullet List

Let say if we want to display list with bullet points.

  • Un Order List Item 1
  • Un Order List Item 2
  • Un Order List Item 3

Android provided one simple class called Spannable class where we can revamp the text in different styles.

 

Create Bullet List with SpannableStringBuilder and BulletSpan()

Suppose we have te List with data like

val items =arrayOf (" Un Order List Item 1", " Un Order List Item 2", " Un Order List Item 3")

 

To Make the Bullet List data we use below code

val items =arrayOf (" Un Order List Item 1", " Un Order List Item 2", " Un Order List Item 3")
var builder =  SpannableStringBuilder()
items.forEach { item ->
    builder.append(
            item + "\n\n", // Add some linebreaks
            BulletSpan(), // Add the bullet point span
            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
    )
}

 

Now let's append this SpannableStringBuilder object to TextView. This will return output like below

 

 

BulletSpan implements LeadingMarginSpan, which basically offsets your text.

 

In case you’d like to set the offset area manually or set the color of the bullet point, simply use the optionalgapWidth and color parameters of BulletSpan

 

Number List

  1. Un Order List Item 1
  2. Un Order List Item 2
  3. Un Order List Item 3

 

To display number list is same like bullet list, but we approach different way to make this number list, why because Android doesn't have any specific Spannable to make this list type.

 

So Let's create a Custom class which will extends LeadingMarginSpan  and Override two methods to handle the logic

override fun drawLeadingMargin(
    canvas: Canvas,
    paint: Paint,
    x: Int,
    dir: Int,
    top: Int,
    baseline: Int,
    bottom: Int,
    text: CharSequence,
    start: Int,
    end: Int,
    first: Boolean,
    layout: Layout
) {

}

 

override fun getLeadingMargin(first: Boolean): Int = width

 

To display the number infront of the each line we need to write below code

val spanStart = (text as Spanned).getSpanStart(this)
val isFirstCharacter = spanStart == start

// If so, draw the text in the leading span
if (isFirstCharacter) {
    canvas.drawText(leadingText, x.toFloat(), baseline.toFloat(), paint)
}

 

Then again follow the above process to set the text for the TextView

 

val txt_order=findViewById<TextView>(R.id.txt_order);
  txt_unorder.setText(builder)


builder =  SpannableStringBuilder()
  items.forEachIndexed { index, item ->
      builder.append(
          item + "\n\n",
          OrderedListSpan(30, "$index."),
          Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
      )
  }
  txt_order.setText(builder)

 

Order List Android TextView

 

Complete TextView Order List Example

 

Activity.kt

package com.rrtutors.inappreview

import android.graphics.Canvas
import android.graphics.Paint
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.text.Layout
import android.text.Spannable
import android.text.SpannableStringBuilder
import android.text.Spanned
import android.text.style.BulletSpan
import android.text.style.LeadingMarginSpan
import android.widget.TextView

class OrderListAndroid : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_order_list_android)
        val items =arrayOf (" Un Order List Item 1", " Un Order List Item 2", " Un Order List Item 3")
        var builder =  SpannableStringBuilder()
        items.forEach { item ->
            builder.append(
                    item + "\n\n", // Add some linebreaks
                    BulletSpan(), // Add the bullet point span
                    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
            )
        }

        val txt_unorder=findViewById<TextView>(R.id.txt_unorder);
        val txt_order=findViewById<TextView>(R.id.txt_order);
        txt_unorder.setText(builder)


      builder =  SpannableStringBuilder()
        items.forEachIndexed { index, item ->
            builder.append(
                item + "\n\n",
                OrderedListSpan(30, "$index."),
                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
            )
        }
        txt_order.setText(builder)
    }



}

 

OrderedListSpan.kt
package com.rrtutors.inappreview

import android.graphics.Canvas
import android.graphics.Paint
import android.text.Layout
import android.text.Spanned
import android.text.style.LeadingMarginSpan

class OrderedListSpan(
    private val width: Int,
    private val leadingText: String
) : LeadingMarginSpan {

    override fun drawLeadingMargin(
        canvas: Canvas,
        paint: Paint,
        x: Int,
        dir: Int,
        top: Int,
        baseline: Int,
        bottom: Int,
        text: CharSequence,
        start: Int,
        end: Int,
        first: Boolean,
        layout: Layout
    ) {
        // Check if we're at the start of the span
        val spanStart = (text as Spanned).getSpanStart(this)
        val isFirstCharacter = spanStart == start

        // If so, draw the text in the leading span
        if (isFirstCharacter) {
            canvas.drawText(leadingText, x.toFloat(), baseline.toFloat(), paint)
        }
    }

    override fun getLeadingMargin(first: Boolean): Int = width

}

 

Article Contributed By :
https://www.rrtutors.com/site_assets/profile/assets/img/avataaars.svg

3168 Views