【发布时间】:2011-02-14 13:38:23
【问题描述】:
如何在我的文本视图中添加项目符号列表?
【问题讨论】:
-
stackoverflow.com/a/40991388/9061224,看看这是否有帮助
如何在我的文本视图中添加项目符号列表?
【问题讨论】:
不支持 ul/li/ol 的难做。幸运的是,您可以将其用作语法糖:
• foo<br/>
• bar<br/>
• baz<br/>
&#8226; 是列表项目符号的 html 实体
更多选择在这里http://www.elizabethcastro.com/html/extras/entities.html
Mark Murphy (@CommonsWare) 提供了有关支持哪些标签的更多信息 http://commonsware.com/blog/Android/2010/05/26/html-tags-supported-by-textview.html 用 Html.fromHtml 加载它
((TextView)findViewById(R.id.my_text_view)).setText(Html.fromHtml(myHtmlString));
【讨论】:
<string name="string_name"><![CDATA[ &#8226; foo<br /> &#8226; bar... ]]></string>
ul/li stackoverflow.com/questions/9754076/…
browep explained nice the way over HTML. 提供的带有 html 实体的解决方案可能很有用。但它只包括子弹。如果您的文本换行,缩进将不正确。
我找到了嵌入 Web 视图的其他解决方案。这可能对某些人来说是合适的,但我认为它有点矫枉过正......(使用列表视图也是如此。)
我喜欢creative approach of Nelson :D,但它不能让您向文本视图添加无序列表。
我的带项目符号的无序列表示例使用BulletSpan
CharSequence t1 = getText(R.string.xxx1);
SpannableString s1 = new SpannableString(t1);
s1.setSpan(new BulletSpan(15), 0, t1.length(), 0);
CharSequence t2 = getText(R.string.xxx2);
SpannableString s2 = new SpannableString(t2);
s2.setSpan(new BulletSpan(15), 0, t2.length(), 0);
textView.setText(TextUtils.concat(s1, s2));
正面:
否定:
【讨论】:
我找到了一个替代品.. 只需复制此项目符号“ •”(它是一个文本)并粘贴到您的文本视图的文本中,您可以通过更改 textcolor 以及所有其他属性(如大小)来更改项目符号颜色,高宽... :)
您可以在打字时使用快捷方式来获取此项目符号
对于窗户
ALT + 7
Mac 版
ALT + 8
【讨论】:
受到此处各种答案的启发,我创建了一个实用程序类,以使其成为一个简单的单行器。这将为包装文本创建一个带有缩进的项目符号列表。 它具有组合字符串、字符串资源和字符串数组资源的方法。
它将创建一个 CharSequence,您可以将其传递给 TextView。例如:
CharSequence bulletedList = BulletListUtil.makeBulletList("First line", "Second line", "Really long third line that will wrap and indent properly.");
textView.setText(bulletedList);
希望对您有所帮助。享受吧。
注意:这将使用系统标准的项目符号,与文本颜色相同的小圆圈。如果您想要自定义项目符号,请考虑将BulletSpan 子类化并覆盖其drawLeadingMargin() 以绘制您想要的项目符号。查看BulletSpan source 了解其工作原理。
public class BulletTextUtil {
/**
* Returns a CharSequence containing a bulleted and properly indented list.
*
* @param leadingMargin In pixels, the space between the left edge of the bullet and the left edge of the text.
* @param context
* @param stringArrayResId A resource id pointing to a string array. Each string will be a separate line/bullet-point.
* @return
*/
public static CharSequence makeBulletListFromStringArrayResource(int leadingMargin, Context context, int stringArrayResId) {
return makeBulletList(leadingMargin, context.getResources().getStringArray(stringArrayResId));
}
/**
* Returns a CharSequence containing a bulleted and properly indented list.
*
* @param leadingMargin In pixels, the space between the left edge of the bullet and the left edge of the text.
* @param context
* @param linesResIds An array of string resource ids. Each string will be a separate line/bullet-point.
* @return
*/
public static CharSequence makeBulletListFromStringResources(int leadingMargin, Context context, int... linesResIds) {
int len = linesResIds.length;
CharSequence[] cslines = new CharSequence[len];
for (int i = 0; i < len; i++) {
cslines[i] = context.getString(linesResIds[i]);
}
return makeBulletList(leadingMargin, cslines);
}
/**
* Returns a CharSequence containing a bulleted and properly indented list.
*
* @param leadingMargin In pixels, the space between the left edge of the bullet and the left edge of the text.
* @param lines An array of CharSequences. Each CharSequences will be a separate line/bullet-point.
* @return
*/
public static CharSequence makeBulletList(int leadingMargin, CharSequence... lines) {
SpannableStringBuilder sb = new SpannableStringBuilder();
for (int i = 0; i < lines.length; i++) {
CharSequence line = lines[i] + (i < lines.length-1 ? "\n" : "");
Spannable spannable = new SpannableString(line);
spannable.setSpan(new BulletSpan(leadingMargin), 0, spannable.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
sb.append(spannable);
}
return sb;
}
}
【讨论】:
即用型 Kotlin 扩展程序
fun List<String>.toBulletedList(): CharSequence {
return SpannableString(this.joinToString("\n")).apply {
this@toBulletedList.foldIndexed(0) { index, acc, span ->
val end = acc + span.length + if (index != this@toBulletedList.size - 1) 1 else 0
this.setSpan(BulletSpan(16), acc, end, 0)
end
}
}
}
用法:
val bulletedList = listOf("One", "Two", "Three").toBulletedList()
label.text = bulletedList
颜色和尺寸:
要更改项目符号颜色或大小,请使用 CustomBulletSpan 而不是 BulletSpan
package com.fbs.archBase.ui.spans
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.text.Layout
import android.text.Spanned
import android.text.style.LeadingMarginSpan
import androidx.annotation.ColorInt
class CustomBulletSpan(
private val bulletRadius: Int = STANDARD_BULLET_RADIUS,
private val gapWidth: Int = STANDARD_GAP_WIDTH,
@ColorInt private val circleColor: Int = STANDARD_COLOR
) : LeadingMarginSpan {
private companion object {
val STANDARD_BULLET_RADIUS = Screen.dp(2)
val STANDARD_GAP_WIDTH = Screen.dp(8)
const val STANDARD_COLOR = Color.BLACK
}
private val circlePaint = Paint().apply {
color = circleColor
style = Paint.Style.FILL
isAntiAlias = true
}
override fun getLeadingMargin(first: Boolean): Int {
return 2 * bulletRadius + gapWidth
}
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?
) {
if ((text as Spanned).getSpanStart(this) == start) {
val yPosition = (top + bottom) / 2f
val xPosition = (x + dir * bulletRadius).toFloat()
canvas.drawCircle(xPosition, yPosition, bulletRadius.toFloat(), circlePaint)
}
}
}
【讨论】:
这是迄今为止最简单的..
<string name="bullet_ed_list">\n\u2022 He has been Chairman of CFL Manufacturers Committee of ELCOMA, the All India Association of Lighting Equipment Manufacturers.
\n\u2022 He has been the President of Federation of Industries of India (FII).</string>
【讨论】:
我使用的一个选项是使用样式设置可绘制项目符号。
<style name="Text.Bullet">
<item name="android:background">@drawable/bullet</item>
<item name="android:paddingLeft">10dp</item>
</style>
用法:
<TextView android:id="@+id/tx_hdr"
android:text="Item 1" style="@style/Text.Bullet" />
【讨论】:
android:drawableLeft=
将简单的 TextView 与复合可绘制对象一起使用。例如
<TextView
android:text="Sample text"
android:drawableLeft="@drawable/bulletimage" >
</TextView>
【讨论】:
刚刚注意到我 8 年前的答案,并决定根据 the latest Android documentation for styling text with HTML markup 更新它:
<ul> 和<li> 等HTML 标签。支持这些标签和许多其他标签!setText()设置TextView文本
• 字符或十六进制代码要好。可以使用字符串资源中的<ul> 和<li> 标签来创建项目符号列表。
请勿使用 setText(Html.fromHtml(string)) 在代码中设置字符串!只需在 xml 中或使用 setText(string) 正常设置字符串。
例如:
strings.xml 文件
<string name="str1">
<ul>
<li><i>first</i> item</li>
<li>item 2</li>
</ul>
</string>
【讨论】:
<ul>
\n<ul><li>a</li> \n<li>b</li> \n<li>c</li></ul>
这是一个项目符号列表,每个项目前面都有一个标题和一个选项卡。
public class BulletListBuilder {
private static final String SPACE = " ";
private static final String BULLET_SYMBOL = "•";
private static final String EOL = System.getProperty("line.separator");
private static final String TAB = "\t";
private BulletListBuilder() {
}
public static String getBulletList(String header, String []items) {
StringBuilder listBuilder = new StringBuilder();
if (header != null && !header.isEmpty()) {
listBuilder.append(header + EOL + EOL);
}
if (items != null && items.length != 0) {
for (String item : items) {
Spanned formattedItem = Html.fromHtml(BULLET_SYMBOL + SPACE + item);
listBuilder.append(TAB + formattedItem + EOL);
}
}
return listBuilder.toString();
}
}
【讨论】:
这是另一种解决方案,不完全将列表添加到一个文本视图,但我想目标是相同的。它使用 TableLayout,只需要 XML,对于小的有序或无序列表来说真的很简单。下面是我用于此的示例代码,而不是 Java 中的一行代码。
正面:
否定:
每个列表项都存储为单独的字符串资源
<TableRow
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
<TextView
style="@style/helpPagePointsStyle"
android:layout_weight="0.2"
android:text="1." />
<TextView
style="@style/helpPagePointsStyle"
android:layout_weight="3"
android:text="@string/help_points1" />
</TableRow>
<TableRow
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
<TextView
style="@style/helpPagePointsStyle"
android:layout_weight="0.2"
android:text="2." />
<TextView
style="@style/helpPagePointsStyle"
android:layout_weight="3"
android:text="@string/help_points2" />
</TableRow>
<TableRow
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
<TextView
style="@style/helpPagePointsStyle"
android:layout_weight="0.2"
android:text="3." />
<TextView
style="@style/helpPagePointsStyle"
android:layout_weight="3"
android:text="@string/help_points3" />
</TableRow>
</TableLayout>
风格:
<style name="helpPagePointsStyle">
<item name="android:layout_width">0dp</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:gravity">left</item>
</style>
【讨论】:
完全矫枉过正并制作了自定义文本视图。
像这样使用它:
<com.blundell.BulletTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="--bullet 1 --bullet two --bullet three --bullet four" />
和代码:
package com.blundell;
import android.content.Context;
import android.text.Html;
import android.util.AttributeSet;
import android.widget.TextView;
public class BulletTextView extends TextView {
private static final String SPLITTER_CHAR = "--";
private static final String NEWLINE_CHAR = "<br/>";
private static final String HTML_BULLETPOINT = "•";
public BulletTextView(Context context, AttributeSet attrs) {
this(context, attrs, android.R.attr.textViewStyle);
}
public BulletTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
checkForBulletPointSplitter();
}
private void checkForBulletPointSplitter() {
String text = (String) getText();
if (text.contains(SPLITTER_CHAR)) {
injectBulletPoints(text);
}
}
private void injectBulletPoints(String text) {
String newLinedText = addNewLinesBetweenBullets(text);
String htmlBulletText = addBulletPoints(newLinedText);
setText(Html.fromHtml(htmlBulletText));
}
private String addNewLinesBetweenBullets(String text) {
String newLinedText = text.replace(SPLITTER_CHAR, NEWLINE_CHAR + SPLITTER_CHAR);
newLinedText = newLinedText.replaceFirst(NEWLINE_CHAR, "");
return newLinedText;
}
private String addBulletPoints(String newLinedText) {
return newLinedText.replace(SPLITTER_CHAR, HTML_BULLETPOINT);
}
}
【讨论】:
&#8226;,您必须选择另一个符号fsymbols.com/signs/bullet-point
我发现这是最简单的方法,将 textView 保留在 xml 文件中并使用以下 java 代码。它对我来说非常好。
private static final String BULLET_SYMBOL = "•";
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tutorial);
TextView tv = (TextView) findViewById(R.id.yourTextView);
tv.setText("To perform this exercise you will need the following: "
+ System.getProperty("line.separator")//this takes you to the next Line
+ System.getProperty("line.separator")
+ Html.fromHtml(BULLET_SYMBOL + " Bed")
+ System.getProperty("line.separator")
+ Html.fromHtml(BULLET_SYMBOL + " Pillow"));
}
【讨论】:
对于single line text,您可以简单地使用drawables:
<TextView
android:id="@+id/txtData"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableStart="@drawable/draw_bullet_list"
android:drawablePadding="@dimen/padding_8dp"
android:text="Hello"
android:textColor="@color/colorBlack" />
draw_bullet_list.xml:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="@color/colorAccent" />
<size
android:width="12dp"
android:height="12dp" />
</shape>
您可以根据需要更改shape、size、color。
【讨论】:
制作项目符号列表的两个选项是
选项 1 是最简单的。
【讨论】:
另一种支持缺少的 HTML 标签的方法是很好地替换它们,如图here
【讨论】:
如果你想创建带有editText结构的项目符号列表。
我受益了references
你可以使用这个bullets
EditText edtNoteContent = findViewById(R.id.editText_description_note);
edtNoteContent.addTextChangedListener(new TextWatcher(){
@Override
public void afterTextChanged(Editable e) {
}
@Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
}
@Override
public void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter)
{
if (lengthAfter > lengthBefore) {
if (text.toString().length() == 1) {
text = "◎ " + text;
edtNoteContent.setText(text);
edtNoteContent.setSelection(edtNoteContent.getText().length());
}
if (text.toString().endsWith("\n")) {
text = text.toString().replace("\n", "\n◎ ");
text = text.toString().replace("◎ ◎", "◎");
edtNoteContent.setText(text);
edtNoteContent.setSelection(edtNoteContent.getText().length());
}
}
}
});
【讨论】: