欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

flutter實(shí)現(xiàn)頁(yè)面多個(gè)webview的方案詳解

 更新時(shí)間:2023年09月08日 16:28:38   作者:booboom  
這篇文章主要為大家詳細(xì)介紹了flutter如何實(shí)現(xiàn)頁(yè)面多個(gè)webview的效果,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起了解下

場(chǎng)景

當(dāng)我們計(jì)劃使用flutter開(kāi)發(fā)app時(shí),遇到一個(gè)頁(yè)面有多個(gè)由富文本編輯器編輯的html內(nèi)容場(chǎng)景,而且內(nèi)容很長(zhǎng)很大,但是都是一些圖文展示的內(nèi)容。

  • 使用和小程序中一樣的方案對(duì)html字符串進(jìn)行轉(zhuǎn)換,所以使用了flutter_html這個(gè)庫(kù),但是結(jié)果是卡異常的卡頓,而且樣式無(wú)法統(tǒng)一。
  • 結(jié)合服務(wù)端將html字符串生成一個(gè)個(gè)單獨(dú)的靜態(tài)網(wǎng)頁(yè),如https://www.testhtml.com/qweasdgtrtyytu.html,文件名隨機(jī)。利用官方庫(kù)webview_flutter進(jìn)行渲染,因?yàn)槭切枰暾故卷?yè)面內(nèi)容所以需要?jiǎng)討B(tài)獲取網(wǎng)頁(yè)高度并設(shè)置flutter組件的高度(下面具體講解),實(shí)現(xiàn)之后當(dāng)頁(yè)面webview太長(zhǎng)時(shí)安卓閃退,由于不太懂安卓webview的機(jī)制,所以無(wú)法解決。
  • 使用三方webview庫(kù)flutter_inappwebview完美解決了以上2個(gè)方法無(wú)法解決的問(wèn)題,樣式統(tǒng)一,可設(shè)置高度,以下我們具體聊聊如何實(shí)現(xiàn)。

引入庫(kù),版本6.0

import 'package:flutter_inappwebview/flutter_inappwebview.dart';

定義一個(gè)Model用來(lái)存放webview的相關(guān)信息

class WebViewModel {
  String title;
  double height;
  double width;
  HeadlessInAppWebView? headlessWebView;
  int progress;
  String url;
  bool convertFlag;
  WebViewModel({
    required this.title,
    this.width = 0,
    this.height = 0,
    this.headlessWebView,
    this.progress = 0,
    this.url = '',
    this.convertFlag = false,
  });
}

初始化相關(guān)屬性

final List<WebViewModel> webviewList = [
    WebViewModel(title: '頁(yè)面一', height: 0, width: 0, url: '', progress: 0, headlessWebView: null),
    WebViewModel(title: '頁(yè)面二', height: 0, width: 0, url: '', progress: 0, headlessWebView: null),
    WebViewModel(title: '頁(yè)面三', height: 0, width: 0, url: '', progress: 0, headlessWebView: null),
  ];
// 加載多個(gè)webview
for (var item in webviewList) {
  HeadlessInAppWebView? headlessWebView = item.headlessWebView;
  if (headlessWebView != null && !headlessWebView.isRunning()) {
    headlessWebView.run();
  }
}
// ....
initWebview(WebUri("https://cdn.testhtml.com/test/html/20230801/4b6e0db8-0c4f-4a85-a664-997a4e3ed288.html"), 0);
initWebview(WebUri("https://cdn.testhtml.com/test/html/20230802/ddbc1705-ca01-454c-97b6-b20a9c16e30d.html"), 1);
initWebview(WebUri("https://cdn.testhtml.com/test/html/20230802/c60c5bf5-2e14-4a16-b572-d2bb2e7efaaf.html"), 2);

initWebview實(shí)現(xiàn)

在實(shí)現(xiàn)之前我們也使用常規(guī)方案進(jìn)行加載webview,但是同時(shí)加載多個(gè)時(shí)還是卡頓,無(wú)法達(dá)到原生的流暢效果,仔細(xì)閱讀文檔后發(fā)現(xiàn)inappwebview6.0有一個(gè)將無(wú)頭瀏覽器模式轉(zhuǎn)換為flutter widget的功能,所以使用無(wú)頭模式優(yōu)先加載之后在渲染到頁(yè)面中,此時(shí)發(fā)現(xiàn)流暢了很多。

initWebview(WebUri url, int index) {
    webviewList[index].headlessWebView = HeadlessInAppWebView(
      initialUrlRequest: URLRequest(url: url),
      initialSettings: InAppWebViewSettings(
        verticalScrollBarEnabled: false,
      ),
      onProgressChanged: (controller, progress) async {
        // 獲取加載進(jìn)度
        setState(() {
          webviewList[index].progress = progress;
        });
      },
      onLoadStop: (controller, url) async {
        // 當(dāng)加載結(jié)束后進(jìn)行頁(yè)面樣式的調(diào)整
        // 執(zhí)行一段js,也可以使用字符串的方式,但是作為前端還是js文件更加親切 = =!!
        // detail_html.js中的內(nèi)容其實(shí)就是控制頁(yè)面縮放比例之類,也可以直接在生成html時(shí)帶上,這里只做參考
        await controller.injectJavascriptFileFromAsset(assetFilePath: "assets/js/detail_html.js");
        // 獲取網(wǎng)頁(yè)的寬高并通知flutter
        var bodyWidth = await controller.evaluateJavascript(source: "document.body.offsetWidth");
        var bodyHeight = await controller.evaluateJavascript(source: "document.body.offsetHeight");
        double domWidth = bodyWidth.runtimeType == double ? bodyWidth : (bodyWidth as int).toDouble();
        double domHeight = bodyHeight.runtimeType == double ? bodyHeight : (bodyHeight as int).toDouble();
        webviewList[index].width = domWidth;
        webviewList[index].height = domHeight;
        webviewList[index].convertFlag = true;
        print('=======$bodyWidth=======$bodyHeight======');
        setState(() {});
      },
    );
  }

detail_html.js內(nèi)容如下:

const head = document.querySelector('head')
const meta = document.createElement('meta')
const body = document.querySelector('body')
meta.setAttribute('name', 'viewport')
meta.setAttribute('content', 'width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, viewport-fit=cover')
head.appendChild(meta)
const style = document.createElement('style')
style.innerHTML = `
  * {margin: 0; padding: 0;}
  html {width: 100%; overflow-x: hidden;}
  body {display: inline-block; width: 100%; padding: 5px; box-sizing: border-box; }
  img {max-width: 100%; height: auto;}
`
head.appendChild(style)

將加載好的webview轉(zhuǎn)化為widget 此時(shí)準(zhǔn)備工作已經(jīng)完成:

  • 組件的寬高
  • webview加載完成

convertFlag: 用來(lái)控制webview加載狀態(tài),加載時(shí)顯示loading

@override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text(
          "HeadlessInAppWebView to InAppWebView",
          textScaleFactor: .8,
        ),
      ),
      body: SingleChildScrollView(
        child: Column(
          children: webviewList.map((item) {
            return item.convertFlag
                ? Container(
                    padding: const EdgeInsets.all(12),
                    margin: const EdgeInsets.all(12),
                    height: item.height,
                    child: InAppWebView(
                      headlessWebView: item.headlessWebView, // 關(guān)鍵
                      onWebViewCreated: (controller) async {
                        item.headlessWebView = null;
                      },
                    ),
                  )
                : SizedBox(
                    width: 40,
                    height: 40,
                    child: Center(
                      child: CircularProgressIndicator(
                        value: (item.progress / 100).toDouble(),
                      ),
                    ),
                  );
          }).toList(),
        ),
      ),
    );

還可以進(jìn)一步優(yōu)化,判斷路由動(dòng)畫(huà)結(jié)束后再加載,這里就不詳細(xì)描述了。

由于是測(cè)試代碼,還有很多優(yōu)化的地方,這里主要提供了一種多webview加載的優(yōu)化方案。

到此這篇關(guān)于flutter實(shí)現(xiàn)頁(yè)面多個(gè)webview的方案詳解的文章就介紹到這了,更多相關(guān)flutter webview內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Android開(kāi)發(fā)中Looper.prepare()和Looper.loop()

    Android開(kāi)發(fā)中Looper.prepare()和Looper.loop()

    Looper用于封裝了android線程中的消息循環(huán),默認(rèn)情況下一個(gè)線程是不存在消息循環(huán)(message loop)的,具體調(diào)用方法大家可以通過(guò)本文學(xué)習(xí)
    2016-11-11
  • Android實(shí)現(xiàn)背景顏色滑動(dòng)漸變效果的全過(guò)程

    Android實(shí)現(xiàn)背景顏色滑動(dòng)漸變效果的全過(guò)程

    在Android開(kāi)發(fā)中,經(jīng)常需要設(shè)置控件的背景顏色或者圖片的src顏色,下面這篇文章主要給大家介紹了關(guān)于Android實(shí)現(xiàn)背景顏色滑動(dòng)漸變效果的相關(guān)資料,本文通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2021-09-09
  • android項(xiàng)目從Eclipse遷移到Android studio中常見(jiàn)問(wèn)題解決方法

    android項(xiàng)目從Eclipse遷移到Android studio中常見(jiàn)問(wèn)題解決方法

    android項(xiàng)目從Eclipse遷移到Android studio中經(jīng)常會(huì)遇到一些問(wèn)題,本文提供了Android studio使用中常見(jiàn)問(wèn)題解決方法
    2018-03-03
  • Android高仿微信表情輸入與鍵盤(pán)輸入詳解

    Android高仿微信表情輸入與鍵盤(pán)輸入詳解

    本文主要介紹 Android高仿微信表情輸入與鍵盤(pán),這里提供了詳細(xì)的相關(guān)資料及實(shí)現(xiàn)示例代碼,有興趣的小伙伴可以參考下
    2016-08-08
  • Android實(shí)現(xiàn)注冊(cè)界面

    Android實(shí)現(xiàn)注冊(cè)界面

    這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)注冊(cè)界面,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • Android實(shí)現(xiàn)EditText圖文混合插入上傳功能

    Android實(shí)現(xiàn)EditText圖文混合插入上傳功能

    這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)EditText圖文混合插入上傳功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-08-08
  • Android OpenGL ES實(shí)現(xiàn)簡(jiǎn)單綠幕摳圖

    Android OpenGL ES實(shí)現(xiàn)簡(jiǎn)單綠幕摳圖

    這篇文章主要為大家介紹了Android OpenGL ES實(shí)現(xiàn)簡(jiǎn)單綠幕摳圖示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • Flutter進(jìn)階之實(shí)現(xiàn)動(dòng)畫(huà)效果(一)

    Flutter進(jìn)階之實(shí)現(xiàn)動(dòng)畫(huà)效果(一)

    這篇文章主要為大家詳細(xì)介紹了Flutter實(shí)現(xiàn)動(dòng)畫(huà)效果的第一篇,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-08-08
  • Android實(shí)現(xiàn)Tab切換界面功能詳解

    Android實(shí)現(xiàn)Tab切換界面功能詳解

    這篇文章主要為大家詳細(xì)介紹了Android如何實(shí)現(xiàn)Tab切換界面的功能,以及對(duì)Tab變化事件進(jìn)行監(jiān)聽(tīng)。文中示例代碼講解詳細(xì),感興趣的可以了解一下
    2022-05-05
  • Android ANR原理分析

    Android ANR原理分析

    ANR即Application Not Responding,顧名思義就是應(yīng)用程序無(wú)響應(yīng)。在Android中,一般情況下,四大組件均是工作在主線程中的,Android會(huì)隨時(shí)監(jiān)控應(yīng)用程序的響應(yīng)情況,如果因?yàn)橐恍┖臅r(shí)操作,那么系統(tǒng)就會(huì)顯示ANR對(duì)話框提示用戶對(duì)應(yīng)的應(yīng)用處于無(wú)響應(yīng)狀態(tài)
    2021-06-06

最新評(píng)論