Search Bar in Flutter – Logic & Material UI

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
searching through all kinds of various content in your flutter app is something you'll likely have to implement one day a successful search implementation needs basically two things a usable search history and also the search bar widget now we are going to take a look at the most extensible and good looking way to do this [Music] hello welcome to riso coder where you are getting prepared for real app development so that you will get freelance clients or a job and be confident about the apps you build so subscribe and hit the bell to join us on our quest for becoming in-demand flutter developers in this project we are going to build a simple app which will contain the basic building blocks of a good search implementation and of course there are many ways to build a search thing in a flutter app but we are going to focus at least in the ui part of things on a package called material floating search bar so this is how it looks like and how it operates in a finished app so this is the app well built we can search for a new term new term and uh search for it now we're going to get search results of course this is just a demo app so the search results don't look really fancy they just are 50 results numbers from 0 to 49 of course and uh yeah so that's it and we can also uh tap on an already existing search term from the history so for example flutter and when we tap on flutter it's gonna be taken to the top of the search history so the most recently used items are first and then there is also a limit on the amount of items in the history that we can have so if we type in another term the last one the last previous term was removed so again the last term is widgets we type in hey search for it and widgets is now no longer present in the history because there is a limit of five items in the history and then also you will be able to delete individual terms like this so this is the extent of the functionality of the app we are going to build there is a bunch of code which is not really so important to what we are trying to accomplish here but it's still necessary to have it so that you can uh have the app running and to get all of this code which you can actually now see on the screen including this search results list view just go to the written tutorial from the link in the video description which contains the link to the star project on github and also in the written tutorial you can find all of the code written in this video links to the libraries and overall go through this lesson at your own pace we are first going to focus on the search history and logic part of things and only then are we going to add the floating search bar from the package which is also linked in the written tutorial the way we are going to implement history will be quite simple we want to keep it down to earth by just operating within the state class so we're going to to just use stateful widgets for state management and also we are not going to persist the history we're just going to use a simple in-memory list that's because there are literally hundreds of ways you could take this simple search history project and apply any kind of state management solution you like whether that's change notifier block state notifier i know get x i i really don't know what else you could apply here when it comes to state management then the same goes for databases you can use more sql flight sambast hive all kinds of things shared preferences and therefore it's just best for me to demonstrate something on the simplest case and then as you will see in just a bit you are going to be able to take all of the code written in this video and change it just a little bit and apply it to your needs with for example hive database and change modifier for state management it's totally up to you the code with that we are going to write in this tutorial is going to be very easily changeable to your particular needs so let's start we are going to need to define the history length which in our case is going to be limited to five so let's create a static constant history length equal to five then as we are going to operate with just a in memory list let's create a list of strings search history starting with an underscore and let's make it equal to an empty list or actually we can make it equal to some predefined history so that we always don't just need to refill the history when we hot restart the app so i'm gonna add the search terms fuchsia flutter widgets and resulcoder to the history so this search history with an underscore is the raw history that we are now going to access from the widgets from the ui and is also pre-filled with values then additionally we want to have another list of strings and this is going to be called filtered search history this one is going to be filtered and also ordered and this history field is actually going to be accessed from the widgets from the ui filtering simply means that as we start typing so let's add another term here starting with uh hello for example this is going to be a good one and as we start typing h riso color is going to disappear sadly when we type e both terms will remain here because the start string of the terms is h e and then when we type l only hello will remain and hey will disappear as well so this is the filtering and when it comes to ordering well we want to order the most recently used items to be first to appear first in the list the way that we are going to do the ordering actually is going to be very very simple and i i think it's quite clever basically whenever you add a new item to a list it's added to the end of the list so new item gets added here to the very end of the list and the way we can show the newly added or newly used items at the top of the list here is just by simply reversing the order of the list so we are going to call reversed that's it this is how we're going to order the list just how we want it to be ordered and lastly we also need to have a string selected term this is going to be needed for when we actually well select a term so that we can display the search results for the selected term accordingly let's first tackle the problem of filtering the search terms we're going to create a function returning a list of strings filter search terms and it's going to take in an optional required name parameter so actually it's no longer optional when it's required required string filter in case that the pest in filtering stream is not null or it's also not empty so if filter doesn't equal null and filter is not empty we want to do just what i have described as i was showing you how the filtering actually works so we want to take the search history to return search history the raw one with an underscore we wanna reverse it so that it's ordered properly and then we want to say where so that filtering can actually take place where term starts with filter as easy as that and then we want to convert it to a list because uh where and reversed both return and iterable but we want to have a solid list in here so this is pretty self-explanatory it orders things so that the most recently used items search terms are being displayed first in the ui eventually and we also filter it with the where function otherwise so else if the pest in filter is in fact null or it's just empty we do not want to filter anything so we're just going to return search history reversed and also to list of course and also i've just noticed that for some reason here's a semicolon let's remove that and now we are golden adding search terms is not going to be as simple as calling add on a list like this because we want to ensure that there are no duplicates in the history and also if the term we are trying to add to the history already exists in there we instead just want to reorder the already existing term to appear first in the ui so in other words when we for example try to again search for flutter by typing in flutter but flutter already exists in the history what we want to do is to move it down so that uh effectively we're gonna move it up in the ui because as you know by now we are using a reversed list so this is what we are trying to uh accomplish right now so let's create a function which is going to return void add search term and we need to accept a string term so we do not want any duplicates in the search history so we are first going to check if search history contains term and if it does contain the term well what we want to do is what i've just described we want to put the already existing search term first for now let's just write a bit of a pseudocode which is not going to compile just yet let's just write put search term first and pass in the search term we're going to implement this method in just a little while but it's pretty apparent what this method is going to do and then we want to short circuit the execution of the method so let's just return then if the history doesn't contain the term we're trying to add already we're just going to add the search term to the history so search history add term and now what we mustn't forget to do when we are adding new search terms is to limit the amount or the length of terms that's allowed in the history as you remember we have set it to five so what we are going to do is check if search history dot length is greater than history length if it is greater then we need to remove the excessive old search history terms we are going to apply a very simple algorithm which is called least recently used which means that we are going to remove the least recently used search term if we go over the history limit to do that we're going to say search history remove range we're going to say remove range because technically we could be removing multiple terms at once it's probably not going to happen because you know we are adding new terms one by one so we are probably going to removing terms also one by one but just in case that we have some preceded values in the history let's stick with remove range and we want to remove the oldest so the least recently used items which in the case of the raw search history start at the beginning of the list so zero index and we want to remove until search history dot length minus history length this subtraction produces the count of excess items in the history and lastly we have just updated the search history which is a state but actually what we are going to be using from the ui from the widgets is the filtered search history so we also need to update that by calling filtered search history is equal to filter search terms and the past in filter will be null you may be asking how do we know if the filter is truly null what if the user has already typed in something into the search bar hello again well if this happens and we are adding a term it just totally doesn't matter because once we search for this term the search bar is either way going to be reset without a term again so that's the reason why we can call with a null filter at all times when we add a new search item again this implementation of adding your search terms and also of the filtering will depend a bit on the database you choose to use and also on the state management solution you choose to use with your app but the principles and even the basic code will remain the same when it comes to deleting the terms by clicking on these x's next to the names of the terms that's pretty simple we're going to create a void method again delete search term accepting a string term and what we're gonna do here is just say search history remove where and where the term t is equal to the pass in term and lastly also we want to update the filtered search history because again this filtered search history is what's actually going to be used from the widgets so we need to always update that in sync when we update the search history which is the private field which is not gonna be used from the widgets let's now think about how we're gonna implement the put search term first method which is uh very important here so that we can have a nicely functioning history which displays the most recently used terms first in the ui let's create a void put search term first which will accept a string term the way we can implement this simply is actually by just first deleting the search term and then by adding it again so add search term why well because deleting a search term is gonna delete it from wherever it is in the history so for example flutter it's gonna be deleted from history wherever it is and then adding it will always just add it to be the last one in the raw search history so again this means that it's first in the filtered and ordered search history this approach is perfect because we are just storing simple strings in the history now of course you could create your own class and store some date time or timestamp object inside of it and update the timestamps of when they were last used and so on that's totally doable but i think that this simple approach works just fine and it's performant there's no issue with it so uh we're going to stick with this simple approach of just first deleting and then adding the search term anew when we try to put it first additionally let's just initialize the filtered search history from init state because as of now it's just null by default so we're going to say filtered search history is equal to actually this null thing so filter search terms filter null and now we can go ahead and implement the search bar ui also again if you would like to look at this code at your own pace to copy it into your project and so on check out the written tutorial from the link in the video description as i've already mentioned we are going to use the material floating search bar package so let's add it to the pop spec the version we are going to use is 0.2.6 you can also get this version and all of that also the link to the library from the written tutorial so let's save the pop spec and here we go we can now use this package from our dart code unlike with the default app bar which you usually put into the app bar parameter or property of the scaffold what we are going to do with the floating search bar is that it's actually going to be wrapping the body of the scaffold so the body of the scaffold currently is just a simple search results list view which just doesn't display anything at this point and we are going to wrap it with a widget called floating search bar let's import that from the package and the search results list view is now going to be the body of the floating search bar and actually let's run the app on an emulator because currently we are running the already pre-built app the app doesn't look like much right now because we are actually missing some required parameters for the floating search bar but we are going to handle that later on for now since we want to also control the search bar programmatically for example close the history view with the history terms displayed whenever we add a new search term or when we click on already existing search term from the history to do that programmatically we need to have a floating search bar controller field so let's just call it controller and we're going to initialize it in its state so controller is equal to floating search bar controller and now we're going to put this controller as the controller of the floating search bar and also we mustn't forget to dispose of the cons controller inside of the dispose method so controller dot dispose now i'm not sure if you have noticed but in the finished app when we scroll down the list the search bar gets hidden you know we scroll up it gets shown again this behavior can only happen if we wrap a scrollable or something which contains some sort of a scrollable list view for example like this search results list view we have here inside of a widget called floating search bar scroll notifier this is going to ensure that the notifications about scrolling from the list view right here are going to be also translated into notifications which affect the floating search bar and then the search bar is going to be automatically hidden and shown depending on how the user scrolls the list view there are a bunch of cosmetic fields which need to be set on a floating search bar too so one of them is transition this is what you see when you open up the search bar so this brief transition when you have more items in there it's more visible so it's sort of a circular floating search bar transition and this is precisely how it's called i'm actually just going to copy its name paste it here you can always get the code from the written tutorial available from the link in the video description then let's talk about physics for a while so the physics for the search bars pop up here they by default are the material physics which shows that over glow or how it's called but we actually want to have the ios style physics which are the balancing scroll physics so again i'm going to copy the code from the written tutorial browsing scroll physics these physics are not applied if you have a low amount of history items inside of there but if you have more search terms in the history then scrolling will take place and this is when you will see the physics so we want it to bounce the next thing is the title so the title is what you see when the search bar is not active let's say so when the user does not click on it basically whenever we have already searched for something for example transition or riso coder we want to show that selected term in the title but if the selected term is null so that means the user has not selected any term yet we just want to show the search app and also it's quite important to style this text properly headline six is actually the style for the default ebar's title so we're gonna be using this headline six from the material theme lastly we have the hint which is the thing that gets shown when you actually activate the search bar so search and find out this is where we want to be shown in there it's also quite useful to be able to clear out something that the user has written so for example we mess up we write something like this we want to be easily able to just clear it up so we have this x icon over here we press that it's cleared up and we can type in new things so this action is actually floating search bar action which is a very special type of an action search to clear so let's add actions floating search bar actions dot search to clear and of course you have multiple other actions which you can add there you can even create your own actions but i think that uh we're just fine with only the search to clear action it's quite useful actually and also it has very nice animations by default so that's definitely a nice touch how are we going to find out about the text that's changing inside of the text field here and how are we going to find out when a user submits this query well we need to find out about these actions and that's exactly what callback methods are for so we have one called on query changed and when the query is changed what we want to do is to refilter the search terms based on the new query so we're going to set state and we're going to set filtered search history equal to filter search terms based on the query being the filter then when the search term is submitted we want to take this query and set state obviously when the search term is submitted we want to add the entry to the history so we are going to add search term query and also whenever something is submitted we want to automatically select it so that it's going to be searched next see search next is now going to be searched next so let's say selected term is equal to query and if i could spell select it term and lastly we're going to use that controller to programmatically close the search bar so we're going to say controller dot close by now we have set up everything except for the ui that's actually responsible for showing the search history terms so in order to implement that there is the builder parameter which gives us a context and a transition the floating search bar gives us a completely free hand at how we want to style this pop-up over here or i'm not sure if it's even a pop-up but this ui element we can style it however we want so we basically want to have rounded corners we want it to be white at least the background should be white and also whenever we press on the list styles here which we are going to add in just a moment there should be this ripple effect so we should see the ink that means that we need to use the material widget because material allows us to use this ink so we're going to return clip r rect because we want to clip the material which is going to be child of this clip are wrecked and we want to clip it so that the borders will be circular so we're going to say border radius is equal to border radius that's circular and the radius is 8 this is a general nice number to use when you are dealing with circular borders and then the child of this clip erect will be material its color will be colors white just simply hard coded in there and let's also deal with elevation to before it's not very visible but i think it's slightly more good looking than if you don't edit here now we're going to take care of the actual child of the material in just a bit but for now let's just put a placeholder in here with fallback height of 200 and let's see how it looks so actually i'm going to switch to this app now it's actually displaying properly and when we tap on the search bar we can see the placeholder with rounded corners and it's white background so that's nice the thing with the content of this builder is that we're not always going to display only the filtered search history for example when i delete all of the search terms we want to show this start searching message then when i type in something and it's not present in the history already we want to show this little hint or however you want to call it which contains exactly the string which we are typing above like this then when we tap on it we're going to add this search term right and only then we want to show the history which is filtered filter it right so something like this when we type in a only a will be displayed so this is only the third case we have three cases of what we want to display in there this means that we are going to use some conditional logic to satisfy the different conditions and display different widgets according to them this in turn means that we need to break out our code into another build method with a builder widget you could also create your own custom widget class but i'm just too lazy to do that so let's just stick with the builder as a quick fix so actually here we go with the builder yeah let's first focus on when we want to display the simple start searching uh hint to the user well that's going to happen if the filtered search history is empty and also controller dot query is empty so we have nothing in the search history at all or at least not in the filtered search history and also actually the query is empty so the user has not typed in anything in that case we want to return a simple container with a text and it's styled nicely and because i don't want to bore you i'm just going to paste it in here you can study it at your own pace from the written tutorial which is available in the link in the video description as always then the next special case which we have already gone through is when you type in something which is not present in the history at all then this gets displayed which is a special list style and when you tap it you're going to search for this term so you're going to add it to the history also so this condition happens so else if the filtered search history is empty but in turn the controller's query the typed in thing by the user is not empty in such a case we want to return a ali style which will have title set to a text containing the controller's query then the leading icon will be just a constant icon icons dot search and now we're getting into the interesting stuff the on tab method of this special list style actually the content of the ontab method the logic which should run is identical to when you are just simply adding a new search term through unsubmitted and now i could just create a brand new method a helper method which would encapsulate this functionality so that we don't have any code duplication but actually this is just a tutorial focused on showing you how to build a search bar so i'm just going to blatantly copy it over here and instead of query we need to write controller that query and also let's not forget about our semicolons lastly inside of the else clause we want to display all of the search history terms inside of a column we are now going to be using a list view for a bunch of reasons which are more outlined in the written tutorial but basically uh yeah there are just issues with these views we would need to disable scrolling we would need to shrink wrap it so i think it's just easier to use columns so let's return a column the catch with a column is that actually it needs to have main axis size set to main xe size dot min and now the children's or the children of the column are going to be derived from the filtered search history so let's say filtered search history dot map and from this map function which will give us terms so term we're going to return for each and every term a list style which will be having a text inside of the title that is going to just display the term as always you can get this code from the recent tutorial next the leading icon in the list style will be showing a history icon like this then the trailing icon is actually going to be interesting because it will contain some logic it will not just be any kind of an icon it will be an icon button and this icon button when it's pressed is going to delete the search term in question and then lastly we are going to add the on tab callback function which will put the search term first and also select the term and also close the search bar programmatically so this is happening because whenever we actually select a term of course we want to search for it so that's why we select it and also put it first because the most recently used items should be displayed first so with this done let's go to the app and let's actually go to the app we are building currently we have some errors and those are quite simple that's because we have an error here which says that basically we need to return a list of widgets not an iterable of list styles so we just need to find the end of this map right here it is and we need to call to list on it and now what's going to happen is that it all works we can see that the app is now successfully built we can search for riso coder and nothing happens why well that's because we are not passing in the selected term this one into the list view so let's scroll down and here inside search results list view we are always passing in null so let's now pass in the selected term from the state save that now actually when i come back we should see the search results being displayed in the app properly but here's the catch have you noticed something weird i'll wait maybe one second the weird thing is that we are displaying 50 search items but the first one we see here is actually the second item because the ordering starts from zero so we should see zero one two three but we see only one two three what's up with that well the thing is that you can currently not even see the very first result because it's hidden by the search bar when i actually try scrolling like this you can see something up top you can see that something is in there but now it gets hidden behind the search bar just perfectly what we need to do is to apply some padding on this list view so that the very first search result is actually going to be visible and we could apply some generic padding some hard-coded values but it's always best to apply padding which is dynamically gotten so basically we need to apply a padding of the height and also some vertical margins of the search bar so how can we get these dimensions of the search bar well it's very very simple with the package we are using we can actually get the state of the floating search bar by just simply calling floating search bar dot off and passing the context this is going to grant us the floating search bar state let's just store it inside final fsb for floating search bar state and now we're going to say that the padding of the listview will be edge in sets only and we only want to set the top inset and this is going to be fsb.height but this is not enough as you can see now we can see the zero index but still it's weird it's hidden quite a bit behind the search bar that's because we also need to take care of the fsb.margins.vertical once we have that we can see the zeroth i'm not sure if you can do that but zeroth search result in its full glory and that's it you have just learned how to implement your own solution of a search bar in a very simple manner you are going to be able to take this code which we have written here and apply it to any kind of project you want with any kind of a state management and database solution you want of course you will need to change some things but the principles and even the basic code will still remain the same so to go through this tutorial at your own pace once again and also to get the code check out the written tutorial available from the link in the video description and if you are serious about becoming a great flower developer who can build real apps for clients or at the job go to flutter.education link is also in the video description by the way to get the top curated flutter news and resources aimed at improving your app development career over there you can also subscribe to my mailing list to get the best flutter resources delivered weekly right into your inbox and if you don't want to miss more tutorials like this be sure to subscribe to this channel and also join notification squad by hitting the bell button to make sure you grow your flutter skills because here on riso coder i am determined to provide you with the best tutorials and resources so that you will become an in-demand flutter developer if this video helped you give it a like and also share with other developers who are surely going to find it beneficial too leave a comment if you have anything to say and see you in the next video [Music] you
Info
Channel: Reso Coder
Views: 39,129
Rating: undefined out of 5
Keywords: resocoder, tutorial, programming, code, programming tutorial, flutter, flutter tutorial, flutter search bar, flutter searchdelegate, flutter appbar, flutter appbar design, floating appbar flutter, flutter appbar search bar, flutter appbar search
Id: 26aYqtOTRU4
Channel Id: undefined
Length: 43min 34sec (2614 seconds)
Published: Sat Jan 23 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.