Flutter 之新聞詳情頁(yè)一——加載本地動(dòng)態(tài)網(wǎng)頁(yè)

現(xiàn)在的新聞閱讀界面一般都包含兩部分,新聞文章內(nèi)容和用戶評(píng)論列表。內(nèi)容一般都是HTML富文本數(shù)據(jù),以便實(shí)現(xiàn)豐富的展示風(fēng)格。現(xiàn)在Flutter原生沒(méi)有支持的HTML富文本展示,也沒(méi)有提供類似的于WebView的Widget。只能使用插件方式調(diào)用原生的WebView。

詳情頁(yè)邏輯流程:

網(wǎng)絡(luò)請(qǐng)求新聞數(shù)據(jù)------組裝成標(biāo)準(zhǔn)的HTML(一般是靜態(tài)的)-------瀏覽器加載頁(yè)面

我網(wǎng)絡(luò)請(qǐng)求返回?cái)?shù)據(jù)組裝后的HTML純文本數(shù)據(jù)

<html>
  <head>
    <meta name="generator"
    content="HTML Tidy for HTML5 (experimental) for Windows https://github.com/w3c/tidy-html5/tree/c63cc39" />
    <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
    <link rel="stylesheet" type="text/css" href="main.css" />
    <title></title>
  </head>
  <body>
    <section data-role="outer" label="Powered by 135editor.com" style="font-size: 16px; font-family: 微軟雅黑;">
      <section data-role="outer" label="Powered by 135editor.com">
        <p style="margin-top: 5px; margin-bottom: 5px; line-height: 1.75em; font-family: Arial, sans-serif; text-indent: 0em; text-align: center;">

          <img imageflag=""
          src="https://cdnproduce.yunshicloud.com/wenshan/QMTNRK_YUNSHI/F41EF6C10FA3408DB377A13D5A01466F/5e7b22b63e73672e423375d50cb694a5.jpg"
          style="width: 100%;" />
        </p>
        <p style="margin-top: 5px; margin-bottom: 5px; line-height: 1.75em; font-family: Arial, sans-serif; text-align: justify; text-indent: 2em;">

          <span style="font-size: 17px;">連日來(lái),為維護(hù)消費(fèi)者合法權(quán)益,保護(hù)人民群眾豬肉食品安全,文山市市場(chǎng)監(jiān)督管理局組織執(zhí)法人員開(kāi)展轄區(qū)內(nèi)生豬肉市場(chǎng)、酒店餐桌專項(xiàng)檢查活動(dòng),保障轄區(qū)內(nèi)生豬肉市場(chǎng)的安全。</span>
        </p>
        <p style="margin-top: 5px; margin-bottom: 5px; line-height: 1.75em; font-family: Arial, sans-serif; text-indent: 0em; text-align: center;">

          <img alt="" height="1080" src="/sites/default/files/news/087659cfb4f94ee074a35c3bcdea9999.jpg" width="1440" />
        </p>
        <p style="margin-top: 5px; margin-bottom: 5px; line-height: 1.75em; font-family: Arial, sans-serif; text-align: justify; text-indent: 2em;">

          <span style="font-size: 17px;">此次檢查的重點(diǎn)是農(nóng)貿(mào)市場(chǎng)和各大酒店賓館,在詩(shī)達(dá)酒店,作為一家四星級(jí)酒店,餐桌食品安全備受關(guān)注,檢查人員先后檢查了該酒店的生產(chǎn)操作間、儲(chǔ)存?zhèn)}庫(kù)及各類食品進(jìn)貨臺(tái)賬,摸清了豬肉進(jìn)貨渠道和銷售數(shù)量,并結(jié)合《食品安全法》《生豬屠宰管理?xiàng)l例》等相關(guān)法律法規(guī),進(jìn)一步加強(qiáng)宣傳,引導(dǎo)廣大經(jīng)營(yíng)業(yè)者守法經(jīng)營(yíng)。督促其建立健全進(jìn)銷貨臺(tái)賬、進(jìn)貨檢驗(yàn)、索證索票、質(zhì)量承諾,落實(shí)豬肉來(lái)源溯源制度,保證豬肉合格,同時(shí)和酒店簽訂了文山市餐飲行業(yè)非洲豬瘟防控工作承諾書。</span>
        </p>
        <p style="margin-top: 5px; margin-bottom: 5px; line-height: 1.75em; font-family: Arial, sans-serif; text-indent: 0em; text-align: center;">
        </p>
        <p style="margin-top: 5px; margin-bottom: 5px; line-height: 1.75em; font-family: Arial, sans-serif; text-indent: 0em; text-align: center;">

          <span style="font-size: 17px;">
          <img imageflag=""
          src="https://cdnproduce.yunshicloud.com/wenshan/QMTNRK_YUNSHI/F41EF6C10FA3408DB377A13D5A01466F/92fe6ad88b8b78efc8af05fe1b4d48c1.jpg"
          style="width: 100%;" /> 
          <img imageflag=""
          src="https://cdnproduce.yunshicloud.com/wenshan/QMTNRK_YUNSHI/F41EF6C10FA3408DB377A13D5A01466F/3eca8da600b80b9b45db45e3d2c46146.jpg"
          style="text-indent: 0em; caret-color: red; width: 100%;" /> </span>
        </p>
        <section class="_135editor" data-id="88403" data-tools="135編輯器" style="border: 0px none; box-sizing: border-box;">
          <section>
            <section style="margin-top: 0.5em; margin-bottom: 0.5em; position: static;">
              <section style="border-top: 3px dashed rgb(147, 122, 122); box-sizing: border-box;"></section>
            </section>
            <section style="margin-top: 20px; margin-bottom: 20px; position: static;">
              <p style="margin-top: 5px; margin-bottom: 5px; font-size: 15px; line-height: 1.75em; font-family: Arial, sans-serif; color: rgb(120, 114, 114); text-align: justify; text-indent: 2em;">
              <strong>
                <span style="font-size: 17px;">文山詩(shī)達(dá)酒店 營(yíng)運(yùn)總監(jiān) 羅桂星:</span>
              </strong> 
              <span style="font-size: 17px;">“我們酒店食品安全這一塊也是經(jīng)常有計(jì)劃有步驟的進(jìn)行計(jì)劃性的培訓(xùn)。除此之外,我們餐飲部門之間也會(huì)經(jīng)常在班天會(huì)上進(jìn)行培訓(xùn),特別是對(duì)于我們產(chǎn)品的進(jìn)入,也是控制得很嚴(yán)。我們專門的采購(gòu)部門,對(duì)食品的采購(gòu)進(jìn)行整個(gè)流程的一個(gè)控制。從采買的索證索票以及到我們酒店大門的運(yùn)貨口,我們驗(yàn)收的每一個(gè)環(huán)節(jié),也是嚴(yán)控,還有我們的成品與半成品都會(huì)分開(kāi)管理和分開(kāi)儲(chǔ)存?!?lt;/span></p>
              <p style="margin-top: 5px; margin-bottom: 5px; font-size: 15px; line-height: 1.75em; font-family: Arial, sans-serif; color: rgb(120, 114, 114); text-indent: 0em; text-align: center;">

                <span style="font-size: 17px;">
                  <img imageflag=""
                  src="https://cdnproduce.yunshicloud.com/wenshan/QMTNRK_YUNSHI/F41EF6C10FA3408DB377A13D5A01466F/4fdd642bb1e1abc5dfdcb3b95ba54207.jpg"
                  style="width: 100%;" />
                </span>
              </p>
            </section>
            <section style="margin-top: 0.5em; margin-bottom: 0.5em; position: static;">
              <section style="border-top: 5px dashed rgb(147, 122, 122); box-sizing: border-box;"></section>
            </section>
          </section>
        </section>
        <p style="margin-top: 5px; margin-bottom: 5px; line-height: 1.75em; font-family: Arial, sans-serif; text-align: justify; text-indent: 2em;">
        </p>
        <section class="_135editor" data-id="89227" data-tools="135編輯器" style="border: 0px none; box-sizing: border-box;">
          <section data-width="100%"
          style="margin: 10px auto; width: 100%; background-color: rgb(251, 251, 251); border-bottom: 1px solid rgb(246, 246, 246); overflow: hidden; box-sizing: border-box;">

            <section style="display: inline-block; width: auto; background-color: rgb(255, 166, 0); border-radius: 0px 0px 10px; margin-right: 60px; margin-left: -30px; padding-left: 30px;transform: skew(-30deg);-webkit-transform: skew(-30deg);-moz-transform: skew(-30deg);-o-transform: skew(-30deg);">

              <section class="135brush" data-brushtype="text"
              style="padding: 8px 30px 8px 20px; color: rgb(255, 255, 255);transform: skew(30deg);-webkit-transform: skew(30deg);-moz-transform: skew(30deg);-o-transform: skew(30deg);">

                <strong>
                  <span style="font-size: 17px;">采訪中,酒店還承諾:</span>
                </strong>
              </section>
            </section>
          </section>
        </section>
        <section class="_135editor" data-id="91614" data-tools="135編輯器" style="border: 0px none; box-sizing: border-box;">
          <section class="_135editor" style="border: 0px none; box-sizing: border-box;">
            <section style="padding: 10px; box-sizing: border-box;">
              <section style="color: rgb(133, 133, 133); line-height: 30px; border: 2px solid rgb(136, 136, 136); box-sizing: border-box;">

                <section style="display: -webkit-flex; justify-content: center; align-items: center;">
                  <section class="135brush" data-brushtype="text" data-width="65%"
                  style="width: 65%; line-height: 30px; font-size: 22px; color: rgb(220, 54, 74); padding-left: 10px; box-sizing: border-box;">
                  </section>
                  <section data-width="35%" style="width: 35%;">
                    <section style="width: 115px; float: right; margin-right: -4px; margin-top: -23px;"></section>
                  </section>
                </section>
                <section class="135brush"
                style="padding-right: 15px; padding-bottom: 30px; padding-left: 15px; text-align: justify; box-sizing: border-box;">

                  <p style="margin-top: 5px; margin-bottom: 5px; line-height: 1.75em; font-family: Arial, sans-serif; text-indent: 2em;">

                    <span style="font-size: 17px;">一、嚴(yán)格按照云南省非洲豬瘟防控工作會(huì)議要求,不使用餐廚剩余物、廢棄物(潲水)飼喂生豬,不向生豬養(yǎng)豬場(chǎng)和養(yǎng)豬戶出售餐廚剩余物、廢棄物(潲水)。</span>
                  </p>
                  <p style="margin-top: 5px; margin-bottom: 5px; line-height: 1.75em; font-family: Arial, sans-serif; text-indent: 2em;">

                    <span style="font-size: 17px;">二、采購(gòu)豬肉向供貨方索取《生豬檢驗(yàn)檢疫合格證明》,堅(jiān)決不購(gòu)買未經(jīng)檢驗(yàn)檢疫的豬肉。</span>
                  </p>
                  <p style="margin-top: 5px; margin-bottom: 5px; line-height: 1.75em; font-family: Arial, sans-serif; text-indent: 2em;">

                    <span style="font-size: 17px;">三、保持食品加工、經(jīng)營(yíng)場(chǎng)所內(nèi)外的衛(wèi)生清潔,確保無(wú)衛(wèi)生死角,無(wú)蟑螂、老鼠、蒼蠅。</span>
                  </p>
                  <p style="margin-top: 5px; margin-bottom: 5px; line-height: 1.75em; font-family: Arial, sans-serif; text-indent: 2em;">

                    <span style="font-size: 17px;">四、認(rèn)真履行食品安全主任責(zé)任,嚴(yán)把食品安全質(zhì)量關(guān)。</span>
                  </p>
                </section>
                <section data-width="100%" style="width: 100%;">
                  <section style="width: 80px; height: 15px; float: right; border-bottom: 2px solid rgb(136, 136, 136); border-right: 2px solid rgb(136, 136, 136); margin-top: -19px; margin-right: 4px; box-sizing: border-box;">
                  </section>
                </section>
              </section>
            </section>
          </section>
        </section>
        <p style="margin-top: 5px; margin-bottom: 5px; line-height: 1.75em; font-family: Arial, sans-serif; text-align: justify; text-indent: 2em;">

          <span style="font-size: 17px;">在文山城區(qū)文新農(nóng)貿(mào)市場(chǎng),檢查人員詳細(xì)詢問(wèn)經(jīng)營(yíng)戶生豬肉來(lái)源,檢查是否具有相關(guān)對(duì)應(yīng)的票據(jù),所售豬肉是否經(jīng)過(guò)衛(wèi)生部門檢疫。嚴(yán)禁露天經(jīng)營(yíng),確保豬肉市場(chǎng)消費(fèi)安全。并要求經(jīng)營(yíng)者在銷售過(guò)程中做好防鼠防蠅措施,讓消費(fèi)者放心吃肉,吃到放心肉。</span>
        </p>
        <p style="margin-top: 5px; margin-bottom: 5px; line-height: 1.75em; font-family: Arial, sans-serif; text-indent: 0em; text-align: center;">

          <span style="font-size: 17px;">
            <img imageflag=""
            src="https://cdnproduce.yunshicloud.com/wenshan/QMTNRK_YUNSHI/F41EF6C10FA3408DB377A13D5A01466F/bd3b9a79d4cfb19cea065a0dd9ef5acf.jpg"
            style="width: 100%;" />
          </span>
        </p>
        <section class="_135editor" data-id="88403" data-tools="135編輯器" style="border: 0px none; box-sizing: border-box;">
          <section>
            <section style="margin-top: 0.5em; margin-bottom: 0.5em; position: static;">
              <section style="border-top: 3px dashed rgb(147, 122, 122); box-sizing: border-box;"></section>
            </section>
            <section style="margin-top: 20px; margin-bottom: 20px; position: static;">
              <p style="margin-top: 5px; margin-bottom: 5px; font-size: 15px; line-height: 1.75em; font-family: Arial, sans-serif; color: rgb(120, 114, 114); text-align: justify; text-indent: 2em;">
              <strong>
                <span style="font-size: 17px;">市民:</span>
              </strong> 
              <span style="font-size: 17px;">“我們買菜一般還是喜歡來(lái)市場(chǎng)買,都不喜歡在外面買,怕買到不好的?!?lt;/span></p>
              <p style="margin-top: 5px; margin-bottom: 5px; font-size: 15px; line-height: 1.75em; font-family: Arial, sans-serif; color: rgb(120, 114, 114); text-indent: 0em; text-align: center;">

                <span style="font-size: 17px;">
                  <img imageflag=""
                  src="https://cdnproduce.yunshicloud.com/wenshan/QMTNRK_YUNSHI/F41EF6C10FA3408DB377A13D5A01466F/cfb5635f567d5154324a55aa9a38d868.jpg"
                  style="width: 100%;" />
                </span>
              </p>
            </section>
            <section style="margin-top: 0.5em; margin-bottom: 0.5em; position: static;">
              <section style="border-top: 5px dashed rgb(147, 122, 122); box-sizing: border-box;"></section>
            </section>
          </section>
        </section>
        <p style="margin-top: 5px; margin-bottom: 5px; line-height: 1.75em; font-family: Arial, sans-serif; text-indent: 2em; text-align: justify;">

          <span style="font-size: 17px; text-indent: 2em; caret-color: red;">在檢查過(guò)程中,執(zhí)法人員不僅向生豬肉經(jīng)營(yíng)者、酒店管理者開(kāi)展了食品安全法律法規(guī)宣傳,引導(dǎo)經(jīng)營(yíng)者增強(qiáng)主體責(zé)任意識(shí),從自我做起。同時(shí)向周邊消費(fèi)者宣傳食品安全法,告知消費(fèi)者購(gòu)買生豬肉時(shí)要檢查豬肉是否蓋有防疫部門的檢疫章,出現(xiàn)問(wèn)題及時(shí)向食品藥品監(jiān)管部門反映,共同維護(hù)生豬肉消費(fèi)市場(chǎng),維護(hù)人民群眾舌尖上的安全。檢查當(dāng)天未發(fā)現(xiàn)不合格豬肉以及其他問(wèn)題。</span>
        </p>
        <p style="margin-top: 5px; margin-bottom: 5px; line-height: 1.75em; font-family: Arial, sans-serif; text-align: justify; text-indent: 2em;">
        </p>
        <p style="margin-top: 5px; margin-bottom: 5px; line-height: 1.75em; font-family: Arial, sans-serif; text-align: justify; text-indent: 2em;">

          <span style="font-size: 17px;">本臺(tái):周 秋 張 麟 實(shí)習(xí):楊仁潔</span>
        </p>
        <p style="margin-top: 5px; margin-bottom: 5px; line-height: 1.75em; font-family: Arial, sans-serif; text-align: justify; text-indent: 2em;">

          <span style="font-size: 17px;">編輯:張海藍(lán) 劉虹</span>
        </p>
        <p style="margin-top: 5px; margin-bottom: 5px; line-height: 1.75em; font-family: Arial, sans-serif; text-align: justify; text-indent: 2em;">

          <span style="font-size: 17px;">制作:馮明蘭 農(nóng)錦莊</span>
        </p>
        <p style="margin-top: 5px; margin-bottom: 5px; line-height: 1.75em; font-family: Arial, sans-serif; text-align: justify; text-indent: 2em;">

          <span style="font-size: 17px;">責(zé)任編輯:胡潤(rùn)</span>
        </p>
      </section>
    </section>
  </body>
</html>

詳情頁(yè)網(wǎng)頁(yè)加載:

  • 想法1:
    Dart可以開(kāi)發(fā)web開(kāi)發(fā),把組裝的靜態(tài)HTML標(biāo)簽轉(zhuǎn)換成Flutter的對(duì)應(yīng)的Widget(翻譯一遍)
    當(dāng)前也有一些現(xiàn)成的庫(kù):例如:flutter_html;flutter_widget_from_html_core
    我均嘗試使用了一番,發(fā)現(xiàn)對(duì)于style和背景較多的網(wǎng)頁(yè)不能美觀的展示。

優(yōu)點(diǎn)是全程可控,繞開(kāi)了WebView加載時(shí)的滑動(dòng)沖突,但缺點(diǎn)也十分明顯,工作量大(就像自己實(shí)現(xiàn)了一個(gè)瀏覽器,兼容性還十分不好的瀏覽器),展示的頁(yè)面效果沒(méi)有WebView效果好。

  • 想法2:使用瀏覽器加載,使用原生WebView加載網(wǎng)頁(yè)。現(xiàn)在也有較好的WebView插件。主要嘗試用了一下flutter_webview_plugin和flutter_inappbrowser;
    flutter_webview_plugin: 主要用來(lái)打開(kāi)網(wǎng)站,非常方便,但需要指定相對(duì)于屏幕的固定的顯示區(qū)域。Rect。而在開(kāi)發(fā)的時(shí)候往往不好計(jì)算得到十分精確的區(qū)域。
    flutter_inappbrowser:應(yīng)該算著flutter_webview_plugin的改進(jìn)版。 支持內(nèi)嵌入頁(yè)面。也需要固定的widget寬高。

由于客戶要求比較高,和大量的兼容性考慮,還是決定WebView加載網(wǎng)頁(yè)。當(dāng)前的WebView插件都是使用HTML的URL方式加載網(wǎng)頁(yè)。因此我們還需要把數(shù)據(jù)保存為文件,在使用WebView去加載本地網(wǎng)頁(yè)。

流程變更為:
網(wǎng)絡(luò)請(qǐng)求新聞數(shù)據(jù)------組裝成標(biāo)準(zhǔn)的HTML(一般是靜態(tài)的)------- 寫入本地設(shè)備html(包括通用的css 文件和 html文件)----- WebView加載html

文件讀寫

1.保存的文件的位置,使用path_provider插件,可以實(shí)現(xiàn)跨平臺(tái)文件路勁的獲取。

  Future<File> _getLocalCssFile() async {
// 獲取本地文檔目錄
    String dir = (await getApplicationDocumentsDirectory()).path;
// 返回本地文件目錄
    return new File('$dir/$fileCssName');
  }

  Future<File> _getLocalHtmlFile() async {
// 獲取本地文檔目錄
    String dir = (await getApplicationDocumentsDirectory()).path;
// 返回本地文件目錄
    return new File('$dir/$fileName');
  }

2.寫入文件
先寫入通用的CSS文件,通用的Css源文件使用assets方式存放。當(dāng)時(shí)苦于不知道flutter怎么獲取asset的URI地址。因此又使用IO操作重新另存一遍。
assets配置

  assets:
    - htmlsource/css/main.css

另存為代碼:(注意:這里進(jìn)行了防止重復(fù)IO操作代碼,但要注意排除修改css文件內(nèi)容情況,當(dāng)前沒(méi)有實(shí)現(xiàn)這個(gè)升級(jí)修改Css內(nèi)容的維護(hù))

void _checkCssFile() async {
    File file = await _getLocalCssFile();
    bool isExist = await file.exists();
    int fileLength = isExist ? await file.length() : -1;
    print('csss file length === $fileLength');
    if (!isExist || fileLength <= 0) {
      if (isExist) {
        await file.delete();
      }
      await file.create();
      String cssStr = await DefaultAssetBundle.of(context)
          .loadString('htmlsource/css/main.css');
      print('csss ==== $cssStr');
      await file.writeAsString(cssStr);
    }
  }

寫入Html文件:并使用URL更新WebView

void _writeDataFile(String data) async {
    _checkCssFile();
    File file = await _getLocalHtmlFile();
    File afterFile = await file.writeAsString(data);
    setState(() {
      _webUrl = afterFile.uri.toString();
    });
    print('weburl ==== $_webUrl');
  }

加載HTML完整代碼:

import 'dart:io';

import 'package:demonewsapp/page/native_web_view.dart';
import 'package:demonewsapp/page/webview.dart';
import 'package:flutter/material.dart';
import 'package:flutter_html/flutter_html.dart';
import 'package:html/dom.dart' as dom;
import 'package:html/parser.dart' as html;
import 'package:path_provider/path_provider.dart';

class NewsDetailsWeb extends StatefulWidget {
  String body;
  List<Widget> widgets;

  NewsDetailsWeb(
      {Key key, @required String this.body, List<Widget> this.widgets})
      : super(key: key);

  @override
  NewsDetailsWebState createState() {
    return NewsDetailsWebState();
  }
}

class NewsDetailsWebState extends State<NewsDetailsWeb> {
  final String fileName = 'wenshan_details.html';
  final String fileCssName = 'wenshan_details_css.css';
  String _webUrl = '';
  double top = 156.899;

  @override
  void initState() {
    super.initState();
    _createHtmlContent();
  }

  void _createHtmlContent() async {
    String cssUrl = (await _getLocalCssFile()).uri.toString();
    String cssHead =
        '''<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no"/>
    <link rel="stylesheet" type="text/css" href="${cssUrl}" />''';
    String newHtml = cssHead + widget.body;
    dom.Document doc = html.parse(newHtml);
    String htmlContent = doc.outerHtml;
    print('htmlContent === $htmlContent');
    _writeDataFile(htmlContent);
  }

  void _checkCssFile() async {
    File file = await _getLocalCssFile();
    bool isExist = await file.exists();
    int fileLength = isExist ? await file.length() : -1;
    print('csss file length === $fileLength');
    if (!isExist || fileLength <= 0) {
      if (isExist) {
        await file.delete();
      }
      await file.create();
      String cssStr = await DefaultAssetBundle.of(context)
          .loadString('htmlsource/css/main.css');
      print('csss ==== $cssStr');
      await file.writeAsString(cssStr);
    }
  }

  void _writeDataFile(String data) async {
    _checkCssFile();
    File file = await _getLocalHtmlFile();
    File afterFile = await file.writeAsString(data);
    setState(() {
      _webUrl = afterFile.uri.toString();
    });
    print('weburl ==== $_webUrl');
  }

  Future<File> _getLocalCssFile() async {
// 獲取本地文檔目錄
    String dir = (await getApplicationDocumentsDirectory()).path;
// 返回本地文件目錄
    return new File('$dir/$fileCssName');
  }

  Future<File> _getLocalHtmlFile() async {
// 獲取本地文檔目錄
    String dir = (await getApplicationDocumentsDirectory()).path;
// 返回本地文件目錄
    return new File('$dir/$fileName');
  }

  @override
  Widget build(BuildContext context) {
    return getNativeWeb();
  }

  Widget getNativeWeb() {
    return _webUrl.isNotEmpty
        ? NativeWebView(
            webUrl: _webUrl,
            webRect: Rect.fromLTWH(0.0, 0.0, MediaQuery.of(context).size.width,
                MediaQuery.of(context).size.height - AppBar().preferredSize.height
                    -MediaQuery.of(context).padding.top),
          )
        : new Container(
            height: 300.0,
            color: Colors.yellow,
          );
  }

  Widget getRectSizeWeb() {
    return _webUrl.isNotEmpty
        ? new WebViewWidget(
            url: _webUrl,
            webRect: Rect.fromLTWH(0.0, top, MediaQuery.of(context).size.width,
                MediaQuery.of(context).size.height - top),
            withZoom: false,
            withLocalStorage: true,
            scrollBar: false,
          )
        : new Container(
            height: 300.0,
            color: Colors.yellow,
          );
  }

  Widget getHtmlView() {
    return Container(
      child: Html(
        data: widget.body,
        padding: EdgeInsets.all(8.0),
      ),
    );
  }
}

InAppWebView 網(wǎng)頁(yè)加載的代碼:

import 'package:flutter/material.dart';
import 'package:flutter_inappbrowser/flutter_inappbrowser.dart';

class NativeWebView extends StatelessWidget {
  String webUrl;
  final Rect webRect;
  InAppWebViewController webView;

  NativeWebView({Key key, this.webUrl, this.webRect}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    InAppWebView webWidget = new InAppWebView(
        initialUrl: webUrl,
        initialHeaders: {},
        initialOptions: {},
        onWebViewCreated: (InAppWebViewController controller) {
          webView = controller;
        },
        onLoadStart: (InAppWebViewController controller, String url) {
          print("started -------------- $url");
          this.webUrl = url;
        },
        onProgressChanged: (InAppWebViewController controller, int progress) {
          double prog = progress / 100;
          print('prog --------- $prog');
        });

    return Container(
      width: webRect.width,
      height: webRect.height,
      child: webWidget,
    );
  }
}

效果:


example1.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1、通過(guò)CocoaPods安裝項(xiàng)目名稱項(xiàng)目信息 AFNetworking網(wǎng)絡(luò)請(qǐng)求組件 FMDB本地?cái)?shù)據(jù)庫(kù)組件 SD...
    陽(yáng)明AI閱讀 16,210評(píng)論 3 119
  • 此刻, 夜已深, 我的思念亦深。 托一顆星星, 我把思念帶給您, 我的父親! 天堂的日子 不再有病痛 不再受苦了吧...
    尚小小閱讀 427評(píng)論 3 3
  • switch語(yǔ)句 執(zhí)行到break就結(jié)束switch語(yǔ)句 執(zhí)行過(guò)程switch語(yǔ)句根據(jù)傳入的值進(jìn)行對(duì)比, 匹配ca...
    前端雨閱讀 1,123評(píng)論 0 0
  • 溫馨提示:閱讀此文大概需要6分鐘 原本計(jì)劃每閱讀完一本書就寫一篇讀后感分享出去,一方面擔(dān)心時(shí)間流逝,自己都不曾記得...
    刷新認(rèn)知閱讀 1,698評(píng)論 0 0
  • 此篇不易百金。人有一口,難勸其詞。俗言爛詞,指桑罵槐。俄而似柳眉之彎彎,轉(zhuǎn)念笑里藏刀輕悲嘆!啖骨嗜血何曾厭?萬(wàn)民之...
    身高一六八閱讀 315評(píng)論 0 2

友情鏈接更多精彩內(nèi)容