Ordered lists inside an Android TextView
I want to display an ordered list inside a TextView, for example:
1) item 1
2) item 2
Using the following layout:
<TextView
android:text="<ol><li>item 1\n</li><li>item 2\n</li></ol>
/>
I get:
- item 1
- item 2
How can I change the bullets to numbers?
Thanks.
Asked by: Robert606 | Posted: 24-01-2022
Answer 1
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 content = 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(content);
Answered by: Freddie797 | Posted: 25-02-2022
Answer 2
I followed the answer by answer by @jk2K and made modifications to his code. As I need to have indentation for each bullet points,
String[] textArray = {
"dfsdljjlfsdsdfjsdjldssdfidfsjdljasdfjfds\n",
"sdfjdfjlkfdjdfkfjiwejojodljfldsjodsjfsdjdlf\n",
"djsdfjsdffjdflljfjsadfdjfldfjl"
};
SpannableStringBuilder content = new SpannableStringBuilder();
int number = 1;
for (String t1 : textArray) {
int contentStart = content.length();
content.append(t1);
int contentEnd = content.length();
content.setSpan(
new BulletSpan(10),
contentStart,
contentEnd,
Spannable.SPAN_INCLUSIVE_EXCLUSIVE
);
number++;
}
I used the BulletSpan class from android library and replaced new LeadingMarginSpan.Standard(0, 66)
with new BulletSpan(10)
which creates a BulletSpan with width. As mentioned in the BulletSpan class documentation
BulletSpan(int gapWidth)
Creates a BulletSpan based on a gap width
So you won't need anymore to append the bullet which is mentioned in the answer by @jk2K,
String leadingString = number + ". ";
content.append(leadingString);
Answered by: Thomas808 | Posted: 25-02-2022
Answer 3
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" />
Answer 4
You can use this way instead:
• foo<br/>
• bar<br/>
• baz<br/>
Answered by: Kimberly136 | Posted: 25-02-2022
Answer 5
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++;
}
Answered by: Michelle997 | Posted: 25-02-2022
Answer 6
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>
Answered by: Lenny328 | Posted: 25-02-2022
Answer 7
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.
Answered by: Michael285 | Posted: 25-02-2022Answer 8
Following @HÃ¥vard answer and facing the same issue that @Vivek modi had, I implemented the next working solution which accounts for custom fonts + line spacing extras and is written in Kotlin:
https://gist.github.com/marcelpallares/ae6285ee0dcb3f04493991dcb18d01bd
class NumberIndentSpan(
private val number: Int,
private val leadWidth: Int = 15,
private val gapWidth: Int = 30,
) : LeadingMarginSpan {
override fun getLeadingMargin(first: Boolean): Int {
return leadWidth + gapWidth
}
override fun drawLeadingMargin(
canvas: Canvas,
paint: Paint,
x: Int,
dir: Int,
top: Int,
baseline: Int,
bottom: Int,
t: CharSequence?,
start: Int,
end: Int,
first: Boolean,
layout: Layout?
) {
if (first) {
val text = "$number."
val width = paint.measureText(text)
val yPosition = baseline.toFloat()
val xPosition = (leadWidth + x - width / 2) * dir
canvas.drawText(text, xPosition, yPosition, paint)
}
}
}
I also added an extension method to use it:
fun TextView.setNumberedText(list: List<String>) {
val content = SpannableStringBuilder()
val gap = context.resources.getDimensionPixelSize(R.dimen.margin_16)
list.forEachIndexed { index, text ->
val contentStart = content.length
content.appendLine(text)
content.setSpan(NumberIndentSpan(index + 1, gapWidth = gap), contentStart, content.length, 0)
}
text = content
}
And finally a custom TextView to be able to use this from XML layouts
class OrderedListTextView @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null
) : AppCompatTextView(context, attrs) {
init {
setNumberedText(text.lines())
}
}
Answered by: Sarah306 | Posted: 25-02-2022
Similar questions
How to use Get Ordered list in android TextView
how can i get ordered list like view using android text-view.
I need to add an Ordered-List in to my activity i am using a text-view but i can't paste the html directly.so how can i get that ?
<TextView
android:Layout_Width="match_parent"
android:Layout_Width="wrap_parent"
android:text="here i want list"/>
I also tried to use string resource same result but i can get new line...
Ordered list from html in android TextView
My intention is to load HTML data into a textView as an ordered (1,2,3,4,.....n) list.But the UI shows always in bullet points rather than an ordered list. I have searched and tried to follow some solutions but nothing works. Your help would be amazing and much appreciated.
The procedure I followed is given underneath.
dataBinding.tvBody.text = HtmlCompat.fro...
android - Can I hook when user copy or paste on TextView?
When user copy or paste on TextView,
Is there anyone explains me what happen on TextView.
If some methods called while user click 'Copy' or 'Paste' in menus,
I'd like to hook them and replace them with my own one.
Here is what I want to do.
1. user copy or paste some string to my TextView.
2. some string copied and paste on my Textview.
3. Before some string is added on Textview, I want to check or change string.
Maximum line length on Android TextView
I'm putting a formatted single line text (no \n's) to a noneditable TextView. In the navigation of the program, the text can be changed. On some text, the TextView shrinks to 0x0 pixel and I can see nothing! I added some menus to truncate the text 10 characters each time and I found that if the number of characters are larger than 4470, the TextView shrinks.
Splitting the text into several lines by putting \n in be...
android - How to bind more then one column to a textview
I am curious if there is a way to bind more then one db column to a resource. I need to bind more information to R.id.secondLine then just the difficulty column. But I'm unsure how to go about this? I'm currently subclassing SimpleCursorAdapter. Should I subclass another adapter? If so How to do I go about it?
Cursor activityHikes = mDbAdapter.fetchAllHikes(false);
startManagingCursor(activityHikes)...
Android TextView Text not getting wrapped
Can anyone tell me what's going wrong with the text? Text longer than one line doesn't wrap to the next line but goes beyond the screen.
Following is the code:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="4dip">
<LinearL...
android - How to display HTML in TextView?
I have simple HTML:
<h2>Title</h2><br>
<p>description here</p>
I want to display HTML styled text it in TextView. How to do this?
how to change text in Android TextView
I tried to do this
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
t=new TextView(this);
t=(TextView)findViewById(R.id.TextView01);
t.setText("Step One: blast egg");
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printSta...
android - Color of the text in TextView changes color
In android, when I press on a TextView, the text changes color (from white to grey).
Can you please tell me how can I disable that functionality?
Thank you.
How can you display upside down text with a textview in Android?
How can you display upside down text with a textview in Android?
In my case I have a 2 player game, where they play across from each other. I want to display test to the second player oriented to them.
This was the solution I implemented after AaronMs advice
The class that does the overriding, bab.foo.UpsideDownText
package bab.foo;
import android.content.Context;
import andr...
textview - How to know all id's that i have in the file main.xml in android?
i'm new at Android world, and i have a doubt, is there any method that give me the name of the id's i create in main.xml?
For example i have this:
main.xml
<TextView android:id="@+id/text1"
android:layout_width="70px"
android:layout_height="70px"
android:text="Google"
/>
<TextView android:id="@+id/text2"
android:layout_width="70px"
android:layout_h...
How do I add a newline to a TextView in Android?
When I define a TextView in xml, how do I add a new line to it? \n seems not to work.
<TextView
android:id="@+id/txtTitlevalue"
android:text="Line1 -\nLine2"
android:layout_width="54dip"
android:layout_height="fill_parent"
android:textSize="11px" />
Still can't find your answer? Check out these communities...
Android Google Support | Android Community | Android Community (Facebook) | Dev.io Android