TextView에 HTML을 표시하는 방법?


756

간단한 HTML이 있습니다 .

<h2>Title</h2><br>
<p>description here</p>

에 HTML 스타일의 텍스트를 표시하고 싶습니다 TextView. 이것을하는 방법?


7
태그를 표시하거나 생략 하시겠습니까?
DerMike


1
더 이상 사용되지 않는 솔루션을 찾고 있다면 바로 여기 stackoverflow.com/questions/37904739/…
crgarridos

답변:


1350

Html.fromHtml()XML 문자열에서 HTML 을 사용 하려면 사용해야합니다. 레이아웃 XML에서 HTML로 문자열을 참조하는 것만으로는 작동하지 않습니다.

이것이 당신이해야 할 일입니다.

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
    textView.setText(Html.fromHtml("<h2>Title</h2><br><p>Description here</p>", Html.FROM_HTML_MODE_COMPACT));
} else { 
    textView.setText(Html.fromHtml("<h2>Title</h2><br><p>Description here</p>"));
}

7
h2정의상 그 자체로 많은 마진이 생깁니다. 그리고 p일부 여유와 함께 제공됩니다. 차이를 원하지 않으면 다른 html 요소를 사용하는 것이 좋습니다.
David Hedlund

10
Kostadin, XML로 태그를 넣을 수 있습니다. CDATA 괄호로 묶으면됩니다.
Gerard

3
ol / ul / li 태그를 사용하려는 사람들은 다음 솔루션을 확인하십시오. stackoverflow.com/a/3150456/1369016
Tiago

13
이어야합니다 android.text.Html.fromHtml. 나는 대부분의 IDE가 당신을 위해 그것을 고칠 것이라는 것을 알고 있지만 가독성을 위해 패키지 이름을 아는 것이 좋습니다.
Martin

14
@Martin 나는 가독성을 말하지 않고 오히려 철저 함을 말할 것이다 . 이와 같이 코드에서 직접 사용되는 IMO 정규화 된 이름은 짧은 이름보다 읽기 어렵습니다. 그러나 나는 이와 같은 답변이 패키지를 제공해야한다는 사실에 동의합니다. (
부록에

76

setText (Html.fromHtml (bodyData)) 는 API 24 이후 더 이상 사용되지 않습니다 . 이제 다음을 수행해야합니다.

 if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
      tvDocument.setText(Html.fromHtml(bodyData,Html.FROM_HTML_MODE_LEGACY));
 } else {
      tvDocument.setText(Html.fromHtml(bodyData));
 }

4
API 24 이상에서 FROM_HTML_MODE_LEGACY를 사용하는 이유는 무엇입니까?
galcyurio

64

이것에 대해 살펴보십시오 : https : //.com/a/8558249/450148

너무 좋습니다!

<resource>
    <string name="your_string">This is an <u>underline</u> text demo for TextView.</string>
</resources>

태그가 거의없는 경우에만 작동합니다.


12
이 방법이 지원하는 태그 목록이 있습니까?
mente

23
@mente 소스 코드에 따름 : <a>, <b>, <big>, <blockquote>, <br>, <cite>, <dfn> <div align = "...">, <em>, < font size = "..."color = "..."face = "..."> <h1-6>, <i>, <img src = "...">, <p>, <small > <strike>, <strong>, <sub>, <sup>, <tt>, <u> (source : dzone.com/snippets/how-display-html-android )
JerabekJakub

@JerabekJakub 그러나주의하십시오. img를 처리하려면 Html.ImageGetter를 구현해야합니다.
MiguelHincapieC

img를 구현할 때 @ 0mahc0 크기를 설정할 수 있습니까?
Joh

1
@Joh 네 가능합니다. .ImageGetter를 구현할 때 getDrawable (String source)이라는 메소드가 있습니다. 더 도움이 필요하면 질문을 작성하고 태그를 지정하십시오. 예를
들겠습니다

41

Java 코드를 수정하지 않고 xml을 통해 구성하려면이 아이디어가 도움이 될 수 있습니다. 간단히 생성자에서 init를 호출하고 텍스트를 html로 설정하십시오.

public class HTMLTextView extends TextView {
    ... constructors calling init...
    private void init(){
       setText(Html.fromHtml(getText().toString()));
    }    
}

xml :

<com.package.HTMLTextView
android:text="@string/about_item_1"/>

1
'...'는 무엇입니까? 설명하십시오
GilbertS

25

문자열 리소스 ID에서 HTML을 표시하려고하면 형식이 화면에 표시되지 않을 수 있습니다. 그럴 경우 CDATA 태그를 대신 사용해보십시오.

strings.xml:
<string name="sample_string"><![CDATA[<h2>Title</h2><br><p>Description here</p>]]></string>

...

MainActivity.java:
text.setText(Html.fromHtml(getString(R.string.sample_string));

자세한 내용은이 게시물 을 참조 하십시오.


감사합니다. API 23을 사용하여 저에게 도움이되었습니다.
XMAN

24

아래 코드는 나에게 가장 좋은 결과를 주었다.

TextView myTextview = (TextView) findViewById(R.id.my_text_view);
htmltext = <your html (markup) character>;
Spanned sp = Html.fromHtml(htmltext);
myTextview.setText(sp);

13
String value = "<html> <a href=\"http://example.com/\">example.com</a> </html>";
    SiteLink= (TextView) findViewById(R.id.textViewSite);
    SiteLink.setText(Html.fromHtml(value));
    SiteLink.setMovementMethod(LinkMovementMethod.getInstance());

앵커의 색상을 어떻게 변경합니까?
EdmundYeung99

android : textColorLink = "color"
페드로

이것은 전체 텍스트보기를 빨간색으로 채색하지만 앵커 태그 만 원한다면 <a> 태그를 <font> 태그로 감싸고 거기에 색상을 추가해야합니다.
EdmundYeung99

11

html 텍스트를 표시하고 정말로 필요하지 않은 경우 TextViewa WebView를 사용하여 다음과 같이 사용하십시오.

String htmlText = ...;
webview.loadData(htmlText , "text/html; charset=UTF-8", null);

html 태그로 제한하지는 않습니다.


2
TextView에서 지원하는 제한된 html 태그 세트를 해결하는 매우 유용한 방법이지만 제대로 작동하지 않는다는 단점이 있습니다. 와를 layout_height="wrap_content". 대신 명시적인 높이 또는 match_parent를 설정해야합니다.
Ridcully

3
webview는 매우 느리다
Jackky777

11

strings.xml 파일의 문자열에 CData 섹션을 사용하여 html 내용을 TextView에 실제로 표시하려면 아래 코드 스 니펫을 사용하는 것이 가장 좋습니다.

//in string.xml file
<string name="welcome_text"><![CDATA[<b>Welcome,</b> to the forthetyroprogrammers blog Logged in as:]]> %1$s.</string>

//and in Java code
String welcomStr=String.format(getString(R.string.welcome_text),username);
tvWelcomeUser.setText(Html.fromHtml(welcomStr));

문자열 텍스트의 CData 섹션은 String.format 메서드를 사용하여 텍스트를 포맷 한 후에도 html 태그 데이터를 그대로 유지합니다. 따라서 Html.fromHtml (str)이 제대로 작동하면 시작 메시지에 굵은 글씨가 표시됩니다.

산출:

좋아하는 음악 앱 스토어에 오신 것을 환영합니다. 다음으로 로그인 : username


감사합니다. API 23을 사용하여 나를 위해 해냈습니다.
XMAN

고마워, u 내 하루를 저장 :) 작은 추가 : 위의 코드 에이 검사를 추가해야합니다. if (Build.VERSION.SDK_INT> = Build.VERSION_CODES.N) {// 24 api 이상 textView.setText ( Html.fromHtml (welcomStr, Html.FROM_HTML_OPTION_USE_CSS_COLORS)); } else {// 또는 이전 API의 경우 textView.setText (Html.fromHtml (welcomStr)); }. API> = 24의 두 번째 매개 변수 플래그 값은 요구 사항에 따라 달라질 수 있습니다.
AndroidGuy


6

다음 프로젝트를 제안하고 싶습니다 : https://github.com/NightWhistler/HtmlSpanner

사용법은 기본 안드로이드 변환기와 거의 동일합니다.

(new HtmlSpanner()).fromHtml()

표준 Html.fromHtml은 렌더링 제어에 대한 충분한 유연성을 제공하지 않으며 심지어 ttf의 사용자 정의 글꼴을 사용할 가능성도 없기 때문에 이미 html에서 확장 가능한 변환기로 자체 구현을 시작한 후에 그것을 발견했습니다.


다음과 같은 오류가 발생합니다. 오류 : (80, 13) 해결하지 못했습니다 : com.osbcp.cssparser : cssparser : 1.5이 문제를 어떻게 해결합니까?
Araju

6

나는이 질문이 오래되었다는 것을 안다. Html.fromHtml()방법을 제안 하는 다른 답변 . 난 당신이 사용하는 것이 좋습니다 HtmlCompat.fromHtml()에서 androidx.core.text.HtmlCompat패키지로 제공된다. 이것은 이전 버전과 호환되는 버전이므로Html 클래스입니다.

샘플 코드 :

import androidx.core.text.HtmlCompat;
import android.text.Spanned;
import android.widget.TextView;

String htmlString = "<h1>Hello World!</h1>";

Spanned spanned = HtmlCompat.fromHtml(htmlString, HtmlCompat.FROM_HTML_MODE_COMPACT);

TextView tvOutput = (TextView) findViewById(R.id.text_view_id);

tvOutput.setText(spanned);

이러한 방식으로 Android API 버전 확인을 피할 수 있으며 사용하기 쉽습니다 (단일 솔루션).


그것은 오래된 메 토트와 어떻게 다릅니 까? HTML 모드의 목적은 무엇입니까?
user1209216

1
이와 같은 것을 찾고있었습니다. 감사합니다 :)
Subhrajyoti Sen

5

간단한 사용 Html.fromHtml("html string"). 작동합니다. 문자열에 태그가 있으면 <h1>공백이 생깁니다. 그러나 우리는 그 공간을 제거 할 수 없습니다. 여전히 공백을 제거하려면 문자열에서 태그를 제거한 다음 문자열을 메소드에 전달하면 Html.fromHtml("html string");됩니다. 또한 일반적으로 이러한 문자열은 서버 (동적)에서 나오지만 문자열에서 태그를 제거하는 것보다 메서드에 그대로 문자열을 전달하는 것이 더 나은 경우가 종종 있습니다.


4
String value = html value ....
mTextView.setText(Html.fromHtml(value),TextView.BufferType.SPANNABLE)

4

다음과 같은 전역 방법을 만드십시오.

public static Spanned stripHtml(String html) {
            if (!TextUtils.isEmpty(html)) {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                    return Html.fromHtml(html, Html.FROM_HTML_MODE_COMPACT);
                } else {
                    return Html.fromHtml(html);
                }
            }
            return null;
        }

다음과 같이 액티비티 / 프레임에서 사용할 수도 있습니다.

text_view.setText(stripHtml(htmlText));

3

웹보기를 사용하여 이것을 구현했습니다. 제 경우에는 텍스트보기의 텍스트와 함께 URL에서 이미지를로드해야하며 이것은 저에게 효과적입니다.

WebView myWebView =new WebView(_context);
        String html = childText;
        String mime = "text/html";
        String encoding = "utf-8";
        myWebView.getSettings().setJavaScriptEnabled(true);
        myWebView.loadDataWithBaseURL(null, html, mime, encoding, null);

UTF-8을 올바르게 표시하려면 MIME 유형을 "text / html; charset = UTF-8"로 설정해야합니다.
shawkinaw

3

여기에 제안 된 대로 Html 프레임 워크 클래스 를 사용하는 다양한 답변을 통해 제안되었지만 불행히도이 클래스는 문제 214637 , 14778 , 235128 에서 설명한 바와 같이 다양한 Android 버전 및 다양한 주소 지정되지 않은 버그에서 다르게 작동합니다.75953 다릅니다 .

따라서 호환성 라이브러리를 사용하여 요소 및 스타일에 대한 더 많은 콜백을 포함하는 Android 버전에서 Html 클래스를 표준화하고 백 포트 할 수 있습니다.

Github 프로젝트 HTMLCompat

프레임 워크의 Html 클래스와 유사하지만 더 많은 콜백을 허용하기 위해 일부 서명 변경이 필요했습니다. GitHub 페이지의 샘플은 다음과 같습니다.

Spanned fromHtml = HtmlCompat.fromHtml(context, source, 0);
// You may want to provide an ImageGetter, TagHandler and SpanCallback:
//Spanned fromHtml = HtmlCompat.fromHtml(context, source, 0,
//        imageGetter, tagHandler, spanCallback);
textView.setMovementMethod(LinkMovementMethod.getInstance());
textView.setText(fromHtml);

@MartijnPieters 이전에 마감 된 답변은 프레임 워크 방법의 사용 중단과 관련하여이 질문에 대한 답변과 중복되었습니다 . 호환성 라이브러리를 사용하는 것이 더 나은 접근 방식 인 이유를 확장했습니다. 두 질문을 명확하게 다른 두 개의 질문으로 표시하는 것이 합리적이라고 생각하지 않습니다.
Paul Lammertsma

2

사용자 정의 텍스트보기를 작성할 때마다 기본 HTML 세트 텍스트 기능이 일부 장치에서 사라집니다.

따라서 우리는 다음과 같은 추가 단계를 수행해야합니다.

public class CustomTextView extends TextView {

    public CustomTextView(..) {
        // other instructions
        setText(Html.fromHtml(getText().toString()));
    }
}

1
public class HtmlTextView extends AppCompatTextView {

public HtmlTextView(Context context) {
    super(context);
    init();
}

private void init(){
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        setText(Html.fromHtml(getText().toString(), Html.FROM_HTML_MODE_COMPACT));
    } else {
        setText(Html.fromHtml(getText().toString()));
    }
 }
}

답변 업데이트


1

솔루션을 얻으려면 아래 코드를 사용하십시오.

textView.setText(fromHtml("<Your Html Text>"))

자폐증 방법

public static Spanned fromHtml(String text)
{
    Spanned result;
    if (Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
        result = Html.fromHtml(text, Html.FROM_HTML_MODE_LEGACY);
    } else {
        result = Html.fromHtml(text);
    }
    return result;
}

1

만든 코 틀린의 확장 변환하는 HTML을 에서 문자열 -

fun String?.toHtml(): Spanned? {
    if (this.isNullOrEmpty()) return null
    return HtmlCompat.fromHtml(this, HtmlCompat.FROM_HTML_MODE_COMPACT)
}

0

다소 해 키지 만 여전히 천재적인 해결책을 제안 할 수 있습니다! 이 기사 에서 아이디어를 얻어 Android에 맞게 조정했습니다. 기본적으로 a를 사용 WebView하고 편집 가능한 div 태그에 표시하고 편집하려는 HTML을 삽입하십시오. 이렇게하면 사용자가WebView 가 키보드를 누르면 키보드가 나타나고 편집 할 수 있습니다. 편집 한 HTML과 짜잔을 다시 얻기 위해 JavaScript를 추가하면됩니다!

코드는 다음과 같습니다.

public class HtmlTextEditor extends WebView {

    class JsObject {
        // This field always keeps the latest edited text
        public String text;
        @JavascriptInterface
        public void textDidChange(String newText) {
            text = newText.replace("\n", "");
        }
    }

    private JsObject mJsObject;

    public HtmlTextEditor(Context context, AttributeSet attrs) {
        super(context, attrs);

        getSettings().setJavaScriptEnabled(true);
        mJsObject = new JsObject();
        addJavascriptInterface(mJsObject, "injectedObject");
        setWebViewClient(new WebViewClient(){
            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
                loadUrl(
                        "javascript:(function() { " +
                            "    var editor = document.getElementById(\"editor\");" +
                            "    editor.addEventListener(\"input\", function() {" +
                            "        injectedObject.textDidChange(editor.innerHTML);" +
                            "    }, false)" +
                            "})()");
            }
        });
    }

    public void setText(String text) {
        if (text == null) { text = ""; }

        String editableHtmlTemplate = "<!DOCTYPE html>" + "<html>" + "<head>" + "<meta name=\"viewport\" content=\"initial-scale=1.0\" />" + "</head>" + "<body>" + "<div id=\"editor\" contenteditable=\"true\">___REPLACE___</div>" + "</body>" + "</html>";
        String editableHtml = editableHtmlTemplate.replace("___REPLACE___", text);
        loadData(editableHtml, "text/html; charset=utf-8", "UTF-8");
        // Init the text field in case it's read without editing the text before
        mJsObject.text = text;
    }

    public String getText() {
        return mJsObject.text;
    }
}

그리고 여기 요점으로서의 구성 요소가 있습니다.

참고 : 원래 솔루션에서 높이 변경 콜백이 필요하지 않으므로 여기에 누락되어 있지만 필요한 경우 쉽게 추가 할 수 있습니다.


0

androidx.프로젝트에서 * 클래스 를 사용하는 경우을 사용해야합니다 HtmlCompat.fromHtml(text, flag). 방법의 출처는 다음과 같습니다.

@NonNull public static Spanned fromHtml(@NonNull String source, @FromHtmlFlags int flags) { if (Build.VERSION.SDK_INT >= 24) { return Html.fromHtml(source, flags); } //noinspection deprecation return Html.fromHtml(source); }

코드가 적고 한 줄만 사용하고 권장되는 방법이 있으므로 Html.fromHtml보다 낫습니다.


0

다음과 같이 간단한 Kotlin 확장 기능을 사용할 수 있습니다.

fun TextView.setHtmlText(source: String) {
    this.text = HtmlCompat.fromHtml(source, HtmlCompat.FROM_HTML_MODE_LEGACY)
}

그리고 사용법 :

textViewMessage.setHtmlText("Message: <b>Hello World</b>")

0

간단히 사용하십시오 :

String variable="StackOverflow";
textView.setText(Html.fromHtml("<b>Hello : </b>"+ variable));
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.