i'm trying to save web page for offline. suppose, if an user has internet connection and visited the page. then it should have to save the last loaded page for offline view. if user don't have internet connection and open the page, it should have to show the previously loaded page. is that possible?
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
class MyCertificatesScreen extends StatefulWidget {
static const routeName = '/webview';
final String url;
const MyCertificatesScreen({Key? key, required this.url}) : super(key: key);
@override
_MyCertificatesScreenState createState() => _MyCertificatesScreenState();
}
class _MyCertificatesScreenState extends State<MyCertificatesScreen> {
late InAppWebViewController _controller;
bool isLoading = true;
final cacheManager = DefaultCacheManager();
@override
void initState() {
super.initState();
// Initialize connectivity
Connectivity().onConnectivityChanged.listen((result) {
if (result == ConnectivityResult.none) {
// No internet connection, try loading cached HTML file
_loadCachedHtmlFile();
}
});
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
// Load the appropriate content based on connectivity
_checkConnectivityAndLoadContent();
}
// Function to load cached HTML file
void _loadCachedHtmlFile() async {
try {
final fileInfo = await cacheManager.getFileFromCache(widget.url);
if (fileInfo != null && fileInfo.file != null && await fileInfo.file.exists()) {
// Cached file exists, load it
final fileContent = await fileInfo.file.readAsString();
_controller.loadData(data: fileContent, mimeType: 'text/html');
} else {
// No cached file found, show an error message or a default page
// You can display an error message here or load a default local HTML file
}
} catch (e) {
// Error loading cached file, show an error message or a default page
// You can display an error message here or load a default local HTML file
}
}
// Function to check connectivity and load content accordingly
void _checkConnectivityAndLoadContent() async {
var connectivityResult = await Connectivity().checkConnectivity();
if (connectivityResult != ConnectivityResult.none) {
// Internet connection available, load web page from URL
if (_controller != null) {
_controller.loadUrl(urlRequest: URLRequest(url: Uri.parse(widget.url)));
}
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color(0xFFF5F9FA),
appBar: null, // Set the app bar to null to remove it
body: Stack(
children: [
InAppWebView(
initialOptions: InAppWebViewGroupOptions(
crossPlatform: InAppWebViewOptions(
javaScriptEnabled: true,
),
),
onWebViewCreated: (InAppWebViewController controller) {
_controller = controller;
// Load the appropriate content based on connectivity
_checkConnectivityAndLoadContent();
},
onLoadStop: (InAppWebViewController controller, Uri? url) {
setState(() {
isLoading = false; // Hide the progress indicator
});
},
onLoadError: (InAppWebViewController controller, Uri? url, int code, String message) {
// Handle web page loading errors here
print("Webpage error: $message");
// If loading from cache fails, show an error message or a default page
// You can display an error message here or load a default local HTML file
},
),
if (isLoading)
Center(
child: CircularProgressIndicator(), // Show the progress indicator
),
],
),
);
}
@override
void dispose() {
cacheManager.dispose();
super.dispose();
}
}
I see you are using an
InAppWebViewControllerobjet. If this object is the one documented here, you have a getHtml() → Future<String?> method which you could call like this to get the HTML:This
htmlString can then be stored for later offline navigation.