Tôi có HTML đơn giản :
<h2>Title</h2><br>
<p>description here</p>
Tôi muốn hiển thị văn bản theo kiểu HTML TextView
. làm như thế nào?
Tôi có HTML đơn giản :
<h2>Title</h2><br>
<p>description here</p>
Tôi muốn hiển thị văn bản theo kiểu HTML TextView
. làm như thế nào?
Câu trả lời:
Bạn cần sử dụng Html.fromHtml()
để sử dụng HTML trong Chuỗi XML của mình. Chỉ cần tham khảo Chuỗi có HTML trong bố cục của bạn XML sẽ không hoạt động.
Đây là những gì bạn nên làm:
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
theo định nghĩa tạo ra rất nhiều lề xung quanh chính nó. và p
cũng đi kèm với một số lề. nếu bạn không muốn khoảng cách, bạn có thể muốn xem xét sử dụng các yếu tố html khác.
android.text.Html.fromHtml
. Tôi biết hầu hết các IDE sẽ sửa nó cho bạn nhưng để dễ đọc thì nên biết tên gói.
setText (Html.fromHtml (bodyData)) đang bị phản đối sau khi api 24. Bây giờ bạn phải làm điều này:
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));
}
Hãy xem cái này: https://stackoverflow.com/a/8558249/450148
Nó cũng khá tốt !!
<resource>
<string name="your_string">This is an <u>underline</u> text demo for TextView.</string>
</resources>
Nó chỉ hoạt động cho một vài thẻ.
Nếu bạn muốn có thể định cấu hình nó thông qua xml mà không cần sửa đổi gì trong mã java, bạn có thể thấy ý tưởng này hữu ích. Đơn giản là bạn gọi init từ constructor và đặt văn bản là 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"/>
Nếu bạn đang cố gắng hiển thị HTML từ id tài nguyên chuỗi, định dạng có thể không hiển thị trên màn hình. Nếu điều đó đang xảy ra với bạn, hãy thử sử dụng thẻ CDATA thay thế:
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));
Xem bài đăng này để biết thêm chi tiết.
Các mã dưới đây đã cho kết quả tốt nhất cho tôi.
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());
Nếu bạn chỉ muốn hiển thị một số văn bản html và không thực sự cần a TextView
, thì hãy lấy WebView
và sử dụng nó như sau:
String htmlText = ...;
webview.loadData(htmlText , "text/html; charset=UTF-8", null);
Điều này cũng không giới hạn bạn trong một vài thẻ html.
layout_height="wrap_content"
. Thay vào đó, bạn sẽ phải đặt chiều cao rõ ràng hoặc match_parent.
Cách tiếp cận tốt nhất để sử dụng các phần CData cho chuỗi trong tệp String.xml để hiển thị thực tế nội dung html cho TextView đoạn mã dưới đây sẽ cho bạn ý tưởng hợp lý.
//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));
Phần CData trong văn bản chuỗi giữ nguyên dữ liệu thẻ html ngay cả sau khi định dạng văn bản bằng phương thức String.format. Vì vậy, Html.fromHtml (str) hoạt động tốt và bạn sẽ thấy văn bản in đậm trong thông điệp Chào mừng.
Đầu ra:
Chào mừng bạn đến cửa hàng ứng dụng âm nhạc yêu thích của bạn. Đăng nhập với tên: tên người dùng
Điều đáng nói là phương thức Html.fromHtml (Nguồn chuỗi) không được dùng cho cấp API 24. Nếu đó là API mục tiêu của bạn, bạn nên sử dụng Html.fromHtml (Nguồn chuỗi, cờ int) .
Tôi cũng muốn đề xuất dự án sau: https://github.com/NightWhistler/HtmlSpanner
Cách sử dụng gần giống như trình chuyển đổi Android mặc định:
(new HtmlSpanner()).fromHtml()
Tìm thấy nó sau khi tôi đã bắt đầu bằng cách triển khai html sang trình chuyển đổi có thể mở rộng, bởi vì Html.fromHtml tiêu chuẩn không cung cấp đủ tính linh hoạt đối với kiểm soát kết xuất và thậm chí không có khả năng sử dụng phông chữ tùy chỉnh từ ttf
Tôi biết câu hỏi này là cũ. Các câu trả lời khác ở đây gợi ýHtml.fromHtml()
phương pháp. Tôi đề nghị bạn sử dụng HtmlCompat.fromHtml()
từ androidx.core.text.HtmlCompat
gói. Vì đây là phiên bản tương thích ngược củaHtml
lớp.
Mã mẫu:
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);
Bằng cách này, bạn có thể tránh kiểm tra phiên bản API của Android và thật dễ sử dụng (giải pháp một dòng).
Sử dụng đơn giản Html.fromHtml("html string")
. Điều này sẽ làm việc. Nếu chuỗi có các thẻ như <h1>
thì không gian sẽ đến. Nhưng chúng ta không thể loại bỏ những không gian đó. Nếu bạn vẫn muốn xóa khoảng trắng, thì bạn có thể xóa các thẻ trong chuỗi và sau đó chuyển chuỗi sang phương thức Html.fromHtml("html string");
. Ngoài ra, nhìn chung các chuỗi này đến từ máy chủ (động) nhưng không thường xuyên, nếu đó là trường hợp tốt hơn để truyền chuỗi vì nó là phương thức hơn là cố gắng loại bỏ các thẻ khỏi chuỗi.
String value = html value ....
mTextView.setText(Html.fromHtml(value),TextView.BufferType.SPANNABLE)
Thực hiện một phương pháp toàn cầu như:
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;
}
Bạn cũng có thể sử dụng nó trong Activity / Fragment của mình như:
text_view.setText(stripHtml(htmlText));
Tôi đã thực hiện điều này bằng cách sử dụng xem web. Trong trường hợp của tôi, tôi phải tải hình ảnh từ URL cùng với văn bản trong chế độ xem văn bản và điều này làm việc cho tôi.
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);
Nó đã được đề xuất thông qua các câu trả lời khác nhau để sử dụng lớp khung Html như được đề xuất ở đây, nhưng thật không may, lớp này có hành vi khác nhau trong các phiên bản khác nhau của Android và các lỗi không được khắc phục khác nhau, như đã được trình bày trong các vấn đề 214637 , 14778 , 235128 và 75953 .
Do đó, bạn có thể muốn sử dụng thư viện tương thích để chuẩn hóa và nhập lại lớp Html trên các phiên bản Android, bao gồm nhiều cuộc gọi lại cho các yếu tố và kiểu dáng:
Mặc dù tương tự như lớp Html của khung công tác, một số thay đổi chữ ký được yêu cầu để cho phép nhiều cuộc gọi lại hơn. Đây là mẫu từ trang 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);
Bất cứ khi nào bạn viết tùy chỉnh xem văn bản, tính năng văn bản của bộ HTML sẽ bị biến mất dưới dạng một số thiết bị.
Vì vậy, chúng ta cần phải làm theo các bước gây nghiện sau đây là công việc
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()));
}
}
}
cập nhật câu trả lời ở trên
Sử dụng mã dưới đây để có được giải pháp:
textView.setText(fromHtml("<Your Html Text>"))
Phương pháp sử dụng
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;
}
Tôi có thể đề nghị một giải pháp hơi khó khăn nhưng vẫn thiên tài! Tôi đã có ý tưởng từ bài viết này và điều chỉnh nó cho Android. Về cơ bản, bạn sử dụng WebView
và chèn HTML bạn muốn hiển thị và chỉnh sửa trong thẻ div có thể chỉnh sửa. Cách này khi người dùng chạmWebView
bàn phím xuất hiện và cho phép chỉnh sửa. Họ chỉ cần thêm một số JavaScript để lấy lại HTML và voila đã chỉnh sửa!
Đây là mã:
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;
}
}
Và đây là thành phần như một Gist.
Lưu ý: Tôi không cần gọi lại thay đổi chiều cao từ giải pháp ban đầu để thiếu ở đây nhưng bạn có thể dễ dàng thêm nó nếu cần.
Nếu bạn sử dụng androidx.
các lớp * trong dự án của bạn, bạn nên sử dụng HtmlCompat.fromHtml(text, flag)
. Nguồn của phương thức là:
@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);
}
Đó là cách tốt hơn so với Html.fromHtml vì có ít mã hơn, chỉ có một dòng và cách được khuyến nghị để sử dụng nó.
Bạn có thể sử dụng chức năng mở rộng Kotlin đơn giản như thế này:
fun TextView.setHtmlText(source: String) {
this.text = HtmlCompat.fromHtml(source, HtmlCompat.FROM_HTML_MODE_LEGACY)
}
Và cách sử dụng:
textViewMessage.setHtmlText("Message: <b>Hello World</b>")
Đơn giản chỉ cần sử dụng:
String variable="StackOverflow";
textView.setText(Html.fromHtml("<b>Hello : </b>"+ variable));