Search code examples
fluttersearchdart-null-safety

I wanted to add search bar in my app, but I got some error messages as below


lib/main.dart:143:13: Error: Field 'searchBar' should be initialized because its type 'SearchBar' doesn't allow null.

  • 'SearchBar' is from 'package:flutter_search_bar/src/flutter_search_bar_base.dart' ('../Documents/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_search_bar-2.1.0/lib/src/flutter_search_bar_base.dart'). SearchBar searchBar; ^^^^^^^^^ Error: Cannot run with sound null safety, because the following dependencies don't support null safety:

  • package:flutter_search_bar

So I ran dart pub upgrade --null-safety in terminal.

Error: Cannot open file, path = 'C:\Users\Miche\Documents\flutter\version' (OS Error: The system cannot find the file specified. , errno = 2)

Code: /// Flutter code sample for BottomNavigationBar

// This example shows a [BottomNavigationBar] as it is used within a [Scaffold]
// widget. The [BottomNavigationBar] has three [BottomNavigationBarItem]
// widgets, which means it defaults to [BottomNavigationBarType.fixed], and
// the [currentIndex] is set to index 0. The selected item is
// amber. The `_onItemTapped` function changes the selected item's index
// and displays a corresponding message in the center of the [Scaffold].

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_search_bar/flutter_search_bar.dart';


void main() => runApp(const MyApp()); // This is the main application widget.

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  static const String _title = 'Flutter Code Sample';


  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: _title,
      home: MyStatefulWidget(),
    );
  }
}

/// This is the stateful widget that the main application instantiates.
class MyStatefulWidget extends StatefulWidget {
  const MyStatefulWidget({Key? key}) : super(key: key);

  @override
  State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
}


/// This is the private State class that goes with MyStatefulWidget.
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
  int _selectedIndex = 0;


  static const List<Widget> _widgetOptions = <Widget>[
    Text(
      'Reuse',
      style: TextStyle(fontSize: 20),
    ),
        Text(
          "Reduce",
          style: TextStyle(fontSize: 20),
        ),

    Text(
      'Recycle',
      style: TextStyle(fontSize: 20),
    )
  ];

  void _onItemTapped(int index) {
    setState(() {
      _selectedIndex = index;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Food3Rs'),
        backgroundColor: Colors.green,
      ),
      drawer: Drawer(
        child: ListView(padding: EdgeInsets.zero, children: const <Widget>[
          DrawerHeader(
            decoration: BoxDecoration(color: Colors.green),
            child: Text(
              'Food Reduction',
              style: TextStyle(
                color: Colors.white,
                fontSize: 24,
              ),
            ),
          ),
          ListTile(
            leading: Icon(Icons.bookmark),
            title: Text('Saved Recipes'),
          ),
          ListTile(
            leading: Icon(Icons.account_circle),
            title: Text('Profile'),
          ),
          ListTile(leading: Icon(Icons.settings), title: Text('Settings'))
        ]),
      ),
      body: Center(
        child: _widgetOptions.elementAt(_selectedIndex),
      ),
      bottomNavigationBar: BottomNavigationBar(
        items: const <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            icon: Icon(Icons.food_bank_outlined),
            label: ('Reduce'),
            backgroundColor: (Colors.lightGreen),
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.food_bank),
            label: ('Reuse'),
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.cloud),
            label: ('Recycle'),
            backgroundColor: (Colors.lightGreen),
          )
        ],
        currentIndex: _selectedIndex,
        selectedItemColor: Colors.amber[800],
        onTap: _onItemTapped,
      ),
    );
  }
}

class SearchBarDemoApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
        title: 'Search Bar Demo',
        theme: new ThemeData(primarySwatch: Colors.blue),
        home: new SearchBarDemoHome());
  }
}

class SearchBarDemoHome extends StatefulWidget {
  @override
  _SearchBarDemoHomeState createState() => new _SearchBarDemoHomeState();
}

class _SearchBarDemoHomeState extends State<SearchBarDemoHome> {
  final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
  SearchBar searchBar;

  AppBar buildAppBar(BuildContext context) {
    return new AppBar(
        title: new Text('Search Bar Demo'),
        actions: [searchBar.getSearchAction(context)]);
  }

  void onSubmitted(String value) {
    setState(() {
      var context = _scaffoldKey.currentContext;

      if (context == null) {
        return;
      }

      ScaffoldMessenger.maybeOf(context)
          ?.showSnackBar(new SnackBar(content: new Text('You wrote "$value"!')));
    });
  }

  _SearchBarDemoHomeState() {
    searchBar = new SearchBar(
        inBar: false,
        buildDefaultAppBar: buildAppBar,
        setState: setState,
        onSubmitted: onSubmitted,
        onCleared: () {
          print("Search bar has been cleared");
        },
        onClosed: () {
          print("Search bar has been closed");
        });
  }
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: searchBar.build(context),
      key: _scaffoldKey,
      body: new Center(
          child: new Text("Don't look at me! Press the search button!")),
    );
  }
}

Solution

  • Since you are definately setting the search bar to a non-null value, just not where it's required for the compiler to recognize it, you can use the late keyword:

    late SearchBar searchBar;
    

    See the documentation for the late keyword for more information.