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.
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
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)
|
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 :
|
|
|
|
3490 Views |