題記
—— 執劍天涯,從你的點滴積累開始,所及之處,必精益求精。
【x1】點擊查看提示javascript
【x2】各類系列的教程html
<p>一個程序員的修煉日記</p> </div> <p/> <hr/> <p>在實際業務開發中,時常會有這種一段Html格式的標籤,看下圖的狀況 :</p> <p><img src="https://img-blog.csdnimg.cn/20200919153356921.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3psMTg2MDM1NDM1NzI=,size_16,color_FFFFFF,t_70#pic_center" alt="在這裏插入圖片描述"/><br/> 在 Flutter 中,有點發愁,由於 Flutter 提供的 Text 與 RichText 還解析不了這種格式的,可是你也不能使用 WebView 插件,若是使用了,你會在每個Item中嵌入一個瀏覽器內核,再強的手機,也會卡,固然確定不能這樣作,由於這樣就是錯誤的作法。</p> <p>小編通過大量的嘗試與思考,終於寫出來了一個插件能夠來解析了,現分享給你們。</p> <h4><a id="1__18"/>1 基本使用實現</h4> <h5><a id="12__20"/>1.2 添加依賴</h5> <p>小編依舊,來個pub方式:<a href="https://pub.flutter-io.cn/packages/flutter_html_rich_text">【不用說 快捷入口在這】</a><a href="https://github.com/zhaolongs">【固然也有github】</a> <a href="https://www.toutiao.com/c/user/token/MS4wLjABAAAAYMrKikomuQJ4d-cPaeBqtAK2cQY697Pv9xIyyDhtwIM/">【誇張點還有 視頻支持】</a></p> <pre><code class="prism language-javascript">dependencies<span class="token punctuation">:</span> flutter_html_rich_text<span class="token punctuation">:</span> <span class="token operator">^</span><span class="token number">1.0</span><span class="token number">.0</span> </code></pre> <p><img src="https://img-blog.csdnimg.cn/2020091915403745.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3psMTg2MDM1NDM1NzI=,size_16,color_FFFFFF,t_70#pic_center" alt="在這裏插入圖片描述"/></p> <h5><a id="13__HTML__30"/>1.3 加載解析 HTML 片斷標籤</h5> <p>核心方法以下:</p> <pre><code class="prism language-javascript"><span class="token comment">///htmlText 就是你的 HTML 片斷了</span> <span class="token function">HtmlRichText</span><span class="token punctuation">(</span> htmlText<span class="token punctuation">:</span> txt<span class="token punctuation">,</span> <span class="token punctuation">)</span><span class="token punctuation">,</span> </code></pre> <p>以下代碼清單 1-3-1 就是上述圖中的效果:</p> <pre><code class="prism language-javascript"><span class="token comment">/// 代碼清單 1-3-1</span> <span class="token keyword">class</span> <span class="token class-name">TestHtmlPage</span> <span class="token keyword">extends</span> <span class="token class-name">StatefulWidget</span> <span class="token punctuation">{<!-- --></span> @override _TestPageState <span class="token function">createState</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">_TestPageState</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">class</span> <span class="token class-name">_TestPageState</span> <span class="token keyword">extends</span> <span class="token class-name">State</span><span class="token operator"><</span>TestHtmlPage<span class="token operator">></span> <span class="token punctuation">{<!-- --></span> String txt <span class="token operator">=</span> <span class="token string">"<p>長途輪 <h4>高速驅動</h4><span style='background-color:#ff3333'>"</span> <span class="token string">"<span style='color:#ffffff;padding:10px'> 3條立減 購胎抽獎</span></span></p>"</span> <span class="token string">"<p>長途高速驅動輪<span ><span style='color:#cc00ff;'> 3條立減 購胎抽獎</span></span></p>"</span><span class="token punctuation">;</span> @override Widget <span class="token function">build</span><span class="token punctuation">(</span>BuildContext context<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token keyword">return</span> <span class="token function">Scaffold</span><span class="token punctuation">(</span> <span class="token comment">///一個標題</span> appBar<span class="token punctuation">:</span> <span class="token function">AppBar</span><span class="token punctuation">(</span>title<span class="token punctuation">:</span> <span class="token function">Text</span><span class="token punctuation">(</span><span class="token string">'A頁面'</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token punctuation">)</span><span class="token punctuation">,</span> body<span class="token punctuation">:</span> <span class="token function">Center</span><span class="token punctuation">(</span> <span class="token comment">///一個列表</span> child<span class="token punctuation">:</span> ListView<span class="token punctuation">.</span><span class="token function">builder</span><span class="token punctuation">(</span> itemBuilder<span class="token punctuation">:</span> <span class="token punctuation">(</span>BuildContext context<span class="token punctuation">,</span> int postiont<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token keyword">return</span> <span class="token function">buildItemWidget</span><span class="token punctuation">(</span>postiont<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> itemCount<span class="token punctuation">:</span> <span class="token number">100</span><span class="token punctuation">,</span> <span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">///ListView的條目</span> Widget <span class="token function">buildItemWidget</span><span class="token punctuation">(</span>int postiont<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token keyword">return</span> <span class="token function">Container</span><span class="token punctuation">(</span> <span class="token comment">///內容邊距</span> padding<span class="token punctuation">:</span> EdgeInsets<span class="token punctuation">.</span><span class="token function">all</span><span class="token punctuation">(</span><span class="token number">8</span><span class="token punctuation">)</span><span class="token punctuation">,</span> child<span class="token punctuation">:</span> <span class="token function">Column</span><span class="token punctuation">(</span> <span class="token comment">///子Widget左對齊</span> crossAxisAlignment<span class="token punctuation">:</span> CrossAxisAlignment<span class="token punctuation">.</span>start<span class="token punctuation">,</span> <span class="token comment">///內容包裹</span> mainAxisSize<span class="token punctuation">:</span> MainAxisSize<span class="token punctuation">.</span>min<span class="token punctuation">,</span> children<span class="token punctuation">:</span> <span class="token punctuation">[</span> <span class="token function">Text</span><span class="token punctuation">(</span> <span class="token string">"測試標題 $postiont"</span><span class="token punctuation">,</span> style<span class="token punctuation">:</span> <span class="token function">TextStyle</span><span class="token punctuation">(</span>fontWeight<span class="token punctuation">:</span> FontWeight<span class="token punctuation">.</span>w500<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token comment">///html富文本標籤</span> <span class="token function">Container</span><span class="token punctuation">(</span> margin<span class="token punctuation">:</span> EdgeInsets<span class="token punctuation">.</span><span class="token function">only</span><span class="token punctuation">(</span>top<span class="token punctuation">:</span> <span class="token number">8</span><span class="token punctuation">)</span><span class="token punctuation">,</span> child<span class="token punctuation">:</span> <span class="token function">HtmlRichText</span><span class="token punctuation">(</span> htmlText<span class="token punctuation">:</span> txt<span class="token punctuation">,</span> <span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">)</span> <span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> </code></pre> <hr/> <p>如下是解析思考 燒腦的實踐</p> <hr/> <h4><a id="_107"/></h4> <h4><a id="2__109"/>2 燒腦思考實踐一</h4> <p>Flutter 應用程序被 Android iOS平臺加載,在原生 Android 中,使用TextView就可輕鬆實現解析(以下代碼清單2-1),固然在iOS中使用UILabel也可輕鬆實現(以下代碼清單2-2)。</p> <pre><code class="prism language-java"><span class="token comment">// Android 原生 TextView加載Html的核心方法</span> <span class="token comment">//代碼清單2-1</span> <span class="token comment">// MxgsaTagHandler 定義的一個 TagHandler 用來處理點擊事件</span> lTextView<span class="token punctuation">.</span><span class="token function">setText</span><span class="token punctuation">(</span>Html<span class="token punctuation">.</span><span class="token function">fromHtml</span><span class="token punctuation">(</span>myContent<span class="token punctuation">,</span> null<span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token class-name">MxgsaTagHandler</span><span class="token punctuation">(</span>context<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> lTextView<span class="token punctuation">.</span><span class="token function">setClickable</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span> lTextView<span class="token punctuation">.</span><span class="token function">setMovementMethod</span><span class="token punctuation">(</span>LinkMovementMethod<span class="token punctuation">.</span><span class="token function">getInstance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> </code></pre> <pre><code class="prism language-objectivec"><span class="token comment">// iOS 原生 UILabel加載Html的核心方法</span> <span class="token comment">//代碼清單2-2</span> <span class="token comment">//返回的HTML文本 如 <font color = 'red'></font></span> NSString <span class="token operator">*</span>str <span class="token operator">=</span> <span class="token string">@"htmlText"</span><span class="token punctuation">;</span> NSString <span class="token operator">*</span>HTMLString <span class="token operator">=</span> <span class="token punctuation">[</span>NSString stringWithFormat<span class="token punctuation">:</span><span class="token string">@"<html><body>%@</body></html>"</span><span class="token punctuation">,</span> str <span class="token punctuation">]</span><span class="token punctuation">;</span> NSDictionary <span class="token operator">*</span>options <span class="token operator">=</span> <span class="token operator">@</span><span class="token punctuation">{<!-- --></span>NSDocumentTypeDocumentAttribute <span class="token punctuation">:</span> NSHTMLTextDocumentType<span class="token punctuation">,</span> NSCharacterEncodingDocumentAttribute <span class="token punctuation">:</span> <span class="token operator">@</span><span class="token punctuation">(</span>NSUTF8StringEncoding<span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> NSData <span class="token operator">*</span>data <span class="token operator">=</span> <span class="token punctuation">[</span>HTMLString dataUsingEncoding<span class="token punctuation">:</span>NSUTF8StringEncoding<span class="token punctuation">]</span><span class="token punctuation">;</span> NSMutableAttributedString <span class="token operator">*</span> attributedString <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">[</span>NSMutableAttributedString alloc<span class="token punctuation">]</span> initWithData<span class="token punctuation">:</span>data options<span class="token punctuation">:</span>options documentAttributes<span class="token punctuation">:</span>nil error<span class="token punctuation">:</span>nil<span class="token punctuation">]</span><span class="token punctuation">;</span> NSMutableParagraphStyle <span class="token operator">*</span>paragraphStyle <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">[</span>NSMutableParagraphStyle alloc<span class="token punctuation">]</span> init<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// 調整行間距</span> paragraphStyle<span class="token punctuation">.</span>lineSpacing <span class="token operator">=</span> <span class="token number">8.0</span><span class="token punctuation">;</span> paragraphStyle<span class="token punctuation">.</span>alignment <span class="token operator">=</span> NSTextAlignmentJustified<span class="token punctuation">;</span> <span class="token punctuation">[</span>attributedString addAttribute<span class="token punctuation">:</span>NSParagraphStyleAttributeName value<span class="token punctuation">:</span>paragraphStyle range<span class="token punctuation">:</span><span class="token function">NSMakeRange</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> attributedString<span class="token punctuation">.</span>length<span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">[</span>attributedString addAttribute<span class="token punctuation">:</span>NSFontAttributeName value<span class="token punctuation">:</span><span class="token punctuation">[</span>UIFont systemFontOfSize<span class="token punctuation">:</span><span class="token number">15</span><span class="token punctuation">]</span> range<span class="token punctuation">:</span><span class="token function">NSMakeRange</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> attributedString<span class="token punctuation">.</span>length<span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">;</span> _uiLabel<span class="token punctuation">.</span>backgroundColor <span class="token operator">=</span> <span class="token punctuation">[</span>UIColor cyanColor<span class="token punctuation">]</span><span class="token punctuation">;</span> _uiLabel<span class="token punctuation">.</span>numberOfLines <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> _uiLabel<span class="token punctuation">.</span>attributedText <span class="token operator">=</span> attributedString<span class="token punctuation">;</span> <span class="token punctuation">[</span>_uiLabel sizeToFit<span class="token punctuation">]</span><span class="token punctuation">;</span> </code></pre> <p>而後對於 Flutter 來說是能夠順利的加載原生 View的 【<a href="https://blog.csdn.net/zl18603543572/article/details/95983215">在這有講述</a>】,以下代碼清單 2-3所示就是在Flutter中經過 AndroidView 與 UiKitView來實現。</p> <pre><code class="prism language-javascript"> <span class="token comment">//Flutter中加載原生View核心方法</span> <span class="token comment">//代碼清單2-3</span> <span class="token function">buildAndroidView</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token keyword">return</span> <span class="token function">AndroidView</span><span class="token punctuation">(</span> <span class="token comment">//設置標識</span> viewType<span class="token punctuation">:</span> <span class="token string">"com.studyon./text_html"</span><span class="token punctuation">,</span> <span class="token comment">//參數的編碼方式</span> creationParamsCodec<span class="token punctuation">:</span> <span class="token keyword">const</span> <span class="token function">StandardMessageCodec</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/// 經過 UiKitView 來加載 iOS原生View</span> <span class="token function">buildUIKitView</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token keyword">return</span> <span class="token function">UiKitView</span><span class="token punctuation">(</span> <span class="token comment">//標識</span> viewType<span class="token punctuation">:</span> <span class="token string">"com.studyon./text_html"</span><span class="token punctuation">,</span> <span class="token comment">//參數的編碼方式</span> creationParamsCodec<span class="token punctuation">:</span> <span class="token keyword">const</span> <span class="token function">StandardMessageCodec</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> </code></pre> <p>因而小編開發了第一波操做,開發了這樣的一個插件來調用原生 View 實現渲染富文本標籤<a href="https://github.com/zhaolongs/flutter_html_text_plugin">【源碼在這裏】</a>,這個插件使用方式很簡單,以下所示:</p> <pre><code class="prism language-javascript"><span class="token function">HTMLTextWidet</span><span class="token punctuation">(</span> htmlText<span class="token punctuation">:</span> <span class="token string">"測試一下"</span><span class="token punctuation">,</span> <span class="token punctuation">)</span> </code></pre> <p>這一步操做真是所謂的騷操做,其實小編在開發前就以爲不太合適,不過以小編的個性,非得嘗試驗證一下,現結果出來了,就是在加載時,因爲應用在列表中,使用 HTMLTextWidet 會有短暫的黑屏效果,並且內存出吃不消,以下圖所示:<br/> <img src="https://img-blog.csdnimg.cn/20200919161053269.gif#pic_center" alt="在這裏插入圖片描述"/><br/> 爲何會黑屏,閒魚技術團隊有過論述<a href="https://juejin.im/post/6844903714180841485">在Flutter中嵌入Native組件的正確姿式</a> 以及 文章 <a href="https://zhuanlan.zhihu.com/p/36577285">深刻了解Flutter界面開發中有詳細論述</a> 。</p> <p>因此結果是 :不可行。</p> <hr/> <h4><a id="3__192"/>3 燒腦思考實踐二</h4> <p>用 Java 的思想來解析 String 的方式來處理 HTML 字符串,處理成小片斷,而後使用Text結合 流式佈局 Wrap 來組合,核心代碼以下清單 3-1 所示爲解析:</p> <pre><code class="prism language-javascript"> <span class="token comment">/* 解析標籤 */</span> List<span class="token operator"><</span>TagColorModel<span class="token operator">></span> <span class="token function">findBackGroundColor</span><span class="token punctuation">(</span>String htmlStr<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> List<span class="token operator"><</span>TagColorModel<span class="token operator">></span> tagColorModelList <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> List<span class="token operator"><</span>String<span class="token operator">></span> colorSpiltList <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> String driverAdvertisement <span class="token operator">=</span> htmlStr<span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>driverAdvertisement <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> colorSpiltList <span class="token operator">=</span> driverAdvertisement<span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token string">"background-color"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> colorSpiltList<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> TagColorModel itemColorModel <span class="token operator">=</span> <span class="token function">TagColorModel</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> String colorsStr <span class="token operator">=</span> colorSpiltList<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">;</span> List<span class="token operator"><</span>String<span class="token operator">></span> itemSpiltList <span class="token operator">=</span> colorsStr<span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token string">":#"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> j <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> j <span class="token operator"><</span> itemSpiltList<span class="token punctuation">.</span>length<span class="token punctuation">;</span> <span class="token operator">++</span>j<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> String item <span class="token operator">=</span> itemSpiltList<span class="token punctuation">[</span>j<span class="token punctuation">]</span><span class="token punctuation">;</span> String itemColor <span class="token operator">=</span> <span class="token string">""</span><span class="token punctuation">;</span> String itemText <span class="token operator">=</span> <span class="token string">""</span><span class="token punctuation">;</span> <span class="token keyword">try</span> <span class="token punctuation">{<!-- --></span> <span class="token keyword">if</span> <span class="token punctuation">(</span>item<span class="token punctuation">.</span>length <span class="token operator">>=</span> <span class="token number">6</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> itemColor <span class="token operator">=</span> item<span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">substring</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>itemColor<span class="token punctuation">.</span><span class="token function">trim</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">toUpperCase</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token string">"FFFFFF"</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> itemColorModel<span class="token punctuation">.</span>backGroundColor <span class="token operator">=</span> ColorUtils<span class="token punctuation">.</span><span class="token function">getRandomColor</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{<!-- --></span> itemColorModel<span class="token punctuation">.</span>backGroundColor <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Color</span><span class="token punctuation">(</span> int<span class="token punctuation">.</span><span class="token function">parse</span><span class="token punctuation">(</span>itemColor<span class="token punctuation">.</span><span class="token function">trim</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> radix<span class="token punctuation">:</span> <span class="token number">16</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token number">0xFF000000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> int startIndex <span class="token operator">=</span> item<span class="token punctuation">.</span><span class="token function">indexOf</span><span class="token punctuation">(</span><span class="token string">"\">"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> int endIndex <span class="token operator">=</span> item<span class="token punctuation">.</span><span class="token function">indexOf</span><span class="token punctuation">(</span><span class="token string">"</"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>startIndex <span class="token operator">!=</span> <span class="token operator">-</span><span class="token number">1</span> <span class="token operator">&&</span> endIndex <span class="token operator">>=</span> startIndex<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> LogUtil<span class="token punctuation">.</span><span class="token function">e</span><span class="token punctuation">(</span><span class="token string">"startIndex $startIndex endIndex $endIndex "</span><span class="token punctuation">)</span><span class="token punctuation">;</span> itemText <span class="token operator">=</span> item<span class="token punctuation">.</span><span class="token function">substring</span><span class="token punctuation">(</span>startIndex <span class="token operator">+</span> <span class="token number">2</span><span class="token punctuation">,</span> endIndex<span class="token punctuation">)</span><span class="token punctuation">;</span> LogUtil<span class="token punctuation">.</span><span class="token function">e</span><span class="token punctuation">(</span><span class="token string">"itemColor $itemColor itemText $itemText "</span><span class="token punctuation">)</span><span class="token punctuation">;</span> itemColorModel<span class="token punctuation">.</span>text <span class="token operator">=</span> itemText<span class="token punctuation">;</span> tagColorModelList<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span>itemColorModel<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token class-name">e</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token comment">///解析異常的 沒必要處理</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> LogUtil<span class="token punctuation">.</span><span class="token function">e</span><span class="token punctuation">(</span><span class="token string">"${tagColorModelList.length} \n\n "</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> tagColorModelList<span class="token punctuation">;</span> <span class="token punctuation">}</span> </code></pre> <p>而後 TagColorModel 的定義以下代碼清單 3-2所示:</p> <pre><code class="prism language-javascript"><span class="token comment">///代碼清單 3-2 </span> <span class="token keyword">class</span> <span class="token class-name">TagColorModel</span> <span class="token punctuation">{<!-- --></span> <span class="token comment">///背景</span> Color backGroundColor<span class="token punctuation">;</span> <span class="token comment">///文本顏色</span> Color textColor<span class="token punctuation">;</span> <span class="token comment">///文本</span> String text<span class="token punctuation">;</span> <span class="token function">TagColorModel</span><span class="token punctuation">(</span> <span class="token punctuation">{<!-- --></span><span class="token keyword">this</span><span class="token punctuation">.</span>text <span class="token operator">=</span> <span class="token string">""</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>backGroundColor <span class="token operator">=</span> Colors<span class="token punctuation">.</span>transparent<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>textColor <span class="token operator">=</span> Colors<span class="token punctuation">.</span>white<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> </code></pre> <p>而後就是使用 Wrap 來使用解析的內容,以下代碼清單3-3所示:</p> <pre><code class="prism language-javascript"><span class="token comment">///代碼清單 3-3</span> <span class="token comment">///獲取背景顏色</span> List<span class="token operator"><</span>TagColorModel<span class="token operator">></span> colorList <span class="token operator">=</span> <span class="token function">findBackGroundColor</span><span class="token punctuation">(</span>htmlStr<span class="token punctuation">)</span><span class="token punctuation">;</span> List<span class="token operator"><</span>Widget<span class="token operator">></span> tagList <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> colorList<span class="token punctuation">.</span>length<span class="token punctuation">;</span> <span class="token operator">++</span>i<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> TagColorModel model <span class="token operator">=</span> colorList<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">;</span> tagList<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token function">Container</span><span class="token punctuation">(</span> margin<span class="token punctuation">:</span> EdgeInsets<span class="token punctuation">.</span><span class="token function">only</span><span class="token punctuation">(</span>right<span class="token punctuation">:</span> <span class="token number">2</span><span class="token punctuation">,</span> left<span class="token punctuation">:</span> <span class="token number">4</span><span class="token punctuation">,</span> top<span class="token punctuation">:</span> <span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">,</span> padding<span class="token punctuation">:</span> EdgeInsets<span class="token punctuation">.</span><span class="token function">only</span><span class="token punctuation">(</span>left<span class="token punctuation">:</span> <span class="token number">6</span><span class="token punctuation">,</span> right<span class="token punctuation">:</span> <span class="token number">6</span><span class="token punctuation">)</span><span class="token punctuation">,</span> decoration<span class="token punctuation">:</span> <span class="token function">BoxDecoration</span><span class="token punctuation">(</span> color<span class="token punctuation">:</span> model<span class="token punctuation">.</span>backGroundColor<span class="token punctuation">,</span> borderRadius<span class="token punctuation">:</span> BorderRadius<span class="token punctuation">.</span><span class="token function">all</span><span class="token punctuation">(</span>Radius<span class="token punctuation">.</span><span class="token function">circular</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">)</span><span class="token punctuation">,</span> child<span class="token punctuation">:</span> <span class="token function">Text</span><span class="token punctuation">(</span> <span class="token string">"${model.text}"</span><span class="token punctuation">,</span> style<span class="token punctuation">:</span> <span class="token function">TextStyle</span><span class="token punctuation">(</span>fontSize<span class="token punctuation">:</span> <span class="token number">12</span><span class="token punctuation">,</span> color<span class="token punctuation">:</span> model<span class="token punctuation">.</span>textColor<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">///而後再使用 Wrap 包裹</span> <span class="token function">Wrap</span><span class="token punctuation">(</span> alignment<span class="token punctuation">:</span> WrapAlignment<span class="token punctuation">.</span>spaceBetween<span class="token punctuation">,</span> children<span class="token punctuation">:</span> tagList<span class="token punctuation">,</span> <span class="token punctuation">)</span><span class="token punctuation">,</span> </code></pre> <p>實踐結果:可行,可是有兼容性差,效率低。</p> <p>固然閒魚團隊在文章 <a href="https://www.jianshu.com/p/4835ad8107d6">如何低成本實現Flutter富文本,看這一篇就夠了!</a> 中也有詳細論述。</p> <h4><a id="4__301"/>4 燒腦思考實踐三</h4> <p>當在Flutter中 Dart 從網站中提取數據時,html依賴庫是一個不錯的選擇,html 是一個開源的 Dart 包,主要用於從 HTML 中提取數據,從中獲取節點的屬性、文本和 HTML以及各類節點的內容。Html <a href="https://pub.flutter-io.cn/packages/html/install">pub倉庫</a></p> <pre><code class="prism language-javascript">dependencies<span class="token punctuation">:</span> html<span class="token punctuation">:</span> <span class="token operator">^</span><span class="token number">0.14</span><span class="token number">.0</span><span class="token operator">+</span><span class="token number">3</span> </code></pre> <p>因而乎小編也開始嘗試,首先是使用 Html 庫解析 HTML文本塊,將解析的 Document 經過遞歸方式遍歷出來全部的 node 節點,以下代碼清單4-1所示:</p> <pre><code class="prism language-javascript"><span class="token comment">代碼清單4-1</span> <span class="token keyword">import</span> <span class="token string">'package:html/parser.dart'</span> <span class="token keyword">as</span> parser<span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token string">'package:html/dom.dart'</span> <span class="token keyword">as</span> dom<span class="token punctuation">;</span> List<span class="token operator"><</span>Widget<span class="token operator">></span> <span class="token function">parse</span><span class="token punctuation">(</span>String originHtmlString<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token comment">// 空格替換 去除全部 br 標籤用 \n 代替,</span> originHtmlString <span class="token operator">=</span> originHtmlString<span class="token punctuation">.</span><span class="token function">replaceAll</span><span class="token punctuation">(</span><span class="token string">'<br/>'</span><span class="token punctuation">,</span> <span class="token string">'\n'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> originHtmlString <span class="token operator">=</span> originHtmlString<span class="token punctuation">.</span><span class="token function">replaceAll</span><span class="token punctuation">(</span><span class="token string">'<br>'</span><span class="token punctuation">,</span> <span class="token string">'\n'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> originHtmlString <span class="token operator">=</span> originHtmlString<span class="token punctuation">.</span><span class="token function">replaceAll</span><span class="token punctuation">(</span><span class="token string">'<br />'</span><span class="token punctuation">,</span> <span class="token string">'\n'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">///html 依賴庫解析</span> dom<span class="token punctuation">.</span>Document document <span class="token operator">=</span> parser<span class="token punctuation">.</span><span class="token function">parse</span><span class="token punctuation">(</span>originHtmlString<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">///獲取 DOM 中的 node 節點</span> dom<span class="token punctuation">.</span>Node cloneNode <span class="token operator">=</span> document<span class="token punctuation">.</span>body<span class="token punctuation">.</span><span class="token function">clone</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 注意: 先序遍歷找到全部關鍵節點(因爲是引用傳值,因此須要從新獲取一遍 hashCode)</span> List<span class="token operator"><</span>dom<span class="token punctuation">.</span>Node<span class="token operator">></span> keyNodeList <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">List</span><span class="token operator"><</span>dom<span class="token punctuation">.</span>Node<span class="token operator">></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> int nodeIndex <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token comment">///遞歸遍歷</span> <span class="token function">parseNodesTree</span><span class="token punctuation">(</span>cloneNode<span class="token punctuation">,</span> callBack<span class="token punctuation">:</span> <span class="token punctuation">(</span>dom<span class="token punctuation">.</span>Node childNode<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token keyword">if</span> <span class="token punctuation">(</span>childNode is dom<span class="token punctuation">.</span>Element <span class="token operator">&&</span> truncateTagList<span class="token punctuation">.</span><span class="token function">indexOf</span><span class="token punctuation">(</span>childNode<span class="token punctuation">.</span>localName<span class="token punctuation">)</span> <span class="token operator">!=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token function">print</span><span class="token punctuation">(</span><span class="token string">'TEST: truncate tag nodeIndex = ${nodeIndex++}'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> keyNodeList<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span>childNode<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 注意: 對於佔據整行的圖片也做爲關鍵節點處理</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>childNode is dom<span class="token punctuation">.</span>Element <span class="token operator">&&</span> childNode<span class="token punctuation">.</span>localName <span class="token operator">==</span> <span class="token string">'img'</span> <span class="token operator">&&</span> <span class="token function">checkImageNeedNewLine</span><span class="token punctuation">(</span>childNode<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token function">print</span><span class="token punctuation">(</span><span class="token string">'TEST: one line image nodeIndex = ${nodeIndex++}'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> keyNodeList<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span>childNode<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> </code></pre> <pre><code class="prism language-javascript"><span class="token comment">///遞歸遍歷</span> <span class="token keyword">void</span> <span class="token function">parseNodesTree</span><span class="token punctuation">(</span>dom<span class="token punctuation">.</span>Node node<span class="token punctuation">,</span> <span class="token punctuation">{<!-- --></span>NodeTreeCallBack callBack <span class="token operator">=</span> printNodeName<span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token comment">///遍歷 Node 節點</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> node<span class="token punctuation">.</span>nodes<span class="token punctuation">.</span>length<span class="token punctuation">;</span> <span class="token operator">++</span>i<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> dom<span class="token punctuation">.</span>Node item <span class="token operator">=</span> node<span class="token punctuation">.</span>nodes<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token function">callBack</span><span class="token punctuation">(</span>item<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">parseNodesTree</span><span class="token punctuation">(</span>item<span class="token punctuation">,</span> callBack<span class="token punctuation">:</span> callBack<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> </code></pre> <p>而後就是將 得出的 node 節點 與 Flutter 組件映射,文本使用 TextSpan ,圖片使用 Image ,而後將 樣式使用 TextStyle 映射,而後最後將解析的結果組件使用 Wrap 來包裹,就達到了如今的插件 <a href="https://pub.flutter-io.cn/packages/flutter_html_rich_text">flutter_html_rich_text</a></p> <p>綜合實現思路就是 使用 HTML 庫完善了【燒腦思考實踐二】中的解析。</p> <p>解析篇幅較長,你們有興趣能夠看下 github 源碼。</p> <hr/> <p>目前小編在西瓜視頻上免費刊登 Flutter 系列教程,每日更新,歡迎關注接收提醒<a href="https://www.ixigua.com/6872871296074514947">點擊查看提示</a> <a href="https://www.ixigua.com/home/3662978423/pseries/?preActiveKey=home">各類系列的教程</a></p> <p>2020.09.12 開發筆記</p> <ul><li><a href="https://blog.csdn.net/zl18603543572/article/details/108542749">iOS中加載Flutter中的圖片</a></li><li><a href="https://www.ixigua.com/6873625398358475272?id=6873233700075766286&logTag=V7knHiGBc_rkicdDQ91oJ">Flutter組件精講【01】 MateriaApp使用概述</a></li><li><a href="https://www.ixigua.com/6873625398358475272?id=6873235818551443971&logTag=fkCe_gTywndHcFSgBq1DY">Flutter組件精講【02】MaterialApp組件的基本使用</a></li><li><a href="https://www.ixigua.com/6873625398358475272?id=6873237305050530312&logTag=YqB9GQOPvB-Za9tNAv3ov">Flutter組件精講【03】 MateriaApp組件路由routes配製</a></li><li><a href="https://www.ixigua.com/6873625398358475272?id=6873240371485213195&logTag=NcL3TWBQ0JZRvo_NCAzPJ">Flutter組件精講【04】 MateriaApp配置默認啓動頁面</a></li><li><a href="https://www.ixigua.com/6873625398358475272">Flutter組件精講【05】 MateriaApp之頁面的跳轉</a></li><li><a href="https://www.ixigua.com/6873625398358475272">Flutter組件精講【06】MaterialApp 組件配置 404 頁面-01</a></li><li><a href="https://www.ixigua.com/6873625398358475272">Flutter組件精講【07】MaterialApp 組件配置 404 頁面-02</a></li></ul>
本文同步分享在 博客「早起的年輕人」(CSDN)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。java