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>"));
}
h2z definicji tworzy wokół siebie duży margines. a ptakż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ź WebViewi 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.HtmlCompatpakietu. Ponieważ jest to wersja Htmlklasy 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 WebViewi wstawiasz HTML, który chcesz pokazać i edytować w edytowalnym znaczniku div. W ten sposób, gdy użytkownik stuknie, WebViewpojawi 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));