[android] Android TextView에서 HTML 목록 태그가 작동하지 않습니다. 어떡해?

Android TextView에서 HTML 목록 태그가 작동하지 않습니다. 이것은 내 문자열 내용입니다.

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



답변

당신은에서 볼 수 있듯이 Html클래스의 소스 코드 , Html.fromHtml(String)모든 HTML 태그를 지원하지 않습니다. 바로이 경우에, <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);


답변

동일한 문제가 있습니다. 내가 한 일은 기본 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 링크 에서 가져 왔습니다 .


답변

전체 샘플 프로젝트는 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 (문자열, ImageGetter, TagHandler을) .

편집 : 더 넓은 HTML 태그 지원을 위해 https://github.com/NightWhistler/HtmlSpanner 도 시도해 볼 가치가 있습니다.


답변

Aman Guatam 코드에 대한 작은 수정. 위의 함수는 개행 문자를 렌더링하는 문제가 있습니다. 예 : before <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;
            }
        }
    }
}


답변

경고

2016 년 2 월 10 일부터 android.text.Html실제로 기본을 지원 li하고 ul태그를 지정하고 사용합니다. new BulletSpan()즉, 최신 버전의 Android에서는 Html.TagHandler여기에 게시 된 솔루션이 무시됩니다.

BulletSpan이 기본값보다 더 큰 간격으로 예상되는 경우 코드가이 변경 사항을 처리하는지 확인하십시오. 스팬 찾기 / 교체를 수행하는 일종의 솔루션이 있어야합니다.


답변

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


답변

목록의 형식 만 지정해야하는 경우 단순하게 유지하고 동일한 결과를 얻으려면 TextView에 유니 코드 문자를 복사 / 붙여 넣기하십시오.

• 유니 코드 문자 ‘BULLET'(U + 2022)