項目需求討論: 文字顯示排版— Html格式

嗨,各位,今天來個小技巧,估計不少人都知道,我也就重複提下罷了。。html

好比 android

升級更新框
通知提示框

咱們看到,我用紅框框出來的地方 1.直接使用系統自帶的AlertDialog的提示框,咱們看到了咱們更新提示裏面的具體內容是(-Bug修改 -新增更新提示);而且換行了。bash

2.是自定義的彈框,(自定義彈框用的是我本身封裝的類:項目需求討論-Android 自定義Dialog實現步驟及封裝),咱們看到裏面的內容會有各類排版,有些是黑色加粗,有些是換行。有些字體可能顏色不一樣突出明顯,等等需求。ide

歸結

歸結起來,咱們不多是好幾個TextView,而後去本身一個段落一個TextView去呈現,通常都是跟後臺約定好,讓他傳過來HTML格式的字符串字體

因此1.裏面咱們就是ui

AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder.setMessage(Html.fromHtml(info.getChangeLog()));
複製代碼

2.裏面咱們是google

TextView message = (TextView) view.findViewById(R.id.message);
if(!TextUtils.isEmpty(content)){
    message.setText(Html.fromHtml(content));
}
複製代碼

因此後臺傳過來的時候,就是多是這種spa

{"content":"<strong><big>低**</big></strong>:本月銷售業績。<br/><br/><strong>諾**</strong>:本月銷售業"}
複製代碼

而後咱們就一個TextView就能夠呈現不一樣的格式的內容。只要用Html.fromHtml(String);先轉一下,再賦給TextView便可。.net


老司機這就完了?????

答案固然是No。 你會發現Html.fromHtml(String message)這個方法畫了橫線,已通過時了。WHF。那應該用什麼。3d

@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標籤的實現:

請參考:Html類TagHandler接口


哪裏錯了但願你們用力噴我!!! O(∩_∩)O哈哈~

相關文章
相關標籤/搜索