Come aggiungere un elenco puntato all'applicazione Android?


89

Ho cercato su Google la mia domanda ma non è stata fornita una risposta funzionante. Come aggiungere un elenco puntato alla mia visualizzazione di testo.

Risposte:


185

Difficile da fare poiché ul / li / ol non sono supportati. Fortunatamente puoi usarlo come zucchero sintattico:

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

&#8226;è l'entità html per un elenco puntato più scelte sono qui http://www.elizabethcastro.com/html/extras/entities.html

ulteriori informazioni su quali tag sono supportati forniti da Mark Murphy (@CommonsWare) http://commonsware.com/blog/Android/2010/05/26/html-tags-supported-by-textview.html Caricalo con Html.fromHtml

((TextView)findViewById(R.id.my_text_view)).setText(Html.fromHtml(myHtmlString));

1
Grazie per il collegamento al sito commonsware, cercavo qualcosa del genere da tempo!
Norman H

4
Tieni presente che se stai ottenendo la stringa da values ​​/ strings.xml (utilizzando context.getString (R.string.yourstring);), dovrai racchiuderla in CDATA : <string name="string_name"><![CDATA[ &#8226; foo<br /> &#8226; bar... ]]></string>
Quentin S.

5
questo non funziona se è presente più di una riga nell'elemento elenco
puntato

sembra ul/ liè supportato ora stackoverflow.com/questions/9754076/...
hmac

55
  1. browep ha spiegato bene il modo in cui l'HTML. La soluzione fornita con l'entità html può essere utile. Ma include solo il proiettile. Se il testo va a capo, il rientro non sarà corretto.

  2. Ho trovato altre soluzioni che incorporano una visualizzazione web. Forse è appropriato per alcuni, ma penso che sia un po 'eccessivo ... (lo stesso con l'utilizzo di una visualizzazione elenco).

  3. Mi piace l' approccio creativo di Nelson : D, ma non ti dà la possibilità di aggiungere un elenco non ordinato a una visualizzazione di testo.

  4. Il mio esempio di un elenco non ordinato con punti elenco utilizzando 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));

Positivo:

  • Punti elenco con rientro corretto dopo il ritorno a capo del testo.
  • Puoi combinare altro testo formattato o non formattato in un'istanza di TextView
  • È possibile definire nel costruttore BulletSpan quanto dovrebbe essere grande il rientro.

Negativo:

  • È necessario salvare ogni elemento dell'elenco in una risorsa stringa separata. Quindi non puoi definire la tua lista così comoda come potresti in HTML.

1
Questo approccio (imitato esattamente) non funziona su 2.2. Finisci con un solo proiettile.
Skone

Ciao Skone, funziona con l'emulatore 2.2 e le build Android originali. Ho visto una versione Android in cui lo spazio tra il proiettile e il testo è stato ignorato. Ma il proiettile è ancora apparso. Hai una nuova riga alla fine delle stringhe dei proiettili?
Diego Frehner

Questa soluzione non funziona quando si modifica l'interlinea nella visualizzazione testo
Marqs

Ottimo modo per farlo con BulletSpan, funziona perfettamente ed è molto facile!
Moonbloom

7
Il codice sopra funziona per me !!! Tutto quello che dovevo fare è aggiungere "\ n" alla fine di ogni stringa in xml ....
Arhat Baid

38

Ho trovato un'alternativa .. copia semplicemente questo punto elenco "•" (è un testo) e incollalo nel testo della visualizzazione del testo, puoi cambiare il colore del punto cambiando il colore del testo e anche tutti gli altri attributi come dimensione, altezza larghezza. .. :)

puoi utilizzare la scorciatoia per ottenere questo punto durante la digitazione

per windows

ALT + 7

per mac

ALT + 8


2
Alt + 7 non funziona per me (forse è solo una cosa per Mac o Linux) ma copiare e incollare il carattere Unicode • ha funzionato.
Jon

2
FYI: ALT + 7 funzionerà solo se la tastiera ha un tastierino numerico separato.
Aks4125

Se incolli il simbolo nel codice, cioè in una stringa, tieni presente i problemi con i caratteri non ASCII e la codifica dei file (prova a cambiare la codifica del file dall'angolo inferiore destro di IntelliJ). Sarebbe meglio usare la sequenza di escape corrispondente (ad esempio \ u1234).
Gil Vegliach

Ben fatto! Vita da delinquente!
goonerDroid

2
\ u2022 è la risposta
user2322082

21

Ispirato dalle varie risposte qui, ho creato una classe di utilità per renderlo facile . Questo creerà un elenco puntato con rientro per il testo avvolto. Ha metodi per combinare stringhe, risorse di stringhe e risorse di array di stringhe.

Creerà una CharSequence che puoi passare a TextView. Per esempio:

CharSequence bulletedList = BulletListUtil.makeBulletList("First line", "Second line", "Really long third line that will wrap and indent properly.");
textView.setText(bulletedList);

Spero sia utile. Godere.

Nota: in questo modo verrà utilizzato il punto elenco standard del sistema, un piccolo cerchio dello stesso colore del testo. Se vuoi un punto elenco personalizzato, considera la possibilità di creare una sottoclasse BulletSpan e sovrascriverlo drawLeadingMargin()per disegnare il punto elenco che desideri. Dai un'occhiata alla fonte BulletSpan per avere un'idea di come funziona.

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

}

Grazie caro signore! Ho usato la funzione makeBulletList e funziona a meraviglia: D
Aba

È meraviglioso! Grazie)
kulikovman

10

Questo è di gran lunga il più semplice ..

<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

Estensione Kotlin pronta per l'uso

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

Utilizzo:

val bulletedList = listOf("One", "Two", "Three").toBulletedList()
label.text = bulletedList

Colori e dimensioni:

Per cambiare il colore o la dimensione del punto elenco, usa CustomBulletSpan invece di 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)
        }
    }
}

Puoi cambiare la dimensione del proiettile in modo che corrisponda in qualche modo alla dimensione del testo?
nenur

@NoahTanenholtz puoi aumentare la dimensione del proiettile cambiando il valore dell'argomento BulletSpan ()
Mikhail Sharin

Oh, pensavo fosse la spaziatura
nenur

La spaziatura è aumentata invece della dimensione del proiettile):
Sumit Shukla

@SumitShukla grazie per il commento. Ho appena aggiunto BulletCustomSpan per la personalizzazione del colore e delle dimensioni
Mikhail Sharin

4

Un'opzione che ho usato era impostare il punto disegnabile usando uno stile.

<style name="Text.Bullet">
    <item name="android:background">@drawable/bullet</item>
    <item name="android:paddingLeft">10dp</item>
</style>

Utilizzo:

<TextView android:id="@+id/tx_hdr" 
android:text="Item 1" style="@style/Text.Bullet" />

Ho appena preso una piccola immagine del proiettile dal web per il disegnabile. Il layout grafico in Eclipse mostra la grafica allungata sotto il testo ... piuttosto lontano da quello che volevo.
JohnK

1
Penso che intendesseandroid:drawableLeft=
Blundell

4

usa TextView semplice con un drawable composto. Per esempio

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

3

Ecco un'altra soluzione, non aggiungere esattamente un elenco a una visualizzazione di testo, ma immagino che l'obiettivo sia lo stesso. Sta usando TableLayout, che richiede solo XML ed è davvero semplice per piccoli elenchi ordinati o non ordinati. Di seguito, il codice di esempio che ho usato per questo, non una riga di codice in Java.

Positivo:

  • puoi mettere quello che vuoi nelle righe della tabella, non deve essere una visualizzazione di testo
  • puoi usarlo per creare elenchi puntati e numerati o qualsiasi altra cosa
  • puoi definire il rientro usando padding o layout_weight

Negativo:

  • noioso per elenchi molto lunghi (a meno che tu non usi un editor di testo furbo con regex)
  • ogni elemento dell'elenco viene archiviato come risorsa stringa separata

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

e lo stile:

<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

Di seguito è riportato un elenco puntato con un'intestazione e una scheda davanti a ciascun elemento.

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

È andato completamente eccessivo e ha creato una visualizzazione del testo personalizzata.

Usalo in questo modo:

<com.blundell.BulletTextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="--bullet 1 --bullet two --bullet three --bullet four" />

e il codice:

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

}

Come possiamo aumentare le dimensioni e la spaziatura dei proiettili?
Sumit Shukla

In questo esempio &#8226;dovresti scegliere un altro simbolo fsymbols.com/signs/bullet-point
Blundell

1

Trovo che questo sia il modo più semplice, lascia il textView così com'è nel file xml e usa il seguente codice java. ha funzionato perfettamente bene per me.

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

L'elenco puntato può essere creato semplicemente utilizzando <ul>e<li> tag nella risorsa stringa.

NON USARE setText (Html.fromHtml (string)) per impostare la stringa nel codice! Basta impostare la stringa normalmente in xml o utilizzando setText ( string ).

Per esempio:

file strings.xml

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


file layout.xml

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


Produrrà il seguente risultato:

  • primo elemento
  • elemento 2


I seguenti tag sono supportati in questo modo (direttamente incorporati nella risorsa stringa):

  • <a> (supporta gli attributi "href")
  • <annotation>
  • <b>
  • <big>
  • <font> (supporta gli attributi "height", "size", "fgcolor" e "bicolor", come numeri interi)
  • <i>
  • <li>
  • <marquee>
  • <small>
  • <strike>
  • <sub>
  • <sup>
  • <tt>
  • <u>

non hai bisogno del<ul>
Blundell

5
Non funziona. I tag html supportati sono solo <b>, <i> e <u>. developer.android.com/guide/topics/resources/…
Wooff

Ha funzionato perfettamente per me! L'unica cosa che dovevo fare per far funzionare tutto era mettere \ n all'inizio di ogni riga. cioè\n<ul><li>a</li> \n<li>b</li> \n<li>c</li></ul>
Jack T

1

Perché single line textpuoi semplicemente usare i 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>

È possibile modificare shape, size, colorbase alle proprie esigenze.


0

Le due opzioni che hai per fare un elenco puntato sono

  • creare l'elenco utilizzando html (ul, ol) e caricare l'html in una WebView
  • Carica i dati in un ListView e imposta il disegno a sinistra della tua visualizzazione di testo nel layout della voce di elenco, su un'immagine adatta per il punto elenco.

L'opzione 1 è la più semplice.



0

Se vuoi creare un elenco puntato con struttura editText.

Ho beneficiato di questi riferimenti

Puoi usare questi proiettili

           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());
                    }
                }
            }
        });
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.