Tengo HTML simple :
<h2>Title</h2><br>
<p>description here</p>
Quiero mostrar texto con estilo HTML en él TextView
. ¿Como hacer esto?
Tengo HTML simple :
<h2>Title</h2><br>
<p>description here</p>
Quiero mostrar texto con estilo HTML en él TextView
. ¿Como hacer esto?
Respuestas:
Debe usar Html.fromHtml()
para usar HTML en sus cadenas XML. Simplemente hacer referencia a una Cadena con HTML en su diseño XML no funcionará.
Esto es lo que debes hacer:
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
por definición crea mucho margen a su alrededor. y p
también viene con cierto margen. Si no desea la brecha, puede considerar usar otros elementos html.
android.text.Html.fromHtml
. Sé que la mayoría de los IDEs lo arreglarán por usted, pero para facilitar la lectura, es mejor conocer los nombres de los paquetes.
setText (Html.fromHtml (bodyData)) está en desuso después de la API 24. Ahora debe hacer esto:
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));
}
Echa un vistazo a esto: https://stackoverflow.com/a/8558249/450148
¡También es bastante bueno!
<resource>
<string name="your_string">This is an <u>underline</u> text demo for TextView.</string>
</resources>
Funciona solo para algunas etiquetas.
Si desea poder configurarlo a través de xml sin ninguna modificación en el código de Java, puede encontrar esta idea útil. Simplemente llame a init desde el constructor y configure el texto como 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"/>
Si está intentando mostrar HTML desde una identificación de recurso de cadena, es posible que el formato no se muestre en la pantalla. Si eso le sucede, intente usar etiquetas CDATA en su lugar:
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));
Vea esta publicación para más detalles.
El siguiente código me dio el mejor resultado.
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());
Si solo desea mostrar texto html y realmente no necesita un TextView
, entonces tome un WebView
y úselo como sigue:
String htmlText = ...;
webview.loadData(htmlText , "text/html; charset=UTF-8", null);
Esto tampoco lo restringe a unas pocas etiquetas html.
layout_height="wrap_content"
. Tendrás que establecer una altura explícita o match_parent en su lugar.
El mejor enfoque para usar secciones CData para la cadena en el archivo strings.xml para obtener una visualización real del contenido html en TextView, el fragmento de código a continuación le dará la idea justa.
//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));
La sección CData en el texto de cadena mantiene intactos los datos de la etiqueta html incluso después de formatear el texto usando el método String.format. Entonces, Html.fromHtml (str) funciona bien y verá el texto en negrita en el mensaje de bienvenida.
Salida:
Bienvenido, a tu tienda de aplicaciones de música favorita. Conectado como: nombre de usuario
Vale la pena mencionar que el método Html.fromHtml (String source) está en desuso a partir del nivel de API 24. Si esa es su API de destino, debería usar Html.fromHtml (String source, int flags) en su lugar.
También me gustaría sugerir el siguiente proyecto: https://github.com/NightWhistler/HtmlSpanner
El uso es casi el mismo que el convertidor de Android predeterminado:
(new HtmlSpanner()).fromHtml()
Lo encontré después de que ya comencé con la implementación propia del convertidor html a spannable, porque Html.fromHtml estándar no proporciona suficiente flexibilidad sobre el control de representación e incluso no hay posibilidad de usar fuentes personalizadas desde ttf
Sé que esta pregunta es vieja. Otras respuestas aquí sugieren Html.fromHtml()
método. Te sugiero que uses HtmlCompat.fromHtml()
del androidx.core.text.HtmlCompat
paquete. Como esta es una versión de Html
clase compatible con versiones anteriores .
Código de muestra:
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);
De esta manera, puede evitar la verificación de la versión de la API de Android y es fácil de usar (solución de línea única).
Uso simple Html.fromHtml("html string")
. Esto funcionará Si la cadena tiene etiquetas como <h1>
entonces vendrán espacios. Pero no podemos eliminar esos espacios. Si aún desea eliminar los espacios, puede eliminar las etiquetas en la cadena y luego pasar la cadena al método Html.fromHtml("html string");
. También, en general, estas cadenas provienen del servidor (dinámico), pero no con frecuencia, si es el caso, es mejor pasar la cadena como está al método que intentar eliminar las etiquetas de la cadena.
String value = html value ....
mTextView.setText(Html.fromHtml(value),TextView.BufferType.SPANNABLE)
Haz un método global como:
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;
}
También puede usarlo en su Actividad / Fragmento como:
text_view.setText(stripHtml(htmlText));
He implementado esto usando la vista web. En mi caso, tengo que cargar la imagen de la URL junto con el texto en la vista de texto y esto funciona para mí.
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);
Se ha sugerido a través de varias respuestas usar la clase de marco Html como se sugiere aquí, pero desafortunadamente esta clase tiene un comportamiento diferente en diferentes versiones de Android y varios errores no solucionados, como se demuestra en los números 214637 , 14778 , 235128 y 75953 .
Por lo tanto, es posible que desee utilizar una biblioteca de compatibilidad para estandarizar y respaldar la clase Html en las versiones de Android que incluye más devoluciones de llamada para elementos y estilo:
Si bien es similar a la clase Html del marco, se requirieron algunos cambios de firma para permitir más devoluciones de llamada. Aquí está la muestra de la página de 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);
Cada vez que escriba una vista de texto personalizada, la función de texto del conjunto HTML básico desaparecerá de algunos de los dispositivos.
Por lo tanto, debemos hacer los siguientes pasos adicionales: hacer que funcione
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()));
}
}
}
actualización de la respuesta anterior
Use el siguiente código para obtener la solución:
textView.setText(fromHtml("<Your Html Text>"))
Método de utilería
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;
}
¿Puedo sugerir una solución un tanto hacky pero genial? Obtuve la idea de este artículo y la adapté para Android. Básicamente, usa WebView
ay inserta el HTML que desea mostrar y editar en una etiqueta div editable. De esta forma, cuando el usuario toca WebView
el teclado, aparece el teclado y permite la edición. ¡Simplemente agregue algo de JavaScript para recuperar el HTML editado y listo!
Aquí está el código:
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;
}
}
Y aquí está el componente como un Gist.
Nota: no necesitaba la devolución de llamada de cambio de altura de la solución original, por lo que falta aquí, pero puede agregarla fácilmente si es necesario.
Si usa androidx.
* clases en su proyecto, debe usar HtmlCompat.fromHtml(text, flag)
. La fuente del método es:
@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);
}
Es mejor manera que Html.fromHtml ya que hay menos código, solo una línea y la forma recomendada de usarlo.
Puede usar una función de extensión Kotlin simple como esta:
fun TextView.setHtmlText(source: String) {
this.text = HtmlCompat.fromHtml(source, HtmlCompat.FROM_HTML_MODE_LEGACY)
}
Y uso:
textViewMessage.setHtmlText("Message: <b>Hello World</b>")
Simplemente use:
String variable="StackOverflow";
textView.setText(Html.fromHtml("<b>Hello : </b>"+ variable));