Masaya
Masaya

Reputation: 301

Switch botttom navigation items by current url on webview_flutter

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

Answers (1)

AJ-
AJ-

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

Related Questions