Reputation: 301
I would like to switch bottom navigation items by current url.
But I cannot get current url and switch bottom navigation items.
Here is my environment.
Flutter 2.10.5 • channel stable •
Tools • Dart 2.16.2 • DevTools 2.9.2
Here is my codes.
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
late WebViewController _webViewController;
final key = UniqueKey();
final List<String> _urlList = [
'https://www.google.com/',
'https://www.youtube.com/',
'',
'',
'https://earth.google.com/web/'
];
final List<BottomNavigationBarItem> _homeBottomItems = [
const BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
),
const BottomNavigationBarItem(
icon: Icon(Icons.ondemand_video),
label: 'Youtube',
),
const BottomNavigationBarItem(
icon: Icon(Icons.bookmark_add_outlined),
label: 'Saved',
),
const BottomNavigationBarItem(
icon: Icon(Icons.settings_outlined),
label: 'Setting',
),
const BottomNavigationBarItem(
icon: Icon(Icons.palette_rounded),
label: 'Google Earth',
),
];
final List<BottomNavigationBarItem> _articleBottomItems = [
const BottomNavigationBarItem(
icon: Icon(Icons.arrow_back_ios_outlined),
),
const BottomNavigationBarItem(
icon: Icon(Icons.bookmark_add_outlined),
),
const BottomNavigationBarItem(
icon: Icon(Icons.ios_share),
),
];
int _selectedIndex = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: WebView(
initialUrl: 'https://www.google.com/',
key: key,
gestureNavigationEnabled: true,
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (WebViewController webViewController) {
_webViewController = webViewController;
},
javascriptChannels: <JavascriptChannel>{
JavascriptChannel(
name: "share",
onMessageReceived: (JavascriptMessage message) {}),
},
),
),
bottomNavigationBar: BottomNavigationBar(
onTap: _onItemTapped,
currentIndex: _selectedIndex,
backgroundColor: Colors.grey,
type: BottomNavigationBarType.fixed,
items: (isStateUrl(_webViewController.currentUrl().toString()))
? _homeBottomItems
: _articleBottomItems,
));
}
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
_webViewController.loadUrl(_urlList[index]);
});
}
bool isStateUrl(String url) {
if (url == _urlList[0] || url == _urlList[1] || url == _urlList[4]) {
return false;
} else {
return true;
}
}
}
However, I got the error message.
======== Exception caught by widgets library =======================================================
The following LateError was thrown building MyHomePage(dirty, state: _MyHomePageState#ec0a8):
LateInitializationError: Field '_webViewController@19387772' has not been initialized.
I have no idea how to sole this issue. This is flutter and dart version
Could you tell your idea to solve it?
V/r,
Upvotes: 1
Views: 385
Reputation: 1783
The problem in your code is in the BottomNavigationBar:
bottomNavigationBar: BottomNavigationBar(
onTap: _onItemTapped,
currentIndex: _selectedIndex,
backgroundColor: Colors.grey,
type: BottomNavigationBarType.fixed,
items: (isStateUrl(_webViewController.currentUrl().toString()))
? _homeBottomItems
: _articleBottomItems,
)
you are trying to access _webViewController
before it has been initialize by onWebCreated
.
To solve this, you should move your isStateUrl()
method inside the onWebCreated
, by for example assigning the result to a variable, and then using such variable in the bottomNavigationBar
:
child: WebView(
initialUrl: 'https://www.google.com/',
key: key,
gestureNavigationEnabled: true,
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (WebViewController webViewController) {
_webViewController = webViewController;
setState(() {
isStateUrlValue = isStateUrl(_webViewController.currentUrl().toString());
});
},
javascriptChannels: <JavascriptChannel>{
JavascriptChannel(
name: "share",
onMessageReceived: (JavascriptMessage message) {}),
},
),
and now you can use isStateUrlValue
variable in bottomNavigationBar
:
bottomNavigationBar: BottomNavigationBar(
onTap: _onItemTapped,
currentIndex: _selectedIndex,
backgroundColor: Colors.grey,
type: BottomNavigationBarType.fixed,
items: isStateUrlValue
? _homeBottomItems
: _articleBottomItems,
));
Upvotes: 1