Làm thế nào để thêm danh sách dấu đầu dòng vào ứng dụng Android?


89

Tôi đã tìm kiếm câu hỏi của mình nhưng không có câu trả lời phù hợp. Làm cách nào để thêm một danh sách có dấu đầu dòng vào chế độ xem văn bản của tôi.

Câu trả lời:


185

Khó thực hiện như ul / li / ol không được hỗ trợ. May mắn thay, bạn có thể sử dụng nó như cú pháp đường:

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

&#8226;là thực thể html cho một dấu đầu dòng danh sách, có nhiều lựa chọn hơn ở đây http://www.elizabethcastro.com/html/extras/entities.html

biết thêm về những thẻ nào được hỗ trợ bởi Mark Murphy (@CommonsWare) http://commonsware.com/blog/Android/2010/05/26/html-tags-supported-by-textview.html Tải lên bằng Html.fromHtml

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

1
Cảm ơn vì liên kết đến trang commonsware, tôi đã tìm kiếm thứ gì đó tương tự trong một thời gian!
Norman H

4
Hãy lưu ý rằng nếu bạn đang nhận được chuỗi từ các giá trị / strings.xml (sử dụng context.getString (R.string.yourstring);), bạn sẽ phải quấn nó trong CDATA : <string name="string_name"><![CDATA[ &#8226; foo<br /> &#8226; bar... ]]></string>
Quentin S.

5
điều này không hoạt động nếu có nhiều hơn một dòng trong mục
dấu đầu dòng

có vẻ như ul/ lihiện đã được hỗ trợ stackoverflow.com/questions/9754076/…
hmac,

55
  1. browep đã giải thích rất hay về cách sử dụng HTML. Giải pháp được cung cấp với thực thể html có thể hữu ích. Nhưng nó chỉ bao gồm gạch đầu dòng. Nếu văn bản của bạn kết thúc, thụt lề sẽ không chính xác.

  2. Tôi tìm thấy các giải pháp khác nhúng chế độ xem web. Điều đó có thể phù hợp với một số người, nhưng tôi nghĩ rằng nó quá mức cần thiết ... (Tương tự với việc sử dụng chế độ xem danh sách.)

  3. Tôi thích cách tiếp cận sáng tạo của Nelson : D, nhưng nó không cung cấp cho bạn khả năng thêm danh sách không có thứ tự vào chế độ xem văn bản.

  4. Ví dụ của tôi về danh sách không có thứ tự có dấu đầu dòng bằng 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));

Tích cực:

  • Dấu đầu dòng có thụt lề chính xác sau khi kết thúc văn bản.
  • Bạn có thể kết hợp văn bản được định dạng hoặc không được định dạng khác trong một phiên bản của TextView
  • Bạn có thể xác định trong hàm tạo BulletSpan mức độ lớn của thụt lề.

Tiêu cực:

  • Bạn phải lưu mọi mục của danh sách trong một tài nguyên chuỗi riêng biệt. Vì vậy, bạn không thể xác định danh sách của mình thoải mái như thế nào trong HTML.

1
Cách tiếp cận này (được mô phỏng chính xác) không hoạt động trên 2.2. Bạn chỉ kết thúc bằng một gạch đầu dòng.
Skone

Xin chào Skone, nó hoạt động trong trình giả lập 2.2 và các bản dựng Android gốc. Tôi đã thấy một phiên bản Android trong đó khoảng cách giữa dấu đầu dòng và văn bản bị bỏ qua. Nhưng viên đạn vẫn xuất hiện. Bạn có một dòng mới ở cuối chuỗi dấu đầu dòng của mình không?
Diego Frehner

Giải pháp này không hoạt động khi bạn thay đổi giãn cách dòng trong chế độ xem văn bản
Marqs

Cách thực hiện tuyệt vời với BulletSpan, hoạt động hoàn hảo và rất dễ dàng!
Moonbloom

7
Đoạn mã trên phù hợp với tôi !!! Tất cả tôi phải làm là add "\ n" ở cuối mỗi chuỗi trong xml ....
A La Hán Baid

38

Tôi đã tìm thấy một thay thế .. chỉ cần sao chép dấu đầu dòng này "•" (nó là một văn bản) và dán vào văn bản của chế độ xem văn bản của bạn, bạn có thể thay đổi màu dấu đầu dòng bằng cách thay đổi màu văn bản và tất cả các thuộc tính khác như kích thước, chiều rộng chiều cao. .. :)

bạn có thể sử dụng phím tắt để lấy dấu đầu dòng này trong khi nhập

cho cửa sổ

ALT + 7

cho mac

ALT + 8


2
Alt + 7 không hoạt động đối với tôi (có lẽ nó chỉ dành cho mac hoặc linux) nhưng việc sao chép và dán ký tự unicode • hoạt động.
Jon

2
FYI: ALT + 7 sẽ chỉ hoạt động nếu bàn phím có bộ gõ riêng.
Aks4125,

Nếu bạn dán biểu tượng trong mã, tức là trong một chuỗi, hãy lưu ý các vấn đề với các ký tự không phải ascii và mã hóa tệp (thử thay đổi mã hóa của tệp từ góc dưới bên phải của IntelliJ). Tốt hơn là sử dụng trình tự thoát tương ứng (ví dụ: \ u1234).
Gil Vegliach

Tốt lắm !! Cuộc sống côn đồ!
goonerDroid

2
\ u2022 là câu trả lời
user2322082

21

Lấy cảm hứng từ các câu trả lời khác nhau ở đây, tôi đã tạo một lớp Tiện ích để biến nó thành một lớp lót dễ dàng . Điều này sẽ tạo ra một danh sách có dấu đầu dòng với thụt lề cho văn bản được bao bọc. Nó có các phương thức để kết hợp chuỗi, tài nguyên chuỗi và tài nguyên mảng chuỗi.

Nó sẽ tạo một CharSequence mà bạn có thể chuyển tới TextView. Ví dụ:

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

Hy vọng nó hữu ích. Thưởng thức.

Lưu ý: Điều này sẽ sử dụng dấu đầu dòng tiêu chuẩn của hệ thống, một vòng tròn nhỏ cùng màu với văn bản. Nếu bạn muốn một dấu đầu dòng tùy chỉnh, hãy xem xét phân lớp BulletSpan và ghi đè nó drawLeadingMargin()để vẽ dấu đầu dòng bạn muốn. Hãy xem nguồn BulletSpan để biết cách hoạt động của nó.

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

}

Cảm ơn bạn thân mến! Tôi đã sử dụng chức năng makeBulletList và nó hoạt động như một sự quyến rũ: D
Aba

Thật tuyệt vời! Cảm ơn bạn)
kulikovman

10

Đây là cách dễ nhất ..

<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

Tiện ích mở rộng Kotlin sẵn sàng sử dụng

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

Sử dụng:

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

Màu sắc và kích thước:

Để thay đổi màu hoặc kích thước dấu đầu dòng, hãy sử dụng CustomBulletSpan thay vì 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)
        }
    }
}

Bạn có thể thay đổi kích thước của dấu đầu dòng để phù hợp với kích thước văn bản bằng cách nào đó không?
nenur

@NoahTanenholtz bạn có thể tăng kích thước đạn bằng cách thay đổi BulletSpan trị đối số ()
Mikhail Sharin

Ồ, tôi nghĩ đó là khoảng cách
nenur

Khoảng cách được tăng lên thay vì kích thước đạn):
Sumit Shukla

@SumitShukla cảm ơn bạn đã nhận xét. Tôi vừa thêm BulletCustomSpan để tùy chỉnh màu sắc và kích thước
Mikhail Sharin

4

Một tùy chọn tôi đã sử dụng là đặt dấu đầu dòng có thể vẽ bằng một kiểu.

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

Sử dụng:

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

Tôi vừa lấy một bức ảnh gạch đầu dòng nhỏ trên web để có thể vẽ được. Bố cục đồ họa trong Eclipse cho thấy đồ họa được kéo dài ra dưới văn bản ... khá xa so với những gì tôi muốn.
JohnK

1
Tôi nghĩ anh ấy có nghĩa làandroid:drawableLeft=
Blundell

4

sử dụng TextView đơn giản với một phức hợp có thể vẽ được. Ví dụ

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

3

Đây là một giải pháp khác, không chính xác là thêm danh sách vào một chế độ xem văn bản, nhưng tôi đoán mục tiêu là như nhau. Nó sử dụng TableLayout, chỉ cần XML và nó thực sự đơn giản cho các danh sách nhỏ có thứ tự hoặc không có thứ tự. Dưới đây, mã mẫu tôi đã sử dụng cho việc này, không phải một dòng mã trong Java.

Tích cực:

  • bạn có thể đặt bất cứ thứ gì bạn thích vào các hàng của bảng, không cần phải là một chế độ xem văn bản
  • bạn có thể sử dụng nó để tạo danh sách có dấu đầu dòng và đánh số hoặc bất cứ thứ gì
  • bạn có thể xác định thụt lề bằng cách sử dụng padding hoặc layout_weight

Tiêu cực:

  • tẻ nhạt cho những danh sách rất dài (trừ khi bạn sử dụng một số trình soạn thảo văn bản xảo quyệt với regex)
  • mọi mục danh sách được lưu trữ dưới dạng tài nguyên chuỗi riêng biệt

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

và phong cách:

<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

Đây là danh sách có dấu đầu dòng với tiêu đề và tab ở phía trước mỗi mục.

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

Đã đi hoàn toàn quá mức cần thiết và thực hiện chế độ xem văn bản tùy chỉnh.

Sử dụng nó như thế này:

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

và mã:

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

}

Làm thế nào chúng ta có thể tăng kích thước và khoảng cách dấu đầu dòng?
Sumit Shukla

Ví dụ này sử dụng, &#8226;bạn sẽ phải chọn một biểu tượng khác fsymbols.com/signs/bullet-point
Blundell

1

Tôi thấy đây là cách dễ nhất, để nguyên textView trong tệp xml và sử dụng mã java sau. nó hoạt động hoàn toàn tốt cho tôi.

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

Danh sách có dấu đầu dòng có thể được tạo đơn giản bằng cách sử dụng <ul><li> thẻ trong tài nguyên chuỗi.

KHÔNG SỬ DỤNG setText (Html.fromHtml (string)) để đặt chuỗi trong mã! Chỉ cần đặt chuỗi thông thường trong xml hoặc bằng cách sử dụng setText ( chuỗi ).

Ví dụ:

tệp string.xml

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


tệp layout.xml

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


Nó sẽ tạo ra kết quả sau:

  • mục đầu tiên
  • mục 2


Các thẻ sau được hỗ trợ như thế này (được nhúng trực tiếp vào tài nguyên chuỗi):

  • <a> (hỗ trợ thuộc tính "href")
  • <annotation>
  • <b>
  • <big>
  • <font> (hỗ trợ các thuộc tính "height", "size", "fgcolor" và "bicolor", dưới dạng số nguyên)
  • <i>
  • <li>
  • <dấu ấn>
  • <small>
  • <strike>
  • <sub>
  • <sup>
  • <tt>
  • <u>

bạn không cần<ul>
Blundell

5
Không hoạt động. Các thẻ html được hỗ trợ chỉ là <b>, <i> và <u>. developer.android.com/guide/topics/resources/…
Wooff

Làm việc hoàn hảo cho tôi! Điều duy nhất tôi phải làm để mọi thứ hoạt động là đặt \ n ở đầu mỗi dòng. tức là\n<ul><li>a</li> \n<li>b</li> \n<li>c</li></ul>
Jack T

1

Đối với single line textbạn, bạn có thể chỉ cần sử dụng có thể kéo được:

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

Bạn có thể thay đổi shape, size, colordựa trên yêu cầu của bạn.


0

Hai tùy chọn bạn có để thực hiện một danh sách có dấu đầu dòng là

  • tạo danh sách bằng html (ul, ol) và tải html vào WebView
  • Tải dữ liệu vào ListView và đặt phần có thể vẽ bên trái của chế độ xem văn bản của bạn trong bố cục mục danh sách, thành hình ảnh phù hợp cho dấu đầu dòng.

Lựa chọn 1 là dễ nhất.



0

Nếu bạn muốn tạo danh sách dấu đầu dòng với cấu trúc editText.

Tôi được hưởng lợi từ tài liệu tham khảo này

Bạn có thể sử dụng đạn

           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());
                    }
                }
            }
        });
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.