-
Notifications
You must be signed in to change notification settings - Fork 939
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to display custom html instead of URL #23
Comments
not possible yet, but a hack would be to create a server with |
new WebviewScaffold(
url: new Uri.dataFromString('<html><body>hello world</body></html>', mimeType: 'text/html').toString() worked for me as well |
Loading data URIs seems quite limiting. Any plans to support https://developer.android.com/reference/android/webkit/WebView.html#loadDataWithBaseURL(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String) and the other similar methods? |
yes I planned to do it, I can't find time to work on the plugin at the moment and I also need to find an equivalent on iOS which is not my domain of expertise :/ |
I guess this is the equivalent function on iOS https://developer.apple.com/documentation/uikit/uiwebview/1617941-loaddata?language=objc |
I understand. I haven't done native mobile development and not the time to dive into it right now, |
To create a server easily you have an example in the readme of this repo |
Hello guys, |
@zoechi Your approach works!
Although it doesn't load any images from img=src from the network. Any ideas how to force load them? |
@AppleEducate Images work for me I added |
Thanks! |
@lejard-h , how to load images/data that are stored locally when launching a webview scaffold that as above? |
@MaskyS see the link in the 2nd comment |
@zoechi I think I'm probably missing something, but that link leads to android documentation? I checked the flutter_webview_plugin documentation and code but there seem to be no implementation of loadData() or loadDataWithBaseUrl() Could you help me understand with an example or clarification? |
@MaskyS the 2nd comment, not my 2nd comment |
@zoechi I had a look at that article; I tried it out and couldn't serve multiple files (I have html1.html, html2.html, etc along with their data folders.). Is it possible? am I missing something? |
@MaskyS just because it doesn't demonstrate how you can serve multiple files, doesn't mean it's not possible. Just serve different files based on the URL |
Thank you will try that. |
I would suggest on the iOS side to use Swift and not Objective C. Most new projects in iOS are written in Swift. Just my thoughts. |
got error java.lang.ClassCastException: android.webkit.WebView cannot be cast to com.flutter_webview_plugin.ObservableWebView for the following code
|
need optimized for the local html data string
|
Was working on this, it would be great if you guys tested it out. flutter/plugins#1137 |
@MaskyS: In my case, I was able to eliminate the error |
Having issue to display html string to normal string in flutter.. i was try all libs but not working suggest me new thank you...... |
ref: flutter/plugins#1247 |
Hi, I want to load the local Html file which is placed in my assets folder as "assets/file/privacy.html" this would be the path and I am using the same plugin and replacing the url as "assets/privacy.html" but still i am not able to view the html file content. Its showing the error as could not found the file. |
@neelu004: I saw that you use a subfolder (i.e. "assets/file/...") for your html file. The Flutter-webview plugin is very tedious if it comes to folder/subfolder/ locations. Try: 1. eliminate the subfolder and place it directly into "assets/privacy.html" instead. Or 2. make sure you also provide the subfolder in your URL when calling the webview. Also, if you have references to other html files or folders from within your html-file that the webview calls (normally index.html with references to other files and folders ... or in your case privacy.html), make sure you use a webserver together with the webview-plugin. Here is what works in my case: (Again: This server is only needed in the case you have references to files and folders from your root html you are trying to show in your webview). If you only show one single html-file (without references), then you don't need this Jaguar server... But if you do have a webpage with references to other files and folders (all in your assets), then your webview-URL must be called with The webserver I set up at the very beginning (inside main())... import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
// import 'dart:async';
import 'package:jaguar/jaguar.dart';
import 'package:jaguar_flutter_asset/jaguar_flutter_asset.dart';
void main() async {
final server = Jaguar();
server.addRoute(serveFlutterAssets());
await server.serve(logRequests: false);
// await server.serve(logRequests: true);
// server.log.onRecord.listen((r) => print(r));
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]).then((_) {
runApp(MyApp());
});
} If you want to navigate to your webview from somewhere: await navigateToWebView(context, 'file/privacy.html'); The navigation: Future<String> navigateToWebView(
BuildContext context, String pathName) async {
return await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => WebViewExample(pathName)));
} And here the webview implementation with the localhost-URL call: (small detail: the comments are an alternative if you don't want the snackbar) import 'package:flutter/material.dart';
import 'dart:async';
import 'package:webview_flutter/webview_flutter.dart';
// import 'package:flutter/services.dart';
class WebViewExample extends StatelessWidget {
final String pathName;
WebViewExample(this.pathName);
final Completer<WebViewController> _controller =
Completer<WebViewController>();
@override
Widget build(BuildContext context) {
final String serverURL = 'http://localhost:8080/' + this.pathName;
final double screenWidth = MediaQuery.of(context).size.shortestSide;
final double screenHeight = MediaQuery.of(context).size.longestSide;
return Scaffold(
appBar: MyAppBar(
title: Text(
'My Title',
style: TextStyle(
fontSize: 16.0, color: Colors.white, fontWeight: FontWeight.w500),
),
),
// body: FutureBuilder<String>(
// future: loadAsset(),
// builder: (context, snapshot) {
// if (snapshot.hasData) {
// return WebView(
// initialUrl:
// Uri.dataFromString(snapshot.data, mimeType: 'text/html')
// .toString(),
// javascriptMode: JavascriptMode.unrestricted,
// onWebViewCreated: (WebViewController webViewController) {
// _controller.complete(webViewController);
// },
// javascriptChannels: <JavascriptChannel>[
// _toasterJavascriptChannel(context),
// ].toSet(),
// );
// } else if (snapshot.hasError) {
// return Text("${snapshot.error}");
// }
// return CircularProgressIndicator();
// },
// ),
// We're using a Builder here so we have a context that is below the Scaffold
// to allow calling Scaffold.of(context) so we can show a snackbar.
body: Builder(builder: (BuildContext context) {
return Container(
color: Color.fromRGBO(
0x3c, 0x3c, 0x3c, 1), // color for bottom part of iOS safe-area
child: SafeArea(
child: Stack(
fit: StackFit.expand,
alignment: AlignmentDirectional.topStart,
children: <Widget>[
Positioned(
left: 0.0,
top: 0.0,
width: screenWidth,
height: screenHeight,
child: Container(
child: WebView(
initialUrl: serverURL,
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (WebViewController webViewController) {
_controller.complete(webViewController);
},
javascriptChannels: <JavascriptChannel>[
_toasterJavascriptChannel(context),
].toSet(),
),
),
),
],
),
),
);
}),
floatingActionButton: favoriteButton(),
);
}
// Future<String> loadAsset() async {
// return await rootBundle.loadString('assets/web1/index.html');
// }
JavascriptChannel _toasterJavascriptChannel(BuildContext context) {
return JavascriptChannel(
name: 'Toaster',
onMessageReceived: (JavascriptMessage message) {
Scaffold.of(context).showSnackBar(
SnackBar(content: Text(message.message)),
);
});
}
Widget favoriteButton() {
return FutureBuilder<WebViewController>(
future: _controller.future,
builder: (BuildContext context,
AsyncSnapshot<WebViewController> controller) {
if (controller.hasData) {
return FloatingActionButton(
onPressed: () async {
final String url = await controller.data.currentUrl();
Scaffold.of(context).showSnackBar(
SnackBar(content: Text('Favorited $url')),
);
},
child: const Icon(Icons.favorite),
);
}
return Container();
});
}
}
enum MenuOptions {
showUserAgent,
toast,
}
class SampleMenu extends StatelessWidget {
SampleMenu(this.controller);
final Future<WebViewController> controller;
@override
Widget build(BuildContext context) {
return FutureBuilder<WebViewController>(
future: controller,
builder:
(BuildContext context, AsyncSnapshot<WebViewController> controller) {
return PopupMenuButton<MenuOptions>(
onSelected: (MenuOptions value) {
switch (value) {
case MenuOptions.showUserAgent:
_onShowUserAgent(controller.data, context);
break;
case MenuOptions.toast:
Scaffold.of(context).showSnackBar(
SnackBar(
content: Text('You selected: $value'),
),
);
break;
}
},
itemBuilder: (BuildContext context) => <PopupMenuItem<MenuOptions>>[
PopupMenuItem<MenuOptions>(
value: MenuOptions.showUserAgent,
child: const Text('Show user agent'),
enabled: controller.hasData,
),
const PopupMenuItem<MenuOptions>(
value: MenuOptions.toast,
child: Text('Make a toast'),
),
],
);
},
);
}
void _onShowUserAgent(
WebViewController controller, BuildContext context) async {
// Send a message with the user agent string to the Toaster JavaScript channel we registered
// with the WebView.
controller.evaluateJavascript(
'Toaster.postMessage("User Agent: " + navigator.userAgent);');
}
}
class NavigationControls extends StatelessWidget {
const NavigationControls(this._webViewControllerFuture)
: assert(_webViewControllerFuture != null);
final Future<WebViewController> _webViewControllerFuture;
@override
Widget build(BuildContext context) {
return FutureBuilder<WebViewController>(
future: _webViewControllerFuture,
builder:
(BuildContext context, AsyncSnapshot<WebViewController> snapshot) {
final bool webViewReady =
snapshot.connectionState == ConnectionState.done;
final WebViewController controller = snapshot.data;
return Row(
children: <Widget>[
IconButton(
icon: const Icon(Icons.arrow_back_ios),
onPressed: !webViewReady
? null
: () async {
if (await controller.canGoBack()) {
controller.goBack();
} else {
Scaffold.of(context).showSnackBar(
const SnackBar(content: Text("No back history item")),
);
return;
}
},
),
IconButton(
icon: const Icon(Icons.arrow_forward_ios),
onPressed: !webViewReady
? null
: () async {
if (await controller.canGoForward()) {
controller.goForward();
} else {
Scaffold.of(context).showSnackBar(
const SnackBar(
content: Text("No forward history item")),
);
return;
}
},
),
IconButton(
icon: const Icon(Icons.replay),
onPressed: !webViewReady
? null
: () {
controller.reload();
},
),
],
);
},
);
}
}
class MyAppBar extends PreferredSize {
MyAppBar({Key key, Widget title})
: super(
key: key,
preferredSize: Size.fromHeight(app_bar_height), // set AppBar height
child: AppBar(
elevation: 0.0, // represents shaddow of AppBar
brightness: Brightness
.dark, // makes statusbar shine in dark AppBar environment
backgroundColor:
Color.fromRGBO(0x3c, 0x3c, 0x3c, 1), // sets AppBar color
title: title, // sets AppBar title
// maybe other AppBar properties
),
);
} |
You should change the plugin’s origin code, because the plugin didn’t use the correct API, you can’t load local html by LoadRequest but LoadFile API, have a try~
发自我的iPhone
…------------------ Original ------------------
From: neelu004 <[email protected]>
Date: Thu,Apr 18,2019 8:39 PM
To: fluttercommunity/flutter_webview_plugin <[email protected]>
Cc: vvlong <[email protected]>, Comment <[email protected]>
Subject: Re: [fluttercommunity/flutter_webview_plugin] How to display custom html instead of URL (#23)
Hi, I want to load the local Html file which is placed in my assets folder as "assets/file/privacy.html" this would be the path and I am using the same plugin and replacing the url as "assets/privacy.html" but still i am not able to view the html file content. Its showing the error as could not found the file.
Please suggest some solution.
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or mute the thread.
|
You can provide the complete example of localhost. Jaguar. thank. |
How to render image using HTML to create Flutter-iOS-App? |
I seem to be having trouble when the html is too large (maybe). It seems to only work half the time on iOS |
How to load custom font(ex: Baamini) in webviewScaffold..? |
this worked for me: #23 (comment) |
I want to display some custom html string instead of loading from a url. Is this possible today?
The text was updated successfully, but these errors were encountered: