簡體   English   中英

Dart:將 html 文件加載到 Flutter Webview 中

[英]Dart: Load an html file into a Flutter Webview

Sthg 讓我發瘋,我嘗試使用帶有 dart:io 庫的 path_provider 插件在磁盤上寫一個 html 文件。

這是我嘗試過的( OKAY ):

Future<File> writeFile() async {
   final file = await _localFile;
   return file.writeAsString('<!DOCTYPE html><html lang="fr"> <head> <meta charset="UTF-8"> <title>test_design</title> ...');
 }

然后文件加載到 webview 中: OKAY

但是如果我嘗試使用更長的 html 文件,它就不再起作用了,例如:

return file.writeAsString(' html file containing js ');

任何的想法?

或者如何在 Flutter webview 中加載 html 文件(文件不是靜態的)?


我使用flutter_webview_plugin.dart

( https://pub.dartlang.org/packages/flutter_webview_plugin )

網絡視圖代碼:

         writeFile().then((file){
            readFile().then((r){
               _localPath.then((path){
                    var uri='file:///'+path+'/index.html';

                    flutterWebViewPlugin.launch(uri,
                        rect: new Rect.fromLTWH(
                          0.0,
                          400.0,
                          MediaQuery.of(context).size.width,
                          200.0,
                        ),
                      );

IMO,這是為此的方法:

這是一個示例方法,我將構建一個 Flutter 應用程序,它可以讀取文件並將數據寫入文件以供以后使用。

這是一個可以將字符串寫入text.txt文件的應用程序。 每次啟動應用程序時,它都會顯示text.txt的內容。

我需要一個地方來將數據寫入磁盤並在應用程序加載時再次讀取它。 所以我使用path_provider插件訪問 Documents 目錄(在 iOS 上,這對應於NSDocumentDirectory ,在 Android 上,這是AppData目錄)。

Future<String> get _localPath async {
  final directory = await getApplicationDocumentsDirectory();
  return directory.path;
}

創建對文件完整位置的引用(在我們的例子中是 text.txt 文件),我們使用dart:io庫中的File類。

Future<File> get _localFile async {
  final path = await _localPath;
  return File('$path/text.txt');
}

需要使用 File writeAsString()方法將字符串寫入文件。 一旦整個操作完成,它就會返回一個Future<File>並以此 File 對象完成。

默認情況下, writeAsString()創建文件並在文件已存在時將其截斷。

要將數據附加到現有文件,請將FileMode.append模式作為第二個參數傳遞。

Future<File> writeFile(String text) async {
  final file = await _localFile;
  return file.writeAsString('$text\r\n', mode: FileMode.append);
}

使用 File readAsString()方法將整個內容作為字符串讀取。 它返回一個Future<String> ,一旦內容被讀取,該字符串就完成了。

Future<String> readFile() async {
  try {
    final file = await _localFile;
 
    String content = await file.readAsString();
    return content;
  } catch (e) {
    return '';
  }
}

這是完整的示例代碼:

import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
import 'dart:async';
import 'dart:io';

void main() {
  runApp(
    MaterialApp(
      title: 'Read/Write Files',
      home: MyApp(storage: TextStorage()),
    ),
  );
}

class TextStorage {
  Future<String> get _localPath async {
    final directory = await getApplicationDocumentsDirectory();
    return directory.path;
  }

  Future<File> get _localFile async {
    final path = await _localPath;
    return File('$path/text.txt');
  }

  Future<String> readFile() async {
    try {
      final file = await _localFile;

      String content = await file.readAsString();
      return content;
    } catch (e) {
      return '';
    }
  }

  Future<File> writeFile(String text) async {
    final file = await _localFile;
    return file.writeAsString('$text\r\n', mode: FileMode.append);
  }

  Future<File> cleanFile() async {
    final file = await _localFile;
    return file.writeAsString('');
  }
}

class MyApp extends StatefulWidget {
  final TextStorage storage;

  MyApp({Key key, @required this.storage}) : super(key: key);

  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  TextEditingController _textField = new TextEditingController();

  String _content = '';

  @override
  void initState() {
    super.initState();
    widget.storage.readFile().then((String text) {
      setState(() {
        _content = text;
      });
    });
  }

  Future<File> _writeStringToTextFile(String text) async {
    setState(() {
      _content += text + '\r\n';
    });

    return widget.storage.writeFile(text);
  }

  Future<File> _clearContentsInTextFile() async {
    setState(() {
      _content = '';
    });

    return widget.storage.cleanFile();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Read/Write File Example'),
        backgroundColor: Colors.blue,
      ),
      body: Container(
        padding: EdgeInsets.all(20.0),
        child: Column(
          children: <Widget>[
            TextField(
              controller: _textField,
            ),
            Padding(
              padding: EdgeInsets.all(20.0),
              child: RaisedButton(
                child: Text('Write to File'),
                color: Colors.lightBlueAccent,
                onPressed: () {
                  if (_textField.text.isNotEmpty) {
                    _writeStringToTextFile(_textField.text);
                    _textField.clear();
                  }
                },
              ),
            ),
            Padding(
              padding: EdgeInsets.only(bottom: 20.0),
              child: RaisedButton(
                child: Text(
                  'Clear Contents',
                  style: TextStyle(color: Colors.white),
                ),
                color: Colors.grey,
                onPressed: () {
                  _clearContentsInTextFile();
                },
              ),
            ),
            Expanded(
              flex: 1,
              child: new SingleChildScrollView(
                child: Text(
                  '$_content',
                  style: TextStyle(
                    color: Colors.blue,
                    fontSize: 22.0,
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

下面是它運行時的樣子:

在此處輸入圖像描述

你可以根據你的要求來玩。

還有關於如何在 Flutter webview 中加載 html 文件的其他問題,這是我的方法:

您實際上可以使用webview_flutter插件使其工作。

在你的 Flutter 應用程序的根目錄中創建一個資產文件夾,然后將你的 .html 文件放在資產文件夾中。

您應該將 your.html 文件添加到pubspec.yaml文件中的assets下。

pubspec.yaml

  assets:
    - assets/SampleHtml.html

這是從本地文件加載 html 的示例實現:

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'dart:async';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  Future<String> localLoader() async {
    return await rootBundle.loadString('assets/SampleHtml.html');
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<String>(
        future: localLoader(),
        builder: (context, snapshot) {
          if (snapshot.hasData) {
            return WebView(
              initialUrl:
                  new Uri.dataFromString(snapshot.data, mimeType: 'text/html')
                      .toString(),
              javascriptMode: JavascriptMode.unrestricted,
            );
          } else if (snapshot.hasError) {
            return Text("${snapshot.error}");
          }
          return CircularProgressIndicator();
        });
  }
}

SampleHtml.html

 <.DOCTYPE html> <meta charset="utf-8"> <title>Sample HTML</title> <html> <head> <link rel="stylesheet"> </head> <body> <h1>Flutter Webview</h1> <p>A Flutter plugin that provides a WebView widget.</p> <ul> <li>List 1</li> <li>List 2</li> <li>List 3</li> </ul> </body> </html>

這是它的樣子:

在此處輸入圖像描述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM