嗨,各位,今天來個小技巧,估計很多人都知道,我也就重複提下罷了。。
比如
我們看到,我用紅框框出來的地方 1.直接使用系統自帶的AlertDialog的提示框,我們看到了我們更新提示裡面的具體內容是(-Bug修改 -新增更新提示);並且換行了。
2.是自定義的彈框,(自定義彈框用的是我自己封裝的類:專案需求討論-Android 自定義Dialog實現步驟及封裝),我們看到裡面的內容會有各種排版,有些是黑色加粗,有些是換行。有些字型可能顏色不同突出明顯,等等需求。
歸結
歸結起來,我們不可能是好幾個TextView,然後去自己一個段落一個TextView去呈現,一般都是跟後臺約定好,讓他傳過來HTML格式的字串
所以1.裡面我們就是
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder.setMessage(Html.fromHtml(info.getChangeLog()));
複製程式碼
2.裡面我們是
TextView message = (TextView) view.findViewById(R.id.message);
if(!TextUtils.isEmpty(content)){
message.setText(Html.fromHtml(content));
}
複製程式碼
所以後臺傳過來的時候,就是可能是這種
{"content":"<strong><big>低**</big></strong>:本月銷售業績。<br/><br/><strong>諾**</strong>:本月銷售業"}
複製程式碼
然後我們就一個TextView就可以呈現不同的格式的內容。只要用Html.fromHtml(String);先轉一下,再賦給TextView即可。
老司機這就完了?????
答案當然是No。 你會發現Html.fromHtml(String message)這個方法畫了橫線,已經過時了。WHF。那應該用什麼。
@SuppressWarnings("deprecation")
public static Spanned fromHtml(String html){
Spanned result;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
result = Html.fromHtml(html,Html.FROM_HTML_MODE_LEGACY);
} else {
result = Html.fromHtml(html);
}
return result;
}
複製程式碼
我們在Android 6 及以下,還是使用Html.fromHtml(String);而在Android 7 及以上要用新的:Html.fromHtml(String , flags); 這個Config分為哪些呢:
官方連結走起:Html class documentation
flags有這些:
public static final int FROM_HTML_MODE_COMPACT = 63;
public static final int FROM_HTML_MODE_LEGACY = 0;
public static final int FROM_HTML_OPTION_USE_CSS_COLORS = 256;
public static final int FROM_HTML_SEPARATOR_LINE_BREAK_BLOCKQUOTE = 32;
public static final int FROM_HTML_SEPARATOR_LINE_BREAK_DIV = 16;
public static final int FROM_HTML_SEPARATOR_LINE_BREAK_HEADING = 2;
public static final int FROM_HTML_SEPARATOR_LINE_BREAK_LIST = 8;
public static final int FROM_HTML_SEPARATOR_LINE_BREAK_LIST_ITEM = 4;
public static final int FROM_HTML_SEPARATOR_LINE_BREAK_PARAGRAPH = 1;
public static final int TO_HTML_PARAGRAPH_LINES_CONSECUTIVE = 0;
public static final int TO_HTML_PARAGRAPH_LINES_INDIVIDUAL = 1;
複製程式碼
看了還是不懂,沒關係。效果圖放出來:
<p style="color: blue;">This is a paragraph with a style</p>
<h4>Heading H4</h4>
<ul>
<li style="color: yellow;">
<font color=\'#FF8000\'>li orange element</font>
</li>
<li>li #2 element</li>
</ul>
<blockquote>This is a blockquote</blockquote>
Text after blockquote
Text before div
<div>This is a div</div>
Text after div
複製程式碼
不同Config的情況下顯示的Html格式的文字呈現效果。
繼續放招
我們用如下程式碼:
String message = "<strong><big>低**</big></strong>:本月銷售業績。<br/><br/><strong>諾**</strong>:本月銷售業";
textView.setText(Html.fromHtml(message));
複製程式碼
OK,沒問題。我們知道會出來我們上面的自定義提示框的格式。 但是我們如果是
textView.setText(Html.fromHtml(message)+"");
複製程式碼
沒錯,我們把Html.fromHtml(message)
和字串拼接之後,再傳給TextView,那麼那些<strong>
,<big>
等標籤就無效了。<br/>
還是有效。
所以我們如果有需求要拼接字串,一定要先把要拼接的字串拼接完後,再用Html.fromHtml包裹,然後賦值給TextView。
有些人說我的字串不是在程式碼中,而是在strings.xml中定義,但是直接XML中的
<string>
標籤裡面定義很多其他標籤:<font>......
。在低版本的Android裝置可能會直接忽略這些標籤,這時候我們可以使用<![CDATA[]]>
,這個標記所包含的內容將表示為純文字。比如:<string name="xx"><![CDATA[ 沒顏色 <font color=#B0CB4A>有顏色的文字</font> <br/> 換一行顯示 <br/> 再換一行顯示]]></string>
老司機最後一招
大家都知道,Html格式中改變字型大小的是<font size = "20"></font>
但是你會發現:
String htmlText = "<font color=#000000 size=18px>"+productName+"</font> <br/><br/>"
+ "<font color=#ff6600 size=18px>積分:</font>"
+ "<font color=#ff6600 size=20px>+"+productPoint+"分</font>";
TextView tv = (TextView)findViewById(R.id.productNameAndPoint);
tv.setText(Html.fromHtml(htmlText));
複製程式碼
我們的顏色<font color = "#123456">
的設定是有效的,但是<font size = "20">
卻無效。
解決方法:
1.如果專案的字型大小要求不是很精緻,只是單純的為了標題突出等,可以用我們上面的<big>,<strong>,<small>
等
2.我們自定義標籤。思路是替換font標籤自己解析設定。用到的介面是Html類TagHandler介面:
public class DdbFontHandler implements TagHandler {
private int startIndex = 0;
private int stopIndex = 0;
@Override
public void handleTag(boolean opening, String tag, Editable output,
XMLReader xmlReader) {
processAttributes(xmlReader);
if(tag.equalsIgnoreCase("ddbfont")){
if(opening){
startFont(tag, output, xmlReader);
}else{
endFont(tag, output, xmlReader);
}
}
}
public void startFont(String tag, Editable output, XMLReader xmlReader) {
startIndex = output.length();
}
public void endFont(String tag, Editable output, XMLReader xmlReader){
stopIndex = output.length();
String color = attributes.get("color");
String size = attributes.get("size");
size = size.split("px")[0];
if(!TextUtils.isEmpty(color) && !TextUtils.isEmpty(size)){
output.setSpan(new ForegroundColorSpan(Color.parseColor(color)), startIndex, stopIndex, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
output.setSpan(new AbsoluteSizeSpan(Utils.dipToPx(GApp.instance(), Integer.parseInt(size))), startIndex, stopIndex, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}else{
output.setSpan(new ForegroundColorSpan(0xff2b2b2b), startIndex, stopIndex, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
final HashMap<String, String> attributes = new HashMap<String, String>();
private void processAttributes(final XMLReader xmlReader) {
try {
Field elementField = xmlReader.getClass().getDeclaredField("theNewElement");
elementField.setAccessible(true);
Object element = elementField.get(xmlReader);
Field attsField = element.getClass().getDeclaredField("theAtts");
attsField.setAccessible(true);
Object atts = attsField.get(element);
Field dataField = atts.getClass().getDeclaredField("data");
dataField.setAccessible(true);
String[] data = (String[])dataField.get(atts);
Field lengthField = atts.getClass().getDeclaredField("length");
lengthField.setAccessible(true);
int len = (Integer)lengthField.get(atts);
/**
* MSH: Look for supported attributes and add to hash map.
* This is as tight as things can get :)
* The data index is "just" where the keys and values are stored.
*/
for(int i = 0; i < len; i++)
attributes.put(data[i * 5 + 1], data[i * 5 + 4]);
}
catch (Exception e) {
}
}
}
複製程式碼
還有超連結等其他的HTML標籤的實現:
哪裡錯了希望大家用力噴我!!! O(∩_∩)O哈哈~