So I mentioned in the last video that the search framework doesn't do the searching for us.
We have to write the code to do that.
Now a common way for it to work is that the user answers the search criteria, and when they submit the
query, the search framework launches another activity to deal with the searching.
And that's why we had to set up the intent filter in the manifest.
But we're going to be doing things slightly differently.
So here, the same activity that contains the intent filter is the one displaying the SearchView widget.
Now this is quite a simple example of how to add a search to an app, and all we need to do here is pass
the search terms back to our main activity, so that it can filter the flickr photos.
So let's see what happens when I search for something and submit the query. So I'm going to just go back to our emulator,
which is running.
So we go into our search.
So what actually happens when I do try searching for something, so I'll search for Oreo and press enter.
Basically it doesn't matter at this stage because we haven't written the code to deal with it, but nothing seems to
have happened.
But if we have a look at the log cat,
we can see here, SearchActivity, so onCreateOptionsMenu and onCreate starts, and they're being called again
because they're actually previously called further up.
So basically they're called, once we press enter there to submit to search.
So in other words, when we submit the search, Android search framework looks in the manifest for an activity
that has the action dot search intent filter and launches that activity, which in this case is our Search
Activity.
Now as I said, a common approach is to have the SearchView widget in one activity, say MainActivity, and
have it launch another activity to perform the actual search.
But the approach we're going to use here is to respond to callback events from the SearchView widget,
to retrieve the search terms that our user enters, then pass them back to MainActivity.
Now we're not going to use the intent filter in the manifest, but we still have to include it, because
the search manager needs it in order to get the searchable info for the activity.
So what we're going to do instead, is respond to events generated by the SearchView widget to handle the
user's search query, and that'll prevent this undesirable behavior.
We're submitting a search just launched, a search activity again as you saw. Alright so documentation
time again. Let's check out some documentation.
Let's have a look at the events that SearchView allows us to respond to, and right away you can see
that the summary's pretty helpful here. Scrolling down here you can see that there's an OnCloseListener, and
an OnQueryTextListener as
well. Now they both sound promising,
so I'm going to follow the links to see how to use them.
Let's have a look at onCloseListener,
and you can see that onCloseListener defines a single function, onClose,
that's called when the user closes a SearchView.
Now if we override that we should return false, to retain the default behavior of clearing the text field and
dismissing it,
closing the SearchView down in other words.
OK, so that sounds like a way to deal with the user cancelling the search,
so let's go back and follow the other link.
So have a look for this OnQueryTextListener, and you can see that OnQueryTextListener defines two
functions. We can monitor every change the user makes to the query text as they type,
but for our purpose, the onQueryTextSubmit function sounds more useful.
Now if we provide an overridden onQueryTextSubmit function, it'll be called when the user submits a
query for the app to search. And scrolling down looking at some of the other information,
basically the more detailed descriptions of this function, this onQueryTextSubmit. We can see there that it's
going to return true, down here,
if we're going to handle the query, which we are going to do. Now because this is an interface we have
to implement both functions.
So for the onQueryTextchange function, we're just going to return false to allow the default behavior
to be used, or the users typing in the search box.
So let's go back to Android Studio,
close down the log cat. Now I'm going to remove some of this logging in the onCreateOptionsMenu function, and set up the listeners
for the SearchView events that we need to respond to.
And this is exactly the same as the other listeners that we've implemented,
when doing things like checking for a button being clicked. We could get our search activity class to
implement both interfaces and just add the function to the class.
Now we took that approach earlier
so just to mix things up, I'm going to implement the two interfaces using anonymous classes, like we did
for the negate button in the calculator app challenge.
So I'll comment out
the log entries first, these three here, then after this line, the isIconified line.
Let's go ahead and do that. So we're going to do searchView,
question mark dot,
and it's going to be setOnQueryTextListener, and it's going to be an object colon SearchView dot OnQueryText
Listener. then we'll add a code block.
So we're going to call the setOnQueryTextListener function and pass an anonymous class that implements
the OnQueryTextListener interface.
Again, just like we did when setting the onClickListener for the negate button in the calculator challenge.
So this is a standard pattern when implementing listeners and the most common one to use when you want
to apply the listener to just a single object.
Alright so we've added that call, the to setOnQueryTextListener to that function.
So let's get Android Studio to generate the stubs using control
i, making sure my cursor's within the code block, and the reason we're getting this error is, I'm doing control i and it's
not working.
The reason for that is, I haven't actually closed this off properly, so we've got a parentheses here opening and I should've
actually added the closing parentheses, closing parentheses there.
Rather what I should be doing is closing the parentheses tag there, like so, and once we do
that, we should find that control i works, and you can see that it has worked.
So again I've done that to get Android Studio to generate the stubs. I'll select both and click OK.
So as I've mentioned we're not going to do anything in the onQueryTextchange function, so we can let that
return false.
Let's go ahead and do that.
So I'll get rid of the TODO then we'll just return false, because we're not dealing with that.
But the one that we do want to work on is this onQueryTextSubmit, which is only called back when the
user submits the search.
So we'll add some logging first, so Log.d parentheses TAG comma double quotes dot onQueryText
submit colon called.
So the only other kind I'm going to put in there other than the logging, is a call to the activity finish
function.
Now finish closes the activity and returns to whichever activity launched it. In our case that's MainActivity so
we can do finish parentheses to call that function,
then we're going to return true. It gets rid of that other error.
Now it's going to be useful to check what happens in MainActivity too.
So let's go back to MainActivity, override its resume function, and add some logging in there as well.
So MainActivity, come down to the bottom,
command o and we want onResume, which is this one here, onResume.
And what we want to do is leave the super call in there for now and just add some logging.
So log.d parentheses TAG comma double quotes dot onResume starts. Alright, so now that we've done that let's actually
have a look at how this behaves when we submit a search query.
So I'm going to run the app again.
OK I'm also going to open log cat,
and let's go back and have a look at our app, and what we want to do is search for some text. I'm going to
click on this search icon, I'm going to enter some text, marshmallow. Now if you press enter here you'll find that you won't
get the proper functionality, and that's because normally when you're actually using a real device,
you've come down here and clicked this button. So I'm going to tap this
right arrow
on the keypad down the bottom here.
And you can see that we've returned to main activity.
Now it's still showing these Oreo photos, because we haven't passed the query results back yet, but the
log cat is and should be interesting.
So I'm going to scroll back to the top, coming up to the top there.
And if you come down and have a bit of a look here, you can see we've got SearchActivity onCreate and onOptions
ItemSelected, both being called. Going down a little bit further,
we've got our onCreateOptionsMenu starting and closing. But a bit further down we've got our onQueryTextSubmit
called, and when that finishes and returns, scrolling down a bit further you can see MainActivity onResume
has been started as well.
So that's pretty interesting. The flow through our program is exactly what we want.
So all we have to do now before search activity finishes, is store the query text somewhere that Main
Activity can retrieve it from.
So let's work on that in the next video.