Thẻ Html List không hoạt động trong android textview. tôi có thể làm gì?


99

Thẻ Danh sách Html không hoạt động trong TextView của android. Đây là nội dung chuỗi của tôi:

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

Tôi đã tải nó ở dạng xem văn bản như thế này:

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

Đầu ra trông giống như một đoạn văn. Tôi có thể làm gì? Có giải pháp nào cho nó không?

Biên tập:

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

1
Nên là text / html không phải texl / html.
Chloe

Câu trả lời:


156

Như bạn có thể thấy trong Htmlmã nguồn lớp , Html.fromHtml(String)không hỗ trợ tất cả các thẻ HTML. Trong trường hợp này, <ul><li>không được hỗ trợ.

Từ mã nguồn, tôi đã xây dựng một danh sách các thẻ HTML được phép:

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

Vì vậy, tốt hơn bạn nên sử dụng WebViewloadDataWithBaseURLphương pháp của nó . Hãy thử một cái gì đó như sau:

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

sau đó tôi có thể làm gì để khắc phục nó?
Praveen

2
rất quan trọng cần lưu ý rằng một số thuộc tính của thẻ "được phép" này cũng không được hỗ trợ. : = (
Jorgesys

2
Bình tĩnh ... Tôi đã chỉnh sửa câu trả lời của mình, vui lòng cho tôi biết nó có hoạt động không.
Cristian

6
Bạn thực sự không thể sử dụng WebView theo cách tương tự, vì vậy đây thực sự không phải là một giải pháp cho tất cả các vấn đề.
Brill Pappin

11
Đó là một giải pháp như thế nào? bạn không thể chỉ sử dụng WebView, nó là một tiện ích rất đắt tiền so với TextView. Bạn không thể chỉ sử dụng WebView cho mọi văn bản được định dạng mà bạn có.
SpaceMonkey

135

Tôi đang gặp vấn đề tương tự, những gì tôi đã làm là ghi đè giá trị mặc định TagHandler . Điều này đã làm việc cho tôi.

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

và để hiển thị văn bản ...

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

[Biên tập]

Kuitsi cũng đã đăng một thư viện tốt làm tương tự, lấy nó từ liên kết SO này .


Cuối cùng chúng tôi đã sử dụng cách tiếp cận này. Bất kỳ thẻ HTML nào không được hỗ trợ, chúng tôi tự viết mã bằng văn bản. Bây giờ nó chỉ là ol và ul, nhưng chúng tôi đã thêm vào các ngăn xếp để xử lý việc lồng danh sách và lưu trữ các chỉ mục khi lồng ol. Ngoài ra, bạn có thể sử dụng tham số mở boolean thay thế cho tham số đầu tiên.
JonWillis

6
@Aman Gautam rất tuyệt, cảm ơn vì điều này! Bạn có bất kỳ ý tưởng nào về cách tab văn bản khi nó bao quanh nhiều hơn 1 dòng không? Với mã này sau dòng thứ 2, văn bản được căn chỉnh với số chứ không phải theo tab để giữ số riêng biệt. Tôi đã cố gắng một vài điều nhưng tôi không thể hình dung nó ra
Ryang

điều tương tự ở đây, dấu ngắt dòng trong danh sách gây ra trobule với cách tiếp cận này.
Andreas Rudolph

Thay vì sử dụng ký tự dấu đầu dòng đã dán, có thể tốt hơn là sử dụng ký tự unicode: output.append ("\ n \ t \ u2022");
Matt McMinn

Cảm ơn bạn đã mã đẹp này, nhưng tôi không thể sử dụng nó cho đến khi chúng tôi sẽ tìm một giải pháp làm thế nào để sửa chữa các dòng thụt đầu dòng nhiều
peter.bartos

68

Dự án mẫu đầy đủ có tại https://bitbucket.org/Kuitsi/android-textview-html-list .
Hình ảnh mẫu có sẵn tại https://kuitsi.bitbucket.io/stackoverflow3150400_screen.png

Giải pháp này gần nhất với câu trả lời của masha . Một số mã cũng được lấy từ lớp bên trong android.text.Html.HtmlToSpannedConverter. Nó hỗ trợ danh sách có thứ tự và không có thứ tự lồng nhau nhưng văn bản quá dài trong danh sách có thứ tự vẫn được căn chỉnh với số mục chứ không phải văn bản. Danh sách hỗn hợp (ol và ul) cũng cần một số công việc. Dự án mẫu chứa việc triển khai Html.TagHandler được chuyển đến Html.fromHtml (String, ImageGetter, TagHandler) .

Chỉnh sửa: Để hỗ trợ thẻ HTML rộng hơn, https://github.com/NightWhistler/HtmlSpanner cũng có thể đáng thử.


Cho đến nay giải pháp tốt nhất. Xin cảm ơn
peter.bartos

Không có vấn đề theo dõi trong kho BitBucket, vì vậy hãy đăng ở đây: bạn cần thêm kiểm tra ở đâyở đây đối output.length() > 0vớiif (output.length() > 0 && output.charAt(output.length() - 1) != '\n')
mindeh

2
Chỉ để tránh người khác lãng phí 2 giờ vào việc này, NightWhistler HtmlSpanner sẽ xóa tất cả các ký tự có dấu vì bất kỳ lý do gì không xác định.
EpicPandaForce

@Kuitsi cảm ơn vì giải pháp. Có một vấn đề với nó, khi văn bản html là "<ul> <li> something </li> </ul>", thì ký tự cuối cùng trong "something" không được hiển thị trong danh sách.
Sam Berg

Đây là một giải pháp rất tốt, NHƯNG có hai nhược điểm: 1) nó không hỗ trợ Android ≥ 7 và 2) nó không đặt thụt lề bắt đầu cho cấp đầu tiên của danh sách.
soshial

24

Một bản sửa lỗi nhỏ cho mã Aman Guatam. Hàm trên gặp sự cố khi hiển thị ký tự dòng mới. Ví dụ: nếu trước <li>thẻ là một <p>thẻ, thì 2 ký tự dòng mới được hiển thị. Đây là mã được nâng cấp:

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

Đơn giản nhưng hiệu quả
steven0529

Còn về danh sách đặt hàng?
nhà phát triển android

13

CẢNH BÁO

kể từ ngày 10 tháng 2 năm 2016 android.text.Htmlthực sự hỗ trợ liulgắn thẻ và sử dụng cơ bản new BulletSpan(), có nghĩa là trong các phiên bản Android mới nhất,Html.TagHandler giải pháp được đăng ở đây sẽ bị bỏ qua

đảm bảo mã của bạn xử lý thay đổi này trong trường hợp bạn đang mong đợi BulletSpan có khoảng cách lớn hơn mặc định, bạn sẽ phải có một số loại giải pháp để tìm / thay thế các nhịp


4
Nhưng lớp Html mới đó chỉ có sẵn trong Android Ntrở lên.
Sakiboy

1
Đúng - vì vậy bạn cần tính đến thực tế là các phiên bản hệ điều hành khác nhau sẽ hoạt động khác nhau. Do đó, tại sao tôi đề xuất một giải pháp tìm và thay thế BulletSpan sau khi HTML đã được phân tích cú pháp thành các nhịp khác nhau. Việc triển khai mặc định của các phiên bản sau N sẽ sử dụng một lề mặc định, bạn có thể tìm và thay thế chúng bằng một lề bạn muốn.
kassim

Luôn luôn cập nhật.
Kai Wang

9

Giải pháp khác nhau bằng cách sử dụng LeadingMarginSpan. Xử lý danh sách có thứ tự và không có thứ tự cũng như lồng vào nhau.

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
Tôi thích ý tưởng sử dụng Spans nhưng tôi không thể có được danh sách lồng nhau làm việc với mã này. Cả hai dòng đều output.setSpan(...)gặp sự cố vớijava.lang.RuntimeException: PARAGRAPH span must start at paragraph boundary
Kuitsi

Cảm ơn vì giải pháp tốt đẹp! Nó cũng Canh lề văn bản nhiều dòng
peter.bartos

2
tại sao bạn sử dụng Vector thay vì ArrayList đơn giản? một Vector dành cho nhiều chủ đề ...
nhà phát triển android.

@androiddeveloper c ++ lập trình viên, tôi tệ, vui lòng chỉnh sửa câu trả lời
masha

1
Tôi đã đăng dưới dạng Snippet androidsnippets.com/…
Pratik Butani,

8

Nếu bạn chỉ cần định dạng một danh sách, hãy giữ nó đơn giản và sao chép / dán một ký tự unicode vào TextView của bạn để đạt được kết quả tương tự.

• Ký tự Unicode 'BULLET' (U + 2022)


6

Tôi đến đây để tìm kiếm các triển khai TagHandler. Cả hai câu trả lời của Truong Nguyen và Aman Guatam đều rất hay, nhưng tôi cần một phiên bản hỗn hợp của cả hai: Tôi cần giải pháp của mình để không định dạng nó quá mức và có thể <ol>phân tích lại các thẻ, vì tôi đang phân tích cú pháp <h3>title</h3><ol><li>item</li><li>item</li><li>item</li></ol>.

Đây là giải pháp của tôi.

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

Lưu ý rằng, vì chúng tôi đang đặt lại giá trị chỉ mục bất cứ khi nào bắt đầu một danh sách mới, nó SẼ KHÔNG hoạt động nếu bạn lồng các danh sách như trong <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

Với mã đó, bạn sẽ nhận được 1, 1, 2, 3thay vì 1, 1, 2, 2.


Mã này hoạt động cho đến phiên bản 23. Làm thế nào để làm cho nó hoạt động cho 24 trở lên?
Abhinav Tyagi

3

Chắc chắn, có một cách để hiển thị dấu đầu dòng trong Android TextView. Bạn có thể thay thế <li>các thẻ bằng &#149;(là mã HTML cho dấu đầu dòng).

Nếu bạn muốn thử các biểu tượng danh sách khác, hãy sử dụng biểu tượng ưu tiên từ bảng là liên kết này;

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


Không làm việc cho tôi. Thay vào đó, trên Android 7.1.1 và 6.0.1, một hộp có dấu x xuyên qua nó sẽ xuất hiện thay vì dấu đầu dòng trong TextView.
dùng1652110

3

Bạn có thể chỉ cần thay thế "li" bằng mã đơn

    @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

Câu trả lời của Lord Voldermort là một điểm khởi đầu tốt. Tuy nhiên, tôi yêu cầu olthẻ để hiển thị danh sách có thứ tự 1. 2. 3. ....thay vì dấu đầu dòng. Ngoài ra, các thẻ lồng nhau cần xử lý đặc biệt để hoạt động bình thường.

Trong mã của tôi, tôi đã duy trì ngăn xếp (parentList) để theo dõi mở ra và khép kín ulolthẻ và cũng để biết thẻ mở hiện hành. Ngoài ra, a levelWiseCounterđược sử dụng để duy trì các số lượng khác nhau trong trường hợp các olthẻ lồng nhau .

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

Làm thế nào về mã tiếp theo (dựa trên liên kết này ):

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
Câu trả lời này chỉ có định dạng hơi khác so với nguồn gốc của câu trả lời này, được tạo ra để hỗ trợ một câu trả lời khác cho câu hỏi tương tự này: stackoverflow.com/a/17365740/262462 :)
Kuitsi

thật. không nhận thấy điều đó.
nhà phát triển android

2

Tôi đã gặp sự cố, rằng tôi luôn nhận được một dòng trống sau danh sách với giải pháp @Kuitsis. Tôi đã thêm một vài dòng trong handleTag () và bây giờ các dòng trống đã biến mất:

@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

Bạn có thể sử dụng Html.TagHandler. Dưới đây có thể được sử dụng cho 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

đây là một xác nhận cho những gì kassim đã nêu. có sự phân mảnh. tôi đã tìm thấy cách giải quyết vấn đề này. tôi phải đổi tên <li>và ul thành thẻ tùy chỉnh. vì thế:

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

thì trong trình xử lý của mình, tôi có thể tìm kiếm customTag đó (không có tác dụng gì) và làm cho nó thực hiện một số thứ.

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

điều này sẽ làm cho nó hoạt động cho tất cả các phiên bản của Android.

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.