super_webview 1.0.0 copy "super_webview: ^1.0.0" to clipboard
super_webview: ^1.0.0 copied to clipboard

A next-level, high-performance Flutter WebView plugin with advanced features like AI DOM automation, native ad blocking, dark mode, and seamless Flutter-JS integration.

example/lib/main.dart

import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:super_webview/super_webview.dart';

void main() {
  runApp(const MaterialApp(
    title: 'SuperWebView Pro Showcase',
    home: SuperWebViewShowcase(),
    debugShowCheckedModeBanner: false,
  ));
}

class SuperWebViewShowcase extends StatefulWidget {
  const SuperWebViewShowcase({super.key});

  @override
  State<SuperWebViewShowcase> createState() => _SuperWebViewShowcaseState();
}

class _SuperWebViewShowcaseState extends State<SuperWebViewShowcase> {
  late SuperWebViewController controller;
  String currentUrl = 'https://flutter.dev';
  int loadingProgress = 0;
  String? pageTitle;
  bool isDarkMode = false;
  bool isDesktopMode = false;
  bool hasError = false;

  @override
  void initState() {
    super.initState();
    controller = SuperWebViewController();
    _setupController();
  }

  void _setupController() {
    controller.setJavaScriptMode(JavaScriptMode.unrestricted);
    
    controller.setNavigationDelegate(NavigationDelegate(
      onProgress: (progress) => setState(() => loadingProgress = progress),
      onPageStarted: (url) {
        setState(() {
          currentUrl = url;
          hasError = false;
        });
      },
      onPageFinished: (url) async {
        final title = await controller.getTitle();
        if (mounted) {
          setState(() {
            currentUrl = url;
            pageTitle = title;
          });
        }
      },
      onWebResourceError: (error) {
        setState(() => hasError = true);
      },
    ));
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(hasError ? 'Load Error' : (pageTitle ?? 'SuperWebView'), 
                 style: const TextStyle(fontSize: 16)),
            Text(currentUrl, 
                 style: const TextStyle(fontSize: 10, fontWeight: FontWeight.normal),
                 overflow: TextOverflow.ellipsis),
          ],
        ),
        actions: [
          IconButton(
            tooltip: 'Dark Mode',
            icon: Icon(isDarkMode ? Icons.light_mode : Icons.dark_mode),
            onPressed: () {
              setState(() => isDarkMode = !isDarkMode);
              controller.setDarkMode(isDarkMode);
            },
          ),
          IconButton(
            tooltip: 'Desktop Mode',
            icon: Icon(isDesktopMode ? Icons.phone_android : Icons.desktop_mac),
            onPressed: () {
              setState(() => isDesktopMode = !isDesktopMode);
              controller.setDesktopMode(isDesktopMode);
            },
          ),
          PopupMenuButton<String>(
            onSelected: _handleMenuAction,
            itemBuilder: (context) => [
              const PopupMenuItem(value: 'screenshot', child: Row(children: [Icon(Icons.camera_alt), SizedBox(width: 8), Text('Screenshot')])),
              const PopupMenuItem(value: 'print', child: Row(children: [Icon(Icons.print), SizedBox(width: 8), Text('Print Page')])),
              const PopupMenuItem(value: 'clear', child: Row(children: [Icon(Icons.delete_forever), SizedBox(width: 8), Text('Clear All')])),
              const PopupMenuItem(value: 'history', child: Row(children: [Icon(Icons.history), SizedBox(width: 8), Text('History')])),
            ],
          ),
        ],
        bottom: PreferredSize(
          preferredSize: const Size.fromHeight(2),
          child: loadingProgress < 100
              ? LinearProgressIndicator(value: loadingProgress / 100, minHeight: 2)
              : const SizedBox.shrink(),
        ),
      ),
      body: hasError ? _buildErrorView() : SuperWebView(
        controller: controller,
        initialUrl: currentUrl,
        allowPullToRefresh: true,
      ),
      bottomNavigationBar: _buildBottomBar(),
    );
  }

  Widget _buildErrorView() {
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          const Icon(Icons.error_outline, size: 64, color: Colors.red),
          const SizedBox(height: 16),
          const Text('Failed to load page'),
          ElevatedButton(onPressed: () => controller.reload(), child: const Text('Retry')),
        ],
      ),
    );
  }

  Widget _buildBottomBar() {
    return BottomAppBar(
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: [
          IconButton(icon: const Icon(Icons.arrow_back_ios), onPressed: () async {
            if (await controller.canGoBack()) controller.goBack();
          }),
          IconButton(icon: const Icon(Icons.arrow_forward_ios), onPressed: () async {
            if (await controller.canGoForward()) controller.goForward();
          }),
          IconButton(icon: const Icon(Icons.refresh), onPressed: () => controller.reload()),
          IconButton(
            icon: const Icon(Icons.search),
            onPressed: () => _showSearchDialog(),
          ),
          IconButton(
            icon: const Icon(Icons.auto_awesome, color: Colors.deepPurple),
            onPressed: () {
               ScaffoldMessenger.of(context).showSnackBar(
                 const SnackBar(content: Text('AI Automation: Try searching for "Email" field in logs!')),
               );
            },
          ),
        ],
      ),
    );
  }

  void _handleMenuAction(String value) async {
    switch (value) {
      case 'screenshot':
        final image = await controller.takeScreenshot();
        if (image != null) _showScreenshot(image);
        break;
      case 'print':
        await controller.printCurrentPage();
        break;
      case 'clear':
        await controller.clearCache();
        await SuperWebViewCookieManager().clearCookies();
        if (mounted) ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('Storage Cleared')));
        break;
      case 'history':
        final history = await controller.getHistory();
        _showHistory(history);
        break;
    }
  }

  void _showScreenshot(Uint8List bytes) {
    showDialog(
      context: context,
      builder: (context) => AlertDialog(
        title: const Text('Captured Screenshot'),
        content: Image.memory(bytes),
        actions: [TextButton(onPressed: () => Navigator.pop(context), child: const Text('Close'))],
      ),
    );
  }

  void _showHistory(WebHistory history) {
    showModalBottomSheet(
      context: context,
      builder: (context) => SizedBox(
        height: 400,
        child: Column(
          children: [
            const Padding(padding: EdgeInsets.all(16), child: Text('Navigation History', style: TextStyle(fontWeight: FontWeight.bold))),
            Expanded(
              child: ListView.builder(
                itemCount: history.list.length,
                itemBuilder: (context, i) {
                  final entry = history.list[i];
                  return ListTile(
                    leading: const Icon(Icons.link),
                    title: Text(entry.title.isEmpty ? 'Untitled' : entry.title, maxLines: 1),
                    subtitle: Text(entry.url, maxLines: 1),
                    selected: i == history.currentIndex,
                    onTap: () {
                      controller.loadRequest(Uri.parse(entry.url));
                      Navigator.pop(context);
                    },
                  );
                },
              ),
            ),
          ],
        ),
      ),
    );
  }

  void _showSearchDialog() {
    String search = '';
    showDialog(
      context: context,
      builder: (context) => AlertDialog(
        title: const Text('Find on Page'),
        content: TextField(onChanged: (v) => search = v, decoration: const InputDecoration(hintText: 'Keyword')),
        actions: [
          TextButton(onPressed: () { controller.clearMatches(); Navigator.pop(context); }, child: const Text('Clear')),
          ElevatedButton(onPressed: () { controller.findAllAsync(search); Navigator.pop(context); }, child: const Text('Find')),
        ],
      ),
    );
  }
}
4
likes
130
points
90
downloads

Documentation

API reference

Publisher

verified publishershirsh.dev

Weekly Downloads

A next-level, high-performance Flutter WebView plugin with advanced features like AI DOM automation, native ad blocking, dark mode, and seamless Flutter-JS integration.

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

flutter, flutter_web_plugins, plugin_platform_interface, web

More

Packages that depend on super_webview

Packages that implement super_webview