ridu
import 'package:flutter/material.dart'; import 'package:webview_flutter/webview_flutter.dart'; void main() => runApp(MyBrowserApp()); class MyBrowserApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Simple Browser', theme: ThemeData( primarySwatch: Colors.blue, ), home: BrowserPage(), ); } } class BrowserPage extends StatefulWidget { @override _BrowserPageState createState() => _BrowserPageState(); } class _BrowserPageState extends State<BrowserPage> { final TextEditingController _controller = TextEditingController(); List<WebViewController> _tabs = []; List<String> _titles = []; int _currentTabIndex = 0; bool _showHomePage = true; @override void initState() { super.initState(); _addNewTab(showHomePage: true); } void _addNewTab({bool showHomePage = false}) { WebViewController webViewController = WebViewController() ..setJavaScriptMode(JavaScriptMode.unrestricted) ..setNavigationDelegate(NavigationDelegate( onProgress: (int progress) {}, onPageStarted: (String url) { _updateLoading(url); _updateTitle('Loading...', _currentTabIndex); }, onPageFinished: (String url) { _updatePageTitle(_currentTabIndex); }, onWebResourceError: (WebResourceError error) {}, onNavigationRequest: (NavigationRequest request) { return NavigationDecision.navigate; }, )); setState(() { _tabs.add(webViewController); _titles.add('New Tab'); _currentTabIndex = _tabs.length - 1; _showHomePage = showHomePage; }); } @override Widget build(BuildContext context) { return WillPopScope( onWillPop: _onWillPop, child: Scaffold( appBar: AppBar( title: _showHomePage ? Text('Homepage') : TextField( controller: _controller, decoration: InputDecoration(hintText: 'Enter a URL or search'), onSubmitted: (input) => _loadSearch(input), ), ), body: _showHomePage ? buildHomePage() : WebViewWidget(controller: _tabs[_currentTabIndex]), bottomNavigationBar: buildBottomNavigationBar(), ), ); } Widget buildHomePage() { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Padding( padding: const EdgeInsets.all(8.0), child: TextField( decoration: InputDecoration( hintText: 'Enter a URL or search', border: OutlineInputBorder(), ), onSubmitted: (input) => _loadSearch(input), ), ), Wrap( spacing: 10.0, children: <Widget>[ _quickAccessButton('Facebook', 'https://facebook.com'), _quickAccessButton('Twitter', 'https://twitter.com'), _quickAccessButton('YouTube', 'https://youtube.com'), _quickAccessButton('Gmail', 'https://mail.google.com'), ], ), ], ), ); } Widget _quickAccessButton(String name, String url) { return ElevatedButton( onPressed: () => _loadUrl(url), child: Text(name), ); } void _loadSearch(String input) { if (_isValidUrl(input)) { _loadUrl(input.contains('://') ? input : 'https://$input'); } else { _loadUrl('https://www.google.com/search?q=${Uri.encodeComponent(input)}'); } } void _loadUrl(String url) { final Uri uri = Uri.parse(url); if (uri.scheme.contains('http')) { _tabs[_currentTabIndex].loadRequest(Uri.parse(url)); setState(() => _showHomePage = false); } } bool _isValidUrl(String url) { final Uri? uri = Uri.tryParse(url); return uri != null && (uri.scheme == 'http' || uri.scheme == 'https'); } BottomNavigationBar buildBottomNavigationBar() { return BottomNavigationBar( backgroundColor: Colors.white, selectedItemColor: Colors.black, unselectedItemColor: Colors.black, items: <BottomNavigationBarItem>[ BottomNavigationBarItem( icon: Icon(Icons.arrow_back), label: 'Back', ), BottomNavigationBarItem( icon: Icon(Icons.arrow_forward), label: 'Forward', ), BottomNavigationBarItem( icon: Icon(Icons.home), label: 'Home', ), BottomNavigationBarItem( icon: Icon(Icons.refresh), label: 'Reload', ), BottomNavigationBarItem( icon: Icon(Icons.tab), label: 'Tabs', ), ], onTap: (index) => _handleNavBarTap(index), ); } void _handleNavBarTap(int index) { if (index == 4) { _showTabDialog(); } else { switch (index) { case 0: // Back _handleBack(); break; case 1: // Forward _tabs[_currentTabIndex].goForward(); break; case 2: // Home setState(() => _showHomePage = true); break; case 3: // Reload _tabs[_currentTabIndex].reload(); break; } } } Future<void> _handleBack() async { if (await _tabs[_currentTabIndex].canGoBack()) { _tabs[_currentTabIndex].goBack(); } else { setState(() => _showHomePage = true); } } void _showTabDialog() { showDialog( context: context, builder: (BuildContext context) { return AlertDialog( title: Text('Open Tabs'), content: Container( width: double.maxFinite, child: ListView.builder( itemCount: _tabs.length, itemBuilder: (BuildContext context, int index) { return ListTile( title: Text('Tab ${index + 1} - ${_titles[index]}'), trailing: index != _currentTabIndex ? IconButton( icon: Icon(Icons.close), onPressed: () => _closeTab(index), ) : null, onTap: () { setState(() { _currentTabIndex = index; _showHomePage = false; }); Navigator.of(context).pop(); }, ); }, ), ), actions: <Widget>[ TextButton( child: Text('New Tab'), onPressed: () { Navigator.of(context).pop(); _addNewTab(showHomePage: true); }, ), ], ); }, ); } void _closeTab(int index) { if (_tabs.length > 1) { setState(() { _tabs.removeAt(index); _titles.removeAt(index); _currentTabIndex = 0; // Switch to the first tab _showHomePage = true; }); } Navigator.of(context).pop(); } void _updateLoading(String url) { setState(() { _controller.text = url; _showHomePage = false; }); } void _updatePageTitle(int tabIndex) { _tabs[tabIndex].runJavaScriptReturningResult('document.title').then((result) { String title = result is String ? result : 'No Title'; setState(() { _titles[tabIndex] = title; }); }); } void _updateTitle(String title, int tabIndex) { setState(() { _titles[tabIndex] = title; }); } Future<bool> _onWillPop() async { if (!_showHomePage) { if (await _tabs[_currentTabIndex].canGoBack()) { _tabs[_currentTabIndex].goBack(); return false; // Prevent exiting the app } else { setState(() => _showHomePage = true); return false; // Prevent exiting the app } } else { return (await showDialog( context: context, builder: (context) => AlertDialog( title: Text('Exit Browser'), content: Text('Are you sure you want to exit the browser?'), actions: <Widget>[ TextButton( child: Text('No'), onPressed: () => Navigator.of(context).pop(false), ), TextButton( child: Text('Yes'), onPressed: () => Navigator.of(context).pop(true), ), ], ), )) ?? false; } } }
Leave a Comment