I use webview_flutter package to create WebView app. Here is my example code:
import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:webview_flutter/webview_flutter.dart';
const purple = 0xFF95377E;
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
]);
return MaterialApp(
title: 'CustomApp',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primaryColor: Color(purple),
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: CustomApp(),
);
}
}
class CustomApp extends StatefulWidget {
@override
_CustomAppState createState() => _CustomAppState();
}
class _CustomAppState extends State<CustomApp> {
WebViewController _controller;
bool isLoading = true;
void initState() {
super.initState();
if (Platform.isAndroid) WebView.platform = SurfaceAndroidWebView();
}
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
print("Clicked!");
if (_controller != null) {
print(_controller.currentUrl());
}
},
child: Scaffold(
backgroundColor: Color(purple),
body: SafeArea(
child: Stack(
children: [
WebView(
initialUrl: 'https://example.com',
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (WebViewController webViewController) {
_controller = webViewController;
},
onPageFinished: (finish) {
setState(() {
isLoading = false;
});
},
onWebResourceError: (error) {
Loading();
},
),
isLoading ? Loading() : Stack(),
],
),
),
),
);
}
}
class Loading extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
fit: StackFit.expand,
children: <Widget>[
Container(
decoration: BoxDecoration(color: Color(purple)),
),
Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Expanded(
flex: 2,
child: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Image.asset(
'assets/images/bg.png',
fit: BoxFit.contain,
height: 70.0,
),
],
),
),
),
Expanded(
flex: 1,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(Colors.white),
),
Padding(
padding: EdgeInsets.only(top: 20.0),
),
Text(
"Загружается...",
softWrap: true,
textAlign: TextAlign.center,
style: TextStyle(fontSize: 18.0, color: Colors.white),
)
],
),
)
],
)
],
),
);
}
}
I need to add RefreshIndicator to my webview application. I tried like this but it's doesn't work:
import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:webview_flutter/webview_flutter.dart';
const purple = 0xFF95377E;
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
]);
return MaterialApp(
title: 'CustomApp',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primaryColor: Color(purple),
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: CustomApp(),
);
}
}
class CustomApp extends StatefulWidget {
@override
_CustomAppState createState() => _CustomAppState();
}
class _CustomAppState extends State<CustomApp> {
WebViewController _controller;
bool isLoading = true;
Completer controller;
StreamController streamController;
double webViewHeight = 100;
void initState() {
super.initState();
streamController.stream.listen((value) {
print(value);
setState(() {
webViewHeight = value;
});
});
if (Platform.isAndroid) WebView.platform = SurfaceAndroidWebView();
}
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
print("Clicked!");
if (_controller != null) {
print(_controller.currentUrl());
}
},
child: Scaffold(
backgroundColor: Color(purple),
body: RefreshIndicator(
onRefresh: () => controller.future.then((webViewController) {
webViewController.reload();
}),
child: ListView.builder(
itemCount: 1,
itemBuilder: (BuildContext context, int index) {
return ListTile(
title: Container(
height: webViewHeight,
child: SafeArea(
child: Stack(
children: [
WebView(
initialUrl: 'https://example.com',
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated:
(WebViewController webViewController) {
_controller = webViewController;
controller.complete(webViewController);
},
onPageFinished: (finish) {
double height;
controller.future.then((value) {
value
.evaluateJavascript(
"document.documentElement.scrollHeight;")
.then((String valueHeight) {
height = double.parse(valueHeight);
streamController.add(height);
});
});
setState(() {
isLoading = false;
});
},
onWebResourceError: (error) {
Loading();
},
),
isLoading ? Loading() : Stack(),
],
),
),
));
},
),
),
),
);
}
}
class Loading extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
fit: StackFit.expand,
children: <Widget>[
Container(
decoration: BoxDecoration(color: Color(purple)),
),
Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Expanded(
flex: 2,
child: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Image.asset(
'assets/images/bg.png',
fit: BoxFit.contain,
height: 70.0,
),
],
),
),
),
Expanded(
flex: 1,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(Colors.white),
),
Padding(
padding: EdgeInsets.only(top: 20.0),
),
Text(
"Загружается...",
softWrap: true,
textAlign: TextAlign.center,
style: TextStyle(fontSize: 18.0, color: Colors.white),
)
],
),
)
],
)
],
),
);
}
}
How I can correctly add RefreshIndicator to webview in my case?