แท็กรายการ Html ไม่ทำงานใน android textview ฉันจะทำอย่างไร


101

แท็กรายการ Html ไม่ทำงานใน Android TextView นี่คือเนื้อหาสตริงของฉัน:

String str="A dressy take on classic gingham in a soft, textured weave of stripes that resembles twill.  Take a closer look at this one.<ul><li>Trim, tailored fit for a bespoke feel</li><li>Medium spread collar, one-button mitered barrel cuffs</li><li>Applied placket with genuine mother-of-pearl buttons</li><li>;Split back yoke, rear side pleats</li><li>Made in the U.S.A. of 100% imported cotton.</li></ul>";

ฉันโหลดในมุมมองข้อความเช่นนี้:

textview.setText(Html.fromHtml(str));

ผลลัพธ์มีลักษณะเหมือนย่อหน้า ฉันจะทำอะไรได้บ้าง? มีวิธีแก้ไขหรือไม่?

แก้ไข:

webview.loadData(str,"text/html","utf-8");

1
ควรเป็น text / html ไม่ใช่ texl / html
Chloe

คำตอบ:


159

ที่คุณสามารถดูในHtmlรหัสที่มาชั้น , Html.fromHtml(String)ไม่สนับสนุนแท็กทั้งหมด ในกรณีนี้<ul>และ<li>ไม่ได้รับการสนับสนุน

จากซอร์สโค้ดฉันได้สร้างรายการแท็ก HTML ที่อนุญาต:

  • br
  • p
  • div
  • em
  • b
  • strong
  • cite
  • dfn
  • i
  • big
  • small
  • font
  • blockquote
  • tt
  • monospace
  • a
  • u
  • sup
  • sub

ดังนั้นคุณควรใช้WebViewและloadDataWithBaseURLวิธีการของมัน ลองทำสิ่งนี้:

String str="<html><body>A dressy take on classic gingham in a soft, textured weave of stripes that resembles twill.  Take a closer look at this one.<ul><li>Trim, tailored fit for a bespoke feel</li><li>Medium spread collar, one-button mitered barrel cuffs</li><li>Applied placket with genuine mother-of-pearl buttons</li><li>;Split back yoke, rear side pleats</li><li>Made in the U.S.A. of 100% imported cotton.</li></ul></body></html>";
webView.loadDataWithBaseURL(null, str, "text/html", "utf-8", null);

แล้วฉันจะแก้ไขมันได้อย่างไร?
ประวีณ

2
สิ่งสำคัญมากที่จะต้องทราบแอตทริบิวต์บางอย่างของแท็ก "อนุญาต" นี้ไม่ได้รับการสนับสนุนด้วย : = (
Jorgesys

2
ใจเย็น ๆ ... ฉันแก้ไขคำตอบแล้วโปรดแจ้งให้เราทราบว่าได้ผลหรือไม่
Cristian

6
คุณไม่สามารถใช้ WebView ในลักษณะเดียวกันได้ดังนั้นนี่จึงไม่ใช่วิธีแก้ปัญหาที่แท้จริง
Brill Pappin

11
วิธีแก้ปัญหานั้นเป็นอย่างไร? คุณไม่สามารถใช้ WebView ได้ แต่เป็นวิดเจ็ตที่มีราคาแพงมากเมื่อเทียบกับ TextView คุณไม่สามารถใช้ WebView สำหรับทุกข้อความที่จัดรูปแบบได้
SpaceMonkey

135

ฉันมีปัญหาเดียวกันสิ่งที่ผมจะเอาชนะเริ่มต้นTagHandler อันนี้ใช้ได้ผลสำหรับฉัน

public class MyTagHandler implements TagHandler {

    boolean first = true;
    String parent = null;
    int index = 1;
    @Override
    public void handleTag(boolean opening, String tag, Editable output, XMLReader xmlReader) {

        if (tag.equals("ul")) {
            parent = "ul";
        } else if (tag.equals("ol")) {
            parent = "ol";
        }

        if (tag.equals("li")) {
            if (parent.equals("ul")) {
                if (first) {
                    output.append("\n\t•");
                    first = false;
                } else {
                    first = true;
                }
            } else{
                if (first) {
                    output.append("\n\t"+index+". ");
                    first = false;
                    index++;
                } else {
                    first = true;
                }
            }   
        }
    }
}

และสำหรับแสดงข้อความ ...

myTextView.setText(Html.fromHtml("<ul><li>I am an Android developer</li><li>Another Item</li></ul>", null, new MyTagHandler()));

[แก้ไข]

Kuitsi ได้โพสต์ไลบรารีที่ดีจริงๆซึ่งทำแบบเดียวกันได้จากลิงค์ SOนี้


เราใช้แนวทางนี้ในที่สุด แท็ก HTML ที่ไม่รองรับใด ๆ เราเขียนโค้ดเป็นข้อความเอง ตอนนี้มันเป็นแค่ ol และ ul แต่เราเพิ่มในสแต็คเพื่อจัดการการซ้อนรายการและจัดเก็บดัชนีเมื่อซ้อน ol นอกจากนี้คุณสามารถใช้พารามิเตอร์บูลีนเปิดเพื่อแทนที่ตัวแรกได้
JonWillis

6
@Aman Gautam ขอบคุณมากสำหรับสิ่งนี้! คุณมีความคิดที่จะแท็บข้อความเมื่อมีมากกว่า 1 บรรทัดหรือไม่? ด้วยรหัสนี้หลังบรรทัดที่ 2 ข้อความจะจัดชิดกับตัวเลขแทนที่จะเป็นแบบแท็บเพื่อแยกตัวเลขออกจากกัน ฉันพยายามทำบางอย่าง แต่คิดไม่ออก
RyanG

สิ่งเดียวกันที่นี่การแตกไลน์ในรายการทำให้เกิดการโจมตีด้วยวิธีนี้
Andreas Rudolph

แทนที่จะใช้อักขระสัญลักษณ์แสดงหัวข้อย่อยที่วางไว้อาจเป็นการดีกว่าที่จะใช้อักขระ Unicode: output.append ("\ n \ t \ u2022");
Matt McMinn

ขอบคุณสำหรับรหัสที่ดีนี้ แต่ฉันไม่สามารถใช้มันได้จนกว่าเราจะพบวิธีแก้ไขการเยื้องหลายบรรทัด
peter.bartos

68

โครงการตัวอย่างเต็มรูปแบบตั้งอยู่ที่https://bitbucket.org/Kuitsi/android-textview-html-list
ดูภาพตัวอย่างได้ที่https://kuitsi.bitbucket.io/stackoverflow3150400_screen.png

วิธีนี้ใกล้เคียงกับคำตอบของ mashaที่สุด โค้ดบางส่วนนำมาจากชั้นในandroid.text.Html.HtmlToSpannedConverterด้วย รองรับรายการที่เรียงลำดับและไม่เรียงลำดับ แต่ข้อความที่ยาวเกินไปในรายการที่เรียงลำดับยังคงสอดคล้องกับหมายเลขรายการแทนที่จะเป็นข้อความ รายการผสม (ol และ ul) ก็ต้องการงานเช่นกัน ตัวอย่างโครงการที่มีการดำเนินงานของHtml.TagHandlerซึ่งถูกส่งไปยังHtml.fromHtml (String, ImageGetter, TagHandler)

แก้ไข: สำหรับการรองรับแท็ก HTML ที่กว้างขึ้นhttps://github.com/NightWhistler/HtmlSpannerอาจคุ้มค่าที่จะลอง


จนถึงตอนนี้ทางออกที่ดีที่สุด ขอบคุณ
peter.bartos

ไม่มีการติดตามประเด็นปัญหาใน BitBucket repo ดังนั้นการโพสต์ที่นี่: คุณจำเป็นต้องเพิ่มการตรวจสอบที่นี่และที่นี่สำหรับoutput.length() > 0ในขณะที่if (output.length() > 0 && output.charAt(output.length() - 1) != '\n')
mindeh

2
เพื่อหลีกเลี่ยงไม่ให้คนอื่นเสียเวลา 2 ชั่วโมงกับเรื่องนี้ NightWhistler HtmlSpanner จะลบอักขระที่เน้นเสียงทั้งหมดไม่ว่าจะด้วยเหตุผลใดก็ตาม
EpicPandaForce

@Kuitsi ขอบคุณสำหรับการแก้ปัญหา มีปัญหาหนึ่งในกรณีนี้เมื่อข้อความ html คือ "<ul> <li> something </li> </ul>" ตัวอักษรสุดท้ายใน "something" จะไม่ปรากฏในรายการ
Sam Berg

นี่เป็นวิธีแก้ปัญหาที่ดีมาก แต่มีข้อเสียสองประการ: 1) ไม่รองรับ Android ≥ 7และ 2) ไม่ใส่การเยื้องเริ่มต้นสำหรับระดับแรกของรายการ
โซเชียล

24

การแก้ไขรหัส Aman Guatam เล็กน้อย ฟังก์ชันข้างต้นมีปัญหาในการแสดงอักขระขึ้นบรรทัดใหม่ ตัวอย่างเช่นหากก่อน<li>แท็กเป็น<p>แท็กระบบจะแสดงอักขระขึ้นบรรทัดใหม่ 2 ตัว นี่คือรหัสอัพเกรด:

import org.xml.sax.XMLReader;

import android.text.Editable;
import android.text.Html.TagHandler;

public class ListTagHandler implements TagHandler {
    boolean first = true;

    @Override
    public void handleTag(boolean opening, String tag, Editable output, XMLReader xmlReader) {

        // TODO Auto-generated method stub
        if (tag.equals("li")) {
            char lastChar = 0;
            if (output.length() > 0)
                lastChar = output.charAt(output.length() - 1);
            if (first) {
                if (lastChar == '\n')
                    output.append("\t•  ");
                else
                    output.append("\n\t•  ");
                first = false;
            } else {
                first = true;
            }
        }
    }
}

เรียบง่าย แต่มีประสิทธิภาพ
steven0529

แล้วรายการสั่งซื้อล่ะ?
นักพัฒนา Android

13

คำเตือน

ณ วันที่ 10 กุมภาพันธ์ 2016 android.text.Htmlรองรับliและulแท็กและใช้งานพื้นฐานnew BulletSpan()จริงซึ่งหมายความว่าใน Android เวอร์ชันล่าสุดHtml.TagHandlerโซลูชันที่โพสต์ที่นี่จะถูกละเว้น

ตรวจสอบให้แน่ใจว่ารหัสของคุณจัดการกับการเปลี่ยนแปลงนี้ในกรณีที่คุณคาดว่า BulletSpan จะมีช่องว่างที่ใหญ่กว่าค่าเริ่มต้นคุณจะต้องมีโซลูชันบางประเภทที่ค้นหา / แทนที่ช่วง


4
แต่คลาส Html ใหม่นั้นมีให้บริการเฉพาะใน Android Nขึ้นไป
Sakiboy

1
ใช่ - ดังนั้นคุณต้องคำนึงถึงข้อเท็จจริงที่ว่า OS เวอร์ชันต่างๆจะทำงานแตกต่างกัน ด้วยเหตุนี้ฉันจึงแนะนำโซลูชันที่ค้นหาและแทนที่ BulletSpan หลังจากที่ HTML ถูกแยกวิเคราะห์เป็นช่วงต่างๆ การใช้งานเริ่มต้นของเวอร์ชันหลังจาก N จะใช้ระยะขอบเริ่มต้นคุณสามารถค้นหาและแทนที่สิ่งเหล่านี้ด้วยระยะขอบที่คุณต้องการได้
kassim

อัปเดตอยู่เสมอ
Kai Wang

9

โซลูชันที่แตกต่างกันโดยใช้ LeadingMarginSpan จัดการรายการที่เรียงลำดับและไม่เรียงลำดับเช่นเดียวกับการซ้อน

public class ListTagHandler implements TagHandler
{
    private int                 m_index     = 0;
    private List< String >  m_parents   = new ArrayList< String >( );

    @Override
    public void handleTag( final boolean opening, final String tag, Editable output,    final XMLReader xmlReader )
    {
        if( tag.equals( "ul" ) || tag.equals( "ol" ) || tag.equals( "dd" ) )
        {
            if( opening )
            {
                m_parents.add( tag );
            }
            else m_parents.remove( tag );

            m_index = 0;
        }
        else if( tag.equals( "li" ) && !opening ) handleListTag( output );
    }

    private void handleListTag( Editable output )
    {
        if( m_parents.get(m_parents.size()-1 ).equals( "ul" ) )
        {
            output.append( "\n" );
            String[ ] split = output.toString( ).split( "\n" );

            int lastIndex = split.length - 1;
            int start = output.length( ) - split[ lastIndex ].length( ) - 1;
            output.setSpan( new BulletSpan( 15 * m_parents.size( ) ), start, output.length( ), 0 );
        }
        else if( m_parents.get(m_parents.size()-1).equals( "ol" ) )
        {
            m_index++ ;

            output.append( "\n" );
            String[ ] split = output.toString( ).split( "\n" );

            int lastIndex = split.length - 1;
            int start = output.length( ) - split[ lastIndex ].length( ) - 1;
            output.insert( start, m_index + ". " );
            output.setSpan( new LeadingMarginSpan.Standard( 15 * m_parents.size( ) ), start, output.length( ), 0 );
        }
    }
}

5
ฉันชอบแนวคิดในการใช้ Spans แต่ฉันไม่สามารถรับรายการซ้อนที่ทำงานกับรหัสนี้ได้ ทั้งสองสายoutput.setSpan(...)ขัดข้องด้วยjava.lang.RuntimeException: PARAGRAPH span must start at paragraph boundary
Kuitsi

ขอบคุณสำหรับทางออกที่ดี! นอกจากนี้ยังเยื้องข้อความหลายบรรทัด
peter.bartos

2
ทำไมคุณถึงใช้ Vector แทน ArrayList ธรรมดา ๆ Vector is for multi threads ...
android developer

@androiddeveloper โปรแกรมเมอร์ c ++ ที่ไม่ดีของฉันอย่าลังเลที่จะแก้ไขคำตอบ
masha

1
ฉันได้โพสต์เป็น Snippet androidsnippets.com/…
Pratik Butani

8

หากคุณต้องการจัดรูปแบบรายการให้เรียบง่ายและคัดลอก / วางอักขระ Unicode ใน TextView ของคุณเพื่อให้ได้ผลลัพธ์เช่นเดียวกัน

•อักขระ Unicode 'BULLET' (U + 2022)


6

ฉันมาที่นี่เพื่อค้นหาการใช้งาน TagHandler ทั้ง Truong Nguyen และ Aman Guatam คำตอบนั้นดีมาก แต่ฉันต้องการทั้งสองเวอร์ชันผสมกัน: ฉันต้องการวิธีแก้ปัญหาไม่ให้จัดรูปแบบมากเกินไปและเพื่อให้สามารถแก้ไข<ol>แท็กได้เนื่องจากฉันกำลังแยกวิเคราะห์บางอย่างเช่น<h3>title</h3><ol><li>item</li><li>item</li><li>item</li></ol>แท็กตั้งแต่ฉันแยกสิ่งที่ต้องการ

นี่คือทางออกของฉัน

import org.xml.sax.XMLReader;

import android.text.Editable;
import android.text.Html.TagHandler;

public class MyTagHandler implements TagHandler {
    boolean first = true;
    String parent = null;
    int index = 1;

    public void handleTag(final boolean opening, final String tag,
            final Editable output, final XMLReader xmlReader) {

        if (tag.equals("ul")) {
            parent = "ul";
                    index = 1;
        } else if (tag.equals("ol")) {
            parent = "ol";
                    index = 1;
        }
        if (tag.equals("li")) {
            char lastChar = 0;
            if (output.length() > 0) {
                lastChar = output.charAt(output.length() - 1);
            }
            if (parent.equals("ul")) {
                if (first) {
                    if (lastChar == '\n') {
                        output.append("\t•  ");
                    } else {
                        output.append("\n\t•  ");
                    }
                    first = false;
                } else {
                    first = true;
                }
            } else {
                if (first) {
                    if (lastChar == '\n') {
                        output.append("\t" + index + ". ");
                    } else {
                        output.append("\n\t" + index + ". ");
                    }
                    first = false;
                    index++;
                } else {
                    first = true;
                }
            }
        }
    }
}

โปรดทราบว่าเนื่องจากเรากำลังรีเซ็ตค่าดัชนีเมื่อใดก็ตามที่รายการใหม่เริ่มต้นขึ้นจะไม่ทำงานหากคุณซ้อนรายการเช่นใน <ol><li>1<ol><li>1.1</li><li>1.2</li></ol><li>2</li></ol>

  1. 1
    1. 1.1
    2. 1.2
  2. 2

ด้วยรหัสที่คุณจะได้รับแทน1, 1, 2, 31, 1, 2, 2


โค้ดนี้ใช้ได้จนถึงเวอร์ชัน 23 วิธีทำให้ใช้งานได้สำหรับ 24 ขึ้นไป
Abhinav Tyagi

3

แน่นอนว่ามีวิธีแสดงสัญลักษณ์แสดงหัวข้อย่อยใน Android TextView คุณสามารถแทนที่<li>แท็กด้วย&#149;(ซึ่งเป็นโค้ด HTML สำหรับสัญลักษณ์แสดงหัวข้อย่อย)

หากคุณต้องการลองใช้ไอคอนรายการอื่น ๆ ให้ใช้ไอคอนที่ต้องการจากตารางคือลิงค์นี้

http://www.ascii-code.com/


ไม่ได้ผลสำหรับฉัน ใน Android 7.1.1 และ 6.0.1 กล่องที่มีเครื่องหมาย x ทะลุจะปรากฏขึ้นแทนสัญลักษณ์แสดงหัวข้อย่อยใน TextView
user1652110

3

คุณสามารถแทนที่ "li" ด้วยยูนิโค้ดได้

    @Override
public void handleTag(boolean opening, String tag, Editable output, XMLReader xmlReader) {

    if (tag.equalsIgnoreCase("li")) {
        if (opening) {
            output.append("\u2022 ");
        } else {
            output.append("\n");
        }
    }
}

2

คำตอบของลอร์ดโวลเดอร์มอร์คือจุดเริ่มต้นที่ดี อย่างไรก็ตามฉันต้องการolแท็กเพื่อแสดงรายการสั่งซื้อ1. 2. 3. ....แทนสัญลักษณ์แสดงหัวข้อย่อย นอกจากนี้แท็กที่ซ้อนกันยังต้องการการจัดการพิเศษเพื่อให้ทำงานได้อย่างถูกต้อง

ในโค้ดของฉันฉันได้ดูแล stack (parentList) เพื่อติดตามการเปิดและปิดulและolแท็กและเพื่อให้ทราบแท็กที่เปิดอยู่ในปัจจุบัน นอกจากนี้ยังlevelWiseCounterใช้เพื่อรักษาการนับที่แตกต่างกันในกรณีของolแท็กที่ซ้อนกัน

myTextView.setText(Html.fromHtml("your string", null, new CustomTagHandler()));

. . .

private static class CustomTagHandler implements TagHandler
   {
      int level = 0;
      private LinkedList<Tag> parentList = new LinkedList<DetailFragment.CustomTagHandler.Tag>();
      private HashMap<Integer, Integer> levelWiseCounter = new HashMap<Integer, Integer>();

      @Override
      public void handleTag(boolean opening, String tag, Editable output, XMLReader xmlReader)
      {
         if (tag.equalsIgnoreCase("ul") || tag.equalsIgnoreCase("ol"))
         {
            if (opening)
            {
               if (tag.equalsIgnoreCase("ul"))
               {
                  parentList.push(Tag.UL);
               }
               else
               {
                  parentList.push(Tag.OL);
               }
               level++;
            }
            else
            {
               if (!parentList.isEmpty())
               {
                  parentList.pop();

                  //remove counter at that level, in any present.
                  levelWiseCounter.remove(level);
               }
               level--;
               if (level < 0)
               {
                  level = 0;
               }
            }
         }
         else if (tag.equalsIgnoreCase("li"))
         {
            if (opening && level > 0)
            {
               //new line check
               int length = output.toString().length();
               if (length > 0 && (output.toString().charAt(length - 1) == '\n'))
               {
               }
               else
               {
                  output.append("\n");
               }

               //add tabs as per current level of li
               for (int i = 0; i < level; i++)
               {
                  output.append("\t");
               }

               // append dot or numbers based on parent tag
               if (Tag.UL == parentList.peek())
               {
                  output.append("•");
               }
               else
               {
                  //parent is OL. Check current level and retreive counter from levelWiseCounter
                  int counter = 1;
                  if (levelWiseCounter.get(level) == null)
                  {
                     levelWiseCounter.put(level, 1);
                  }
                  else
                  {
                     counter = levelWiseCounter.get(level) + 1;
                     levelWiseCounter.put(level, counter);
                  }
                  output.append(padInt(counter) + ".");
               }

               //trailing tab
               output.append("\t");

            }
         }
      }

      /**
       * Add padding so that all numbers are aligned properly. Currently supports padding from 1-99.
       * 
       * @param num
       * @return
       */
      private static String padInt(int num)
      {
         if (num < 10)
         {
            return " " + num;
         }
         return "" + num;
      }

      private enum Tag
      {
         UL, OL
      }
   }

2

รหัสถัดไป (ตามลิงค์นี้ ):

public class TextViewHtmlTagHandler implements TagHandler
  {
  /**
   * Keeps track of lists (ol, ul). On bottom of Stack is the outermost list
   * and on top of Stack is the most nested list
   */
  Stack<String>                   lists          =new Stack<String>();
  /**
   * Tracks indexes of ordered lists so that after a nested list ends
   * we can continue with correct index of outer list
   */
  Stack<Integer>                  olNextIndex    =new Stack<Integer>();
  /**
   * List indentation in pixels. Nested lists use multiple of this.
   */
  private static final int        indent         =10;
  private static final int        listItemIndent =indent*2;
  private static final BulletSpan bullet         =new BulletSpan(indent);

  @Override
  public void handleTag(final boolean opening,final String tag,final Editable output,final XMLReader xmlReader)
    {
    if(tag.equalsIgnoreCase("ul"))
      {
      if(opening)
        lists.push(tag);
      else lists.pop();
      }
    else if(tag.equalsIgnoreCase("ol"))
      {
      if(opening)
        {
        lists.push(tag);
        olNextIndex.push(Integer.valueOf(1)).toString();// TODO: add support for lists starting other index than 1
        }
      else
        {
        lists.pop();
        olNextIndex.pop().toString();
        }
      }
    else if(tag.equalsIgnoreCase("li"))
      {
      if(opening)
        {
        if(output.length()>0&&output.charAt(output.length()-1)!='\n')
          output.append("\n");
        final String parentList=lists.peek();
        if(parentList.equalsIgnoreCase("ol"))
          {
          start(output,new Ol());
          output.append(olNextIndex.peek().toString()+". ");
          olNextIndex.push(Integer.valueOf(olNextIndex.pop().intValue()+1));
          }
        else if(parentList.equalsIgnoreCase("ul"))
          start(output,new Ul());
        }
      else if(lists.peek().equalsIgnoreCase("ul"))
        {
        if(output.charAt(output.length()-1)!='\n')
          output.append("\n");
        // Nested BulletSpans increases distance between bullet and text, so we must prevent it.
        int bulletMargin=indent;
        if(lists.size()>1)
          {
          bulletMargin=indent-bullet.getLeadingMargin(true);
          if(lists.size()>2)
            // This get's more complicated when we add a LeadingMarginSpan into the same line:
            // we have also counter it's effect to BulletSpan
            bulletMargin-=(lists.size()-2)*listItemIndent;
          }
        final BulletSpan newBullet=new BulletSpan(bulletMargin);
        end(output,Ul.class,new LeadingMarginSpan.Standard(listItemIndent*(lists.size()-1)),newBullet);
        }
      else if(lists.peek().equalsIgnoreCase("ol"))
        {
        if(output.charAt(output.length()-1)!='\n')
          output.append("\n");
        int numberMargin=listItemIndent*(lists.size()-1);
        if(lists.size()>2)
          // Same as in ordered lists: counter the effect of nested Spans
          numberMargin-=(lists.size()-2)*listItemIndent;
        end(output,Ol.class,new LeadingMarginSpan.Standard(numberMargin));
        }
      }
    else if(opening)
      Log.d("TagHandler","Found an unsupported tag "+tag);
    }

  private static void start(final Editable text,final Object mark)
    {
    final int len=text.length();
    text.setSpan(mark,len,len,Spanned.SPAN_MARK_MARK);
    }

  private static void end(final Editable text,final Class<?> kind,final Object... replaces)
    {
    final int len=text.length();
    final Object obj=getLast(text,kind);
    final int where=text.getSpanStart(obj);
    text.removeSpan(obj);
    if(where!=len)
      for(final Object replace : replaces)
        text.setSpan(replace,where,len,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    return;
    }

  private static Object getLast(final Spanned text,final Class<?> kind)
    {
    /*
     * This knows that the last returned object from getSpans()
     * will be the most recently added.
     */
    final Object[] objs=text.getSpans(0,text.length(),kind);
    if(objs.length==0)
      return null;
    return objs[objs.length-1];
    }

  private static class Ul
    {
    }

  private static class Ol
    {
    }
  }

1
คำตอบนี้มีการจัดรูปแบบที่แตกต่างกันเล็กน้อยเมื่อเทียบกับแหล่งที่มาดั้งเดิมซึ่งสร้างขึ้นเพื่อรองรับคำตอบอื่นสำหรับคำถามเดียวกันนี้: stackoverflow.com/a/17365740/262462 :)
Kuitsi

จริง. ไม่ได้สังเกตว่า
นักพัฒนา Android

2

ฉันมีปัญหาฉันมักจะมีบรรทัดว่างหลังจากรายการด้วยโซลูชัน @Kuitsis ฉันเพิ่มสองสามบรรทัดใน handleTag () และตอนนี้บรรทัดว่างก็หายไป:

@Override
public void handleTag(final boolean opening, final String tag, final Editable output, final XMLReader xmlReader) {
    if (UL_TAG.equalsIgnoreCase(tag)) {
        if (opening) {   // handle <ul>
            lists.push(new Ul());
        } else {   // handle </ul>
            lists.pop();
            if (output.length() > 0 && output.charAt(output.length() - 1) == '\n') {
                output.delete(output.length() - 1, output.length());
            }
        }
    } else if (OL_TAG.equalsIgnoreCase(tag)) {
        if (opening) {   // handle <ol>
            lists.push(new Ol()); // use default start index of 1
        } else {   // handle </ol>
            lists.pop();
            if (output.length() > 0 && output.charAt(output.length() - 1) == '\n') {
                output.delete(output.length() - 1, output.length());
            }
        }
    } else if (LI_TAG.equalsIgnoreCase(tag)) {
        if (opening) {   // handle <li>
            lists.peek().openItem(output);
        } else {   // handle </li>
            lists.peek().closeItem(output, lists.size());
        }
    } else {
        Log.d("TagHandler", "Found an unsupported tag " + tag);
    }
}

2

คุณสามารถใช้Html.TagHandler. ด้านล่างสามารถใช้สำหรับ kotlin

    class UlTagHandler : Html.TagHandler {
    override fun handleTag(
        opening: Boolean, tag: String, output: Editable,
        xmlReader: XMLReader
    ) {
        if (tag == "ul" && !opening) output.append("\n")
        if (tag == "li" && opening) output.append("\n\t•")
    }
}

และ

textView.setText(Html.fromHtml(myHtmlText, null, UlTagHandler()));

0

นี่คือการยืนยันสิ่งที่ kassim ระบุไว้ มีการกระจายตัว ฉันพบวิธีแก้ปัญหานี้ ฉันต้องเปลี่ยนชื่อ<li>และ ul เป็นแท็กที่กำหนดเอง ดังนั้น:

myHTML.replaceAll("</ul>","</customTag>").replaceAll("<ul>","<customTag>");
//likewise for li

จากนั้นในตัวจัดการของฉันฉันสามารถมองหา customTag นั้น (ซึ่งไม่ทำอะไรเลย) และทำให้มันทำอะไรบางอย่าง

//now my handler can handle the customtags. it was ignoring them after nougat. 
 public class UlTagHandler implements Html.TagHandler {
        //for ul in nougat and up this tagHandler is completely ignored
        @Override
        public void handleTag(boolean opening, String tag, Editable output,
                              XMLReader xmlReader) {

            if (tag.equals("customtag2") && opening)
            output.append("\n\t\u25CF\t");
        if (tag.equals("customtag2") && !opening)
            output.append("\n");
        }
    }

สิ่งนี้ควรทำให้ใช้งานได้กับ Android ทุกเวอร์ชัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.