Mam prosty HTML :
<h2>Title</h2><br>
<p>description here</p>
Chcę wyświetlić tekst w stylu HTML TextView
. Jak to zrobić?
Mam prosty HTML :
<h2>Title</h2><br>
<p>description here</p>
Chcę wyświetlić tekst w stylu HTML TextView
. Jak to zrobić?
Odpowiedzi:
Musisz użyć, Html.fromHtml()
aby użyć HTML w ciągach XML. Po prostu odwołanie się do ciągu za pomocą HTML w układzie XML nie będzie działać.
Oto co powinieneś zrobić:
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>"));
}
h2
z definicji tworzy wokół siebie duży margines. a p
także ma pewien margines. jeśli nie chcesz odstępu, możesz rozważyć użycie innych elementów HTML.
android.text.Html.fromHtml
. Wiem, że większość IDE naprawi to dla ciebie, ale dla czytelności lepiej poznać nazwy pakietów.
setText (Html.fromHtml (bodyData)) jest przestarzały po API 24. Teraz musisz to zrobić:
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));
}
Spójrz na to: https://stackoverflow.com/a/8558249/450148
To też jest całkiem dobre !!
<resource>
<string name="your_string">This is an <u>underline</u> text demo for TextView.</string>
</resources>
Działa tylko z kilkoma tagami.
Jeśli chcesz mieć możliwość skonfigurowania go za pomocą xml bez żadnych modyfikacji w kodzie Java, ten pomysł może okazać się pomocny. Wystarczy wywołać init z konstruktora i ustawić tekst jako 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"/>
Jeśli próbujesz wyświetlić HTML z identyfikatora zasobu ciąg, formatowanie może nie zostać wyświetlone na ekranie. Jeśli tak się dzieje, spróbuj zamiast tego użyć tagów 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));
Zobacz ten post, aby uzyskać więcej informacji.
Poniższy kod dał mi najlepszy wynik.
TextView myTextview = (TextView) findViewById(R.id.my_text_view);
htmltext = <your html (markup) character>;
Spanned sp = Html.fromHtml(htmltext);
myTextview.setText(sp);
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());
Jeśli chcesz tylko wyświetlić tekst HTML i naprawdę nie potrzebujesz go TextView
, to weź WebView
i użyj go w następujący sposób:
String htmlText = ...;
webview.loadData(htmlText , "text/html; charset=UTF-8", null);
Nie ogranicza to również kilku tagów HTML.
layout_height="wrap_content"
. Zamiast tego będziesz musiał ustawić jawną wysokość lub match_parent.
Najlepsze podejście do korzystania z sekcji CData dla łańcucha w pliku strings.xml w celu uzyskania rzeczywistego wyświetlania zawartości HTML w TextView poniższy fragment kodu da ci dobry pomysł.
//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));
Sekcja CData w tekście ciągłym zachowuje nietknięte dane znacznika html nawet po sformatowaniu tekstu za pomocą metody String.format. Html.fromHtml (str) działa dobrze i zobaczysz pogrubiony tekst w wiadomości powitalnej.
Wynik:
Witamy w ulubionym sklepie z aplikacjami muzycznymi. Zalogowany jako: nazwa użytkownika
Warto wspomnieć, że metoda Html.fromHtml (ciąg znaków) jest przestarzała od poziomu API 24. Jeśli to jest twój docelowy interfejs API, powinieneś użyć Html.fromHtml (źródła ciągów, flagi int) .
Chciałbym również zasugerować następujący projekt: https://github.com/NightWhistler/HtmlSpanner
Użycie jest prawie takie samo jak domyślny konwerter Androida:
(new HtmlSpanner()).fromHtml()
Znalazłem go po tym, jak już rozpocząłem od własnej implementacji html do spanowalnego konwertera, ponieważ standardowy Html.fromHtml nie zapewnia wystarczającej elastyczności w zakresie kontroli renderowania, a nawet nie ma możliwości używania niestandardowych czcionek z ttf
Wiem, że to pytanie jest stare. Inne odpowiedzi tutaj sugerują Html.fromHtml()
metodę. Proponuję użyć HtmlCompat.fromHtml()
z androidx.core.text.HtmlCompat
pakietu. Ponieważ jest to wersja Html
klasy kompatybilna wstecz .
Przykładowy kod:
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);
W ten sposób można uniknąć sprawdzania wersji interfejsu API Androida i jest on łatwy w użyciu (rozwiązanie jednoliniowe).
Proste zastosowanie Html.fromHtml("html string")
. To zadziała. Jeśli ciąg ma tagi, <h1>
to będą spacje. Ale nie możemy wyeliminować tych przestrzeni. Jeśli nadal chcesz usunąć spacje, możesz usunąć tagi w ciągu, a następnie przekazać ciąg do metody Html.fromHtml("html string");
. Również ogólnie te ciągi pochodzą z serwera (dynamiczne), ale nie często, jeśli lepiej jest przekazać ciąg tak, jak jest w metodzie, niż próbować usunąć tagi z ciągu.
String value = html value ....
mTextView.setText(Html.fromHtml(value),TextView.BufferType.SPANNABLE)
Stwórz globalną metodę, taką jak:
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;
}
Możesz również użyć go w swojej aktywności / fragmencie, takich jak:
text_view.setText(stripHtml(htmlText));
Zaimplementowałem to za pomocą widoku internetowego. W moim przypadku muszę załadować obraz z adresu URL wraz z tekstem w widoku tekstowym i to działa dla mnie.
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);
Sugerowano przez różne odpowiedzi używać HTML klasę ramową jak sugeruje tutaj, ale niestety ta klasa ma różne zachowanie w różnych wersjach Androida i różnych bezadresowych błędów, jak wykazano w sprawach 214637 , 14778 , 235128 i 75953 .
Dlatego możesz użyć biblioteki kompatybilności do standaryzacji i wykonania kopii zapasowej klasy HTML w różnych wersjach Androida, która zawiera więcej wywołań zwrotnych elementów i stylów:
Chociaż jest podobny do klasy Html frameworka, konieczne były pewne zmiany sygnatur, aby umożliwić więcej wywołań zwrotnych. Oto przykład ze strony 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);
Za każdym razem, gdy piszesz niestandardowy widok tekstu, podstawowa funkcja ustawiania tekstu HTML zniknie z niektórych urządzeń.
Musimy więc wykonać następujące dodatkowe kroki, aby to działało
public class CustomTextView extends TextView {
public CustomTextView(..) {
// other instructions
setText(Html.fromHtml(getText().toString()));
}
}
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()));
}
}
}
aktualizacja odpowiedzi powyżej
Użyj poniższego kodu, aby uzyskać rozwiązanie:
textView.setText(fromHtml("<Your Html Text>"))
Metoda użyteczna
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;
}
Pozwól, że zasugeruję nieco pospieszne, ale genialne rozwiązanie! Pomysł zaczerpnąłem z tego artykułu i dostosowałem go do systemu Android. Zasadniczo używasz WebView
i wstawiasz HTML, który chcesz pokazać i edytować w edytowalnym znaczniku div. W ten sposób, gdy użytkownik stuknie, WebView
pojawi się klawiatura i umożliwia edycję. Po prostu dodajesz JavaScript, aby odzyskać edytowany kod HTML i voila!
Oto kod:
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;
}
}
I tutaj jest element jako Gist.
Uwaga: Nie potrzebowałem wywołania zwrotnego zmiany wysokości w stosunku do oryginalnego rozwiązania, więc tutaj go brakuje, ale w razie potrzeby można go łatwo dodać.
Jeśli używasz androidx.
* klas w swoim projekcie, powinieneś użyć HtmlCompat.fromHtml(text, flag)
. Źródło metody to:
@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);
}
Jest to lepszy sposób niż Html.fromHtml, ponieważ jest mniej kodu, tylko jedna linia i zalecany sposób jego użycia.
Możesz użyć prostej funkcji rozszerzenia Kotlin w następujący sposób:
fun TextView.setHtmlText(source: String) {
this.text = HtmlCompat.fromHtml(source, HtmlCompat.FROM_HTML_MODE_LEGACY)
}
I użycie:
textViewMessage.setHtmlText("Message: <b>Hello World</b>")
Po prostu użyj:
String variable="StackOverflow";
textView.setText(Html.fromHtml("<b>Hello : </b>"+ variable));