Logo

dev-resources.site

for different kinds of informations.

A Search Bar in Flutter without any External Package

Published at
3/5/2022
Categories
flutter
searchbar
flutterdevelopment
programming
Author
raj4477
Author
7 person written this
raj4477
open
A Search Bar in Flutter without any External Package

The lack of a built-in search bar Widget, equivalent to a SearchView for Android, UISearchBar accessible when creating for iOS, or a SearchBar in React Native, was one challenge I recently faced while designing a mobile application using Flutter.
I was able to identify a couple of Dart Packages that attempted to fix this problem, but I chose to solve this myself rather than depending on the third-party packages’ upkeep and health.
Now I’ve made the decision to do it on my own. So let me break the task into small steps.

Step 1- Creating a model of a searchable list

when it comes to models, classes come 😉.

class model { 
 final String name; 
 model({this.name});
}
Enter fullscreen mode Exit fullscreen mode

Then we will make a list of the model class, explicitly.

  // List of items to be searched
List<model> Items = [   
 model(name: "Name"), 
 model(name: "XYZ"), 
 model(name: "Demo"), 
 model(name: "GDSC"),  
 model(name: "Unknown"),  
 model(name: "Upper Moons"),  
 model(name: "Tanjiro"), 
 model(name: "Kivan"), 
 model(name: "India"), 
 model(name: "USA"),
];
Enter fullscreen mode Exit fullscreen mode

We can also take data from the internet in form of HTTP response in this project. But that part could be more lengthy so we will cover that part in the upcoming articles.
So we have created a local list (searchable)🙌.
Then we also have to create a list of items to be filtered after searching

// List of item to be filtered after searching
List<model> filteredItem = [];
Enter fullscreen mode Exit fullscreen mode

Step 2- Creating the UI of the App

Widget build(BuildContext context) {   
 Size size = MediaQuery.of(context).size;   
 return Scaffold(      
    body: SafeArea(    
    child: Column(       
       children: [          
          Padding(         
            padding: const EdgeInsets.all(8.0),   
             child: Container(     
                  width: size.width, 
                  height: size.height * 0.1,                                                 
                  alignment: Alignment.center,
                  child: TextField(          
           // controller: textController, We will declare this later 
                  decoration: InputDecoration(     
                      prefixIcon: Icon(
                         Icons.arrow_back_ios_new_sharp, 
                             color: Colors.black,), 
                   hintText: "Search",  
                   enabledBorder: OutlineInputBorder(    
                        borderRadius: BorderRadius.circular(25)),  
                  focusedBorder: OutlineInputBorder(      
                         borderRadius: BorderRadius.circular(25),   
                         borderSide: BorderSide(width: 2)),    
                ),
             ),   
           ),      
          ),
    Expanded(
    child: ListView.builder(
     itemCount: filteredItem.length,
     itemBuilder: (context, index) {
           return Container(
              margin: EdgeInsets.only(top: 10),
               width: size.width * 0.9,
               height: size.height * 0.0888,
               alignment: Alignment.centerLeft,
               decoration: BoxDecoration(
                   color: Color(0xff9379FF),
                   borderRadius: BorderRadius.circular(20)), 
               child: Padding(
        padding: const EdgeInsets.only(left: 28),
         child: Text(
           filteredItem[index].name,
           style: TextStyle(
           color: Colors.white,
           fontSize: 22,
           fontWeight: FontWeight.w400),),),
                   );
                })// ListBuilder
           ), //Column
          )//SafeArea
           ); //Scaffold
Enter fullscreen mode Exit fullscreen mode

But we have to initialize our filteredItem with Item in the initState() function of the class of the screen.

void initState() {    
super.initState();    
filteredItem = Items;
}
Enter fullscreen mode Exit fullscreen mode

Step 3- Declaring TextEditingController listener for TextField and adding its Listener, too.
For controlling the text entered in the TextField, we have to make an instance of TextEditingController, named as textController
final textController = new TextEditingController();
Before adding a listener, we will declare two global variables

String searchText = ""; // to store the search text in TextField
bool found = true; //to store whether searched text is found or not
Enter fullscreen mode Exit fullscreen mode

Now adding the listener of textController in the initState() function of Stateful class

void initState() {    
super.initState();    
filteredItem = Items;
textController.addListener(() {
      if (textController.text.isEmpty) {
        setState(() {
          searchText = "";
          found = true;
          filteredItem = Items;
        });
      } else {
        setState(() {
          searchText = textController.text.trim();
        });
        // Function for checking the items in List searchFunc();
      }
    });
}
}
Enter fullscreen mode Exit fullscreen mode

Step 4- Making the Function which will be invoked for Searching
The basic approach is that we will iterate through Item list and check whether searchText contains the list if it does then we will add Item at that index to a temporary list. Then later on we will equalize our filteredList with that temporary and set found equal to true in setState() Function
Let’s code it🤞.

void searchFunc() {
    List<model> tempList = [];
    if (!searchText.isEmpty) {
      for (int i = 0; i < Items.length; i++) {     if(Items[i].name.toLowerCase().contains(searchText.toLowerCase())) {
          tempList.add(Items[i]);
        }
      }
      setState(() {
        found = true;
        filteredItem = tempList;
      });
    }
   if (filteredItem.isEmpty) {
      setState(() {
        found = false;
      });
    }
  }
Enter fullscreen mode Exit fullscreen mode

Looks great.
Wait but what if searchText is not available in the Item list😥.
No worries 😎, we already declared a global variable named found. So if found is true then we will display our List(filteredList) otherwise we will display Text as “Not Available”

Sounds good! Let’s code this approach, too.

Expanded( 
     child: found
                  ? ListView.builder(
                      itemCount: filteredItem.length,
                      itemBuilder: (context, index) {
                        return Container(
                          margin: EdgeInsets.only(top: 10),
                          width: size.width * 0.9,
                          height: size.height * 0.0888,
                          alignment: Alignment.centerLeft,
                          decoration: BoxDecoration(
                              color: Color(0xff9379FF),
                           borderRadius: BorderRadius.circular(20)),
                          child: Padding(
                           padding: const EdgeInsets.only(left: 28),
                            child: Text(
                              filteredItem[index].name,
                              style: TextStyle(
                                  color: Colors.white,
                                  fontSize: 22,
                                  fontWeight: FontWeight.w400),
                            ),
                          ),
                        );
                      }
                      )
                  : Container(
                      height: size.height * 0.72,
                      width: size.width,
                      alignment: Alignment.center,
                      child: Text("Not Available",style:
                      TextStyle(color: Colors.black,fontSize: 23),),
                    ),//Container
            ) //Expanded
Enter fullscreen mode Exit fullscreen mode

Our Task is done now 🙌🙌

FULL CODE

Catch me on LinkedIn

Medium Post

flutterdevelopment Article's
30 articles in total
Favicon
Streamlining Flutter Development with FVM: A Comprehensive Guide
Favicon
Constraining Dart’s Numeric Types And Why You May Want To Do This
Favicon
Hire Dedicated Flutter Developers Online: Unveiling Top Benefits
Favicon
Flutter Flair: Elevating Your UI/UX Game with Dart's Magic
Favicon
Getting Started with Flutter for Mobile Application Development
Favicon
Unleashing the Power of Flutter: Your Ultimate Guide to Hiring Flutter Developers
Favicon
Isolate Bliss: Elevate Your Flutter Experience✨
Favicon
Firebase vs Device Time
Favicon
Understanding the Significance of the Freezed Package in Flutter
Favicon
Applying Dependency Injection in Flutter Using Injectable
Favicon
Getting creative with Shorebird
Favicon
Deploying Flutter Application with Github Actions (PlayStore)
Favicon
The Power of Flutter for Web Development: Should You Use it?
Favicon
The Benefits of Using Flutter for MVP Development
Favicon
Essential Tools for Flutter Developers: Boosting Productivity and Efficiency
Favicon
The Power of Flutter: Creating Cross-Platform Applications
Favicon
Flutter: Data Testing
Favicon
Widget testing: Dealing with Renderflex Overflow Errors
Favicon
Flutter: Up your testing game
Favicon
Custom Draggable Bottom Sheet in Flutter
Favicon
Flutter 2.10: Flutter Stable Support for Windows and Other Updates
Favicon
A Search Bar in Flutter without any External Package
Favicon
Weekend App: 3D Print Cost Calculator
Favicon
Why choose Flutter?
Favicon
Changing your debugging browser for Flutter (MacOS)
Favicon
My essential tools as a Flutter Developer
Favicon
Unit testing DateTime.now() with the help of Dart extensions
Favicon
Flutter Web: Should I use it? (Part 4— I believe so)
Favicon
Flutter Web: Should I use it? (Part 3— Other considerations)
Favicon
Flutter Web: Should I use it? (Part 3 — Other considerations)

Featured ones: