Як додати маркований список до програми для Android?


91

Я погуглив своє запитання, але робоча відповідь не надана. Як додати маркований список до мого текстового перегляду.

Відповіді:


189

Це важко зробити, оскільки ul / li / ol не підтримуються. На щастя, ви можете використовувати це як синтаксичний цукор:

&#8226; foo<br/>
&#8226; bar<br/>
&#8226; baz<br/>

&#8226;є суттю html для маркера списку, інші варіанти тут http://www.elizabethcastro.com/html/extras/entities.html

докладніше про те, які теги підтримуються, надає Марк Мерфі (@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));

1
Дякуємо за посилання на спільний сайт, якийсь час шукав щось подібне!
Норман Н

4
Зверніть увагу, що якщо ви отримуєте рядок зі значень / strings.xml (використовуючи context.getString (R.string.yourstring);), вам доведеться обернути його в CDATA : <string name="string_name"><![CDATA[ &#8226; foo<br /> &#8226; bar... ]]></string>
Квентін С.

5
це не спрацьовує, якщо в елементі з
маркером

це виглядає як ul/ liпідтримується в даний час stackoverflow.com/questions/9754076 / ...
HMAC

55
  1. browep пояснив приємний шлях через HTML. Надане рішення із суттю html може бути корисним. Але вона включає лише кулю. Якщо текст загортається, відступ буде неправильним.

  2. Я знайшов інші рішення для вбудовування веб-перегляду. Це, можливо, підходить для деяких, але я думаю, що це надмірно ... (Те саме з використанням подання списку.)

  3. Мені подобається творчий підхід Nelson : D, але він не дає вам можливості додати невпорядкований список до подання тексту.

  4. Мій приклад невпорядкованого списку з маркерами за допомогою 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));
    

Позитивні:

  • Маркери з правильним відступом після обгортання тексту.
  • Ви можете поєднувати інший відформатований або неформатований текст в одному екземплярі TextView
  • Ви можете визначити в конструкторі BulletSpan, наскільки великим буде відступ.

Негативні:

  • Ви повинні зберегти кожен елемент списку в окремому рядковому ресурсі. Отже, ви не можете визначити свій список так зручно, як ви могли б у HTML.

1
Цей підхід (точно імітований) не працює на 2.2. У підсумку ви отримуєте лише одну кулю.
Сконе

Привіт Сконе, він працює в емуляторі 2.2 та оригінальних збірках для Android. Я побачив версію для android, де проміжок між маркером та текстом ігнорувався. Але куля все-таки з’явилася. Чи є у вас новий рядок у кінці рядків кулі?
Дієго Френер,

Це рішення не працює, коли ви змінюєте інтервал між рядками в текстовому режимі
Marqs

Чудовий спосіб зробити це за допомогою BulletSpan, працює ідеально і дуже просто!
Moonbloom

7
Наведений вище код працює для мене !!! Все, що мені потрібно було зробити, це додати "\ n" в кінці кожного рядка в xml ....
Архат Бейд

38

Я знайшов альтернативний варіант. Просто скопіюйте цей маркер "•" (це текст) і вставте в текст подання тексту, ви можете змінити колір маркера, змінивши кольори тексту, а також всі інші атрибути, такі як розмір, ширина висоти. .. :)

Ви можете використовувати ярлик, щоб отримати цю кулю під час набору тексту

для вікон

ALT + 7

для mac

ALT + 8


2
Alt + 7 у мене не працює (можливо, це лише Mac або Linux), але копіювання та вставлення символу • юнікоду спрацювало.
Джон

2
FYI: ALT + 7 працюватиме, лише якщо клавіатура має окрему цифрову клавіатуру.
Aks4125

Якщо ви вставляєте символ у код, тобто в рядок, майте на увазі проблеми із символами, не пов'язаними з ascii, та кодуванням файлів (спробуйте змінити кодування файлу з нижнього правого кута IntelliJ). Краще було б використовувати відповідну послідовність виходу (наприклад, \ u1234).
Gil Vegliach

Хороший шлях !! бандитське життя!
goonerDroid

2
\ u2022 - відповідь
user2322082

21

Натхненний різними відповідями тут, я створив клас Utility, щоб зробити цей простий лайнер . Це створить маркований список із відступами для загорнутого тексту. У ньому є методи поєднання рядків, рядкових ресурсів та ресурсів масиву рядків.

Він створить 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, щоб зрозуміти, як це працює.

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;
}

}

Дякую шановний пане! Я використовував функцію makeBulletList, і вона працює як шарм: D
Аба,

Це приголомшливо! Дякую)
kulikovman

10

Це на сьогоднішній день найпростіше ..

<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>

8

Готове до використання розширення 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)
        }
    }
}

Чи можете ви змінити розмір маркера, щоб якось відповідати розміру тексту?
nenur

@NoahTanenholtz, ти можеш збільшити розмір кулі, змінивши значення аргументу BulletSpan ()
Михайло

О, я думав, що це проміжок часу
nenur

Інтервал збільшено замість розміру кулі):
Суміт Шукла

@SumitShukla дякую за коментар. Я щойно додав BulletCustomSpan для налаштування кольору та розміру
Михайло Шарін

4

Варіантом, який я використовував, було встановити кулю, яку можна намалювати, використовуючи стиль.

<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" />

Я просто схопив маленький знімок кулі з Інтернету, щоб витягнути. Графічний макет в Eclipse показує графіку, розтягнуту під текстом ... досить далеко від того, що я хотів.
JohnK

1
Думаю, він мав на увазіandroid:drawableLeft=
Бланделл

4

використовуйте простий TextView із складеним малюнком. Наприклад

<TextView     
    android:text="Sample text"
    android:drawableLeft="@drawable/bulletimage" >
</TextView>

3

Ось ще одне рішення, не точно додавання списку до одного текстового перегляду, але, мабуть, мета однакова. Він використовує TableLayout, який потребує лише XML, і це дуже просто для невеликих впорядкованих або невпорядкованих списків. Нижче, зразок коду, який я використав для цього, а не рядок коду в Java.

Позитивні:

  • ви можете помістити все, що вам подобається, у рядки таблиці, не обов’язково для текстового перегляду
  • ви можете використовувати його для створення маркованого та нумерованого списку або чого завгодно
  • Ви можете визначити відступ за допомогою відступів або layout_weight

Негативні:

  • нудно для дуже довгих списків (якщо ви не використовуєте якийсь хитрий текстовий редактор із регулярним виразом)
  • кожен елемент списку зберігається як окремий рядовий ресурс

        <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>

2

Ось маркований список із заголовком та вкладкою перед кожним елементом.

public class BulletListBuilder {

    private static final String SPACE = " ";
    private static final String BULLET_SYMBOL = "&#8226";
    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();
    }

}

2

Повністю переборщив і зробив власний перегляд тексту.

Використовуйте його так:

<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 = "&#8226;";

    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
Blundell

1

Я вважаю, що це найпростіший спосіб, залиште textView таким, як він є у файлі xml, і використовуйте такий код Java. у мене це спрацювало чудово.

private static final String BULLET_SYMBOL = "&#8226";

@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"));
}

1

Маркірований список можна просто створити, використовуючи теги <ul>та <li>в рядковому ресурсі.

НЕ ВИКОРИСТОВУЙТЕ setText (Html.fromHtml (рядок)), щоб встановити рядок у коді! Просто встановіть рядок нормально в xml або за допомогою setText ( рядок ).

Наприклад:

файл strings.xml

<string name="str1">
    <ul>
        <li><i>first</i> item</li>
        <li>item 2</li>
    </ul>
</string>


файл layout.xml

<TextView
    android:text="@string/str1"
/>


Це дасть такий результат:

  • перший пункт
  • пункт 2


Підтримуються такі теги (безпосередньо вбудовані в рядок):

  • <a> (підтримує атрибути "href")
  • <анотація>
  • <b>
  • <велике>
  • <font> (підтримує атрибути "height", "size", "fgcolor" і "bicolor" як цілі числа)
  • <i>
  • <li>
  • <marquee>
  • <маленький>
  • <страйк>
  • <sub>
  • <sup>
  • <tt>
  • <u>

вам не потрібен<ul>
Blundell 02

5
Не працює. Підтримувані HTML-теги - це лише <b>, <i> та <u>. developer.android.com/guide/topics/resources/…
Wooff,

У мене чудово працювало! Єдине, що мені потрібно було зробити, щоб все запрацювало, було поставлено \ n на початку кожного рядка. тобто\n<ul><li>a</li> \n<li>b</li> \n<li>c</li></ul>
Джек Т

1

Для цього single line textви можете просто використовувати малюнки:

<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грунтуючись на вашому вимозі.


0

Два варіанти створення маркованого списку:

  • створити список за допомогою html (ul, ol) і завантажити html у WebView
  • Завантажте дані в ListView та встановіть лівий малюнок вашого текстового подання в макеті елемента списку на відповідне зображення для маркера.

Варіант 1 найпростіший.



0

Якщо ви хочете створити список маркерів зі структурою editText.

Я отримав користь від цих посилань

Ви можете використовувати ці кулі

           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());
                    }
                }
            }
        });
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.