1

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,

1 Answer 1

1

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,
    
    ));
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for your answer. I tried to use your code. But it didn't change items on bottom navigation bar when I moved to other page on webView.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.