原來只知道這個類可以轉換一些Html的標籤,常用的也就是fromHtml方法。但是之前一直不太明白這個方法的應用場景,最近通過項目的實踐,瞭解到了strings.xml中使用Html樣式的文案信息,然後通過更換顏色和字體樣式等方式,就能完成在一個TextView爲文案內容設置多種樣式的需求,這樣做還能減少layout中的組件使用數量,可以通過很少的組件就完成需求的頁面。
常用方法:
1.格式化字符串成Html樣式
publicstatic Spanned fromHtml(String source)
public static Spanned fromHtml(String source, ImageGetter imageGetter, TagHandler tagHandler)
以上兩個方法都是通過String內容轉換成Html樣式的內容,然後就可以賦值給TextView中。
第二個方法和第一個的區別在於第二個可以傳入圖片,但是需要注意這個圖片需要重寫ImageGetter纔可以支持網絡圖片獲取。
也可以重寫ImageGetter來獲取本地的圖片,或者傳入drawable的id來獲取drawable對象,這樣的做法可以用來實現內容包含表情的功能開發。
例如:聊天中輸入的editText和顯示的textView中通過這樣的方式獲取表情圖片。
2.public static String toHtml(Spanned text)
將spanned轉換String
3.常用的Html標籤和css:div,font,color,size,align,center,left,right(其中color可以傳入十六進制,但是注意轉義字符)
4.TagHandler的作用(特別像AngularJs中的自定義標籤)
就像註釋中的說明一樣,這個對象就是一個所有標籤的過濾器,可以通過重寫對象中的
public void handleTag(boolean opening, String tag, Editable output, XMLReader xmlReader)
方法來重新自定義標籤中的樣式,例如我在例子中自定義了一個hello的標籤,然後通過自定義的TagHandler把hello標籤替換成了一個字符串,其實我想到的可以通過自定義標籤和屬性來定義你的文字樣式,然後加到spanned中。
同時這個過濾不僅對不知道標籤過濾,已有的標籤依舊會走這個handler,所以可以對原有的一些樣式就行修飾。
源碼備忘:
<span style="white-space:pre"> </span>else if (mTagHandler != null) {
mTagHandler.handleTag(true, tag, mSpannableStringBuilder, mReader);
}
<span style="white-space:pre"> </span>else if (mTagHandler != null) {
mTagHandler.handleTag(false, tag, mSpannableStringBuilder, mReader);
}
其中兩段代碼分別是開始標籤和結束標籤傳回,可以看出handleTag(boolean opening, String tag, Editable output, XMLReader xmlReader) 的opening標識的是這個標籤是否爲開始標籤,然後tag是源碼幫忙過濾出的標籤。代碼實現:
MainActivity.java:
package com.code41.demo;
import org.xml.sax.XMLReader;
import android.app.Activity;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.text.Editable;
import android.text.Html;
import android.text.Html.ImageGetter;
import android.text.Html.TagHandler;
import android.text.Spanned;
import android.util.Log;
import android.widget.TextView;
public class MainActivity extends Activity {
private TextView demoTextView;// TextView for test string.xml
private TextView styleDemoTextView;// TextView for test string.xml
private TextView htmlTextView;// TextView for test string.xml
private Handler mHandler = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
demoTextView = (TextView) findViewById(R.id.text_view_string_demo);
styleDemoTextView = (TextView) findViewById(R.id.text_view_style_string_demo);
htmlTextView = (TextView) findViewById(R.id.text_view_html_demo);
// 大部分應用都是網絡請求應用,所以要養成異步賦值的好習慣
post(new Runnable() {
@Override
public void run() {
// 設置無樣式的字符串內容
String stringDemoValue = getString(R.string.code41_string_demo_value, "鮮花", 200);
demoTextView.setText(stringDemoValue);
// 設置HTML樣式的字符串內容
String styleStringDemoValue = getString(R.string.code41_style_string_demo_value, "鮮花", 200);
Spanned styleSpanned = Html.fromHtml(styleStringDemoValue);
Log.e("MainActivity", "content=>" + styleSpanned);
styleDemoTextView.setText(styleSpanned);
// 將spanned轉換String
String content = Html.toHtml(styleSpanned);
Log.e("MainActivity", "content=>" + content);
// log content=>content=><p
// dir="ltr">很高興可以收到你贈送的<b><font
// color ="#eb6067">鮮花</font></b>和<b><font
// color ="#eb6067">200</font></b>金幣。</p>
// 將圖片內容img帶入textView中
String htmlDemoString = getString(R.string.code41_html_string_demo_value, R.drawable.ic_launcher);
htmlTextView.setText(Html.fromHtml(htmlDemoString, imgGetter, tagHandler));
}
});
}
private void post(Runnable runnable) {
if (isFinishing() || null == mHandler) {
return;
}
mHandler.post(runnable);
}
/**
* 重寫圖片獲取的ImageGetter
*/
ImageGetter imgGetter = new Html.ImageGetter() {
public Drawable getDrawable(String source) {
int id = Integer.parseInt(source);
Drawable d = getResources().getDrawable(id);
d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());
return d;
}
};
/**
* 重寫未知標籤Handle
*/
TagHandler tagHandler = new TagHandler() {
@Override
public void handleTag(boolean opening, String tag, Editable output, XMLReader xmlReader) {
if ("hello".equals(tag) && opening) {
output.append("hello tag filter");
}
}
};
}
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#f8f8f8" >
<TextView
android:id="@+id/text_view_string_demo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textColor="#666666"
android:textSize="20sp" />
<TextView
android:id="@+id/text_view_style_string_demo"
android:layout_below="@+id/text_view_string_demo"
android:layout_marginTop="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#666666"
android:textSize="20sp" />
<TextView
android:id="@+id/text_view_html_demo"
android:layout_below="@+id/text_view_style_string_demo"
android:layout_marginTop="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#666666"
android:textSize="20sp" />
</RelativeLayout>
strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">StringDemo</string>
<string name="hello_world">Hello world!</string>
<string name="code41_string_demo_value">很高興可以收到你贈送的%1$s和%2$d金幣。</string>
<string name="code41_style_string_demo_value">很高興可以收到你贈送的<Data><![CDATA[<font color="#eb6067"><b>%1$s</b></font>和<font color="#eb6067"><b>%2$d</b></font>金幣]]></Data>。</string>
<string name="code41_html_string_demo_value">嵌入的圖片是<Data><![CDATA[<img src=\"%1$d\"/>和測試自定義的tag是<hello></hello>]]></Data></string>
</resources>
效果截圖: