1 00:00:05,070 --> 00:00:10,080 So I mentioned in the last video that the search framework doesn't do the searching for us. 2 00:00:10,170 --> 00:00:11,770 We have to write the code to do that. 3 00:00:11,940 --> 00:00:17,370 Now a common way for it to work is that the user answers the search criteria, and when they submit the 4 00:00:17,370 --> 00:00:22,280 query, the search framework launches another activity to deal with the searching. 5 00:00:22,560 --> 00:00:25,910 And that's why we had to set up the intent filter in the manifest. 6 00:00:26,100 --> 00:00:28,430 But we're going to be doing things slightly differently. 7 00:00:28,680 --> 00:00:35,640 So here, the same activity that contains the intent filter is the one displaying the SearchView widget. 8 00:00:35,640 --> 00:00:41,310 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 9 00:00:41,310 --> 00:00:46,410 the search terms back to our main activity, so that it can filter the flickr photos. 10 00:00:46,620 --> 00:00:51,630 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, 11 00:00:51,630 --> 00:00:52,840 which is running. 12 00:00:53,120 --> 00:00:55,590 So we go into our search. 13 00:00:55,670 --> 00:01:03,490 So what actually happens when I do try searching for something, so I'll search for Oreo and press enter. 14 00:01:03,590 --> 00:01:08,150 Basically it doesn't matter at this stage because we haven't written the code to deal with it, but nothing seems to 15 00:01:08,150 --> 00:01:08,910 have happened. 16 00:01:09,140 --> 00:01:10,620 But if we have a look at the log cat, 17 00:01:14,260 --> 00:01:21,470 we can see here, SearchActivity, so onCreateOptionsMenu and onCreate starts, and they're being called again 18 00:01:21,470 --> 00:01:24,200 because they're actually previously called further up. 19 00:01:24,200 --> 00:01:28,450 So basically they're called, once we press enter there to submit to search. 20 00:01:28,700 --> 00:01:34,670 So in other words, when we submit the search, Android search framework looks in the manifest for an activity 21 00:01:35,000 --> 00:01:41,030 that has the action dot search intent filter and launches that activity, which in this case is our Search 22 00:01:41,030 --> 00:01:41,960 Activity. 23 00:01:41,960 --> 00:01:47,690 Now as I said, a common approach is to have the SearchView widget in one activity, say MainActivity, and 24 00:01:47,690 --> 00:01:51,430 have it launch another activity to perform the actual search. 25 00:01:51,740 --> 00:01:56,810 But the approach we're going to use here is to respond to callback events from the SearchView widget, 26 00:01:57,050 --> 00:02:02,540 to retrieve the search terms that our user enters, then pass them back to MainActivity. 27 00:02:02,540 --> 00:02:07,820 Now we're not going to use the intent filter in the manifest, but we still have to include it, because 28 00:02:07,820 --> 00:02:12,440 the search manager needs it in order to get the searchable info for the activity. 29 00:02:12,710 --> 00:02:18,770 So what we're going to do instead, is respond to events generated by the SearchView widget to handle the 30 00:02:18,770 --> 00:02:22,970 user's search query, and that'll prevent this undesirable behavior. 31 00:02:23,180 --> 00:02:28,120 We're submitting a search just launched, a search activity again as you saw. Alright so documentation 32 00:02:28,130 --> 00:02:30,100 time again. Let's check out some documentation. 33 00:02:34,750 --> 00:02:40,510 Let's have a look at the events that SearchView allows us to respond to, and right away you can see 34 00:02:40,510 --> 00:02:45,970 that the summary's pretty helpful here. Scrolling down here you can see that there's an OnCloseListener, and 35 00:02:45,970 --> 00:02:48,160 an OnQueryTextListener as 36 00:02:48,160 --> 00:02:50,140 well. Now they both sound promising, 37 00:02:50,140 --> 00:02:52,350 so I'm going to follow the links to see how to use them. 38 00:02:52,350 --> 00:02:53,710 Let's have a look at onCloseListener, 39 00:02:56,500 --> 00:03:01,080 and you can see that onCloseListener defines a single function, onClose, 40 00:03:01,270 --> 00:03:03,330 that's called when the user closes a SearchView. 41 00:03:03,940 --> 00:03:10,560 Now if we override that we should return false, to retain the default behavior of clearing the text field and 42 00:03:10,580 --> 00:03:11,390 dismissing it, 43 00:03:11,560 --> 00:03:13,510 closing the SearchView down in other words. 44 00:03:13,850 --> 00:03:17,980 OK, so that sounds like a way to deal with the user cancelling the search, 45 00:03:18,090 --> 00:03:19,900 so let's go back and follow the other link. 46 00:03:23,250 --> 00:03:30,690 So have a look for this OnQueryTextListener, and you can see that OnQueryTextListener defines two 47 00:03:30,690 --> 00:03:35,770 functions. We can monitor every change the user makes to the query text as they type, 48 00:03:35,880 --> 00:03:40,590 but for our purpose, the onQueryTextSubmit function sounds more useful. 49 00:03:40,660 --> 00:03:46,140 Now if we provide an overridden onQueryTextSubmit function, it'll be called when the user submits a 50 00:03:46,140 --> 00:03:51,420 query for the app to search. And scrolling down looking at some of the other information, 51 00:03:51,420 --> 00:03:57,210 basically the more detailed descriptions of this function, this onQueryTextSubmit. We can see there that it's 52 00:03:57,210 --> 00:03:59,450 going to return true, down here, 53 00:03:59,680 --> 00:04:05,220 if we're going to handle the query, which we are going to do. Now because this is an interface we have 54 00:04:05,220 --> 00:04:07,040 to implement both functions. 55 00:04:07,100 --> 00:04:12,900 So for the onQueryTextchange function, we're just going to return false to allow the default behavior 56 00:04:12,900 --> 00:04:15,970 to be used, or the users typing in the search box. 57 00:04:16,300 --> 00:04:17,610 So let's go back to Android Studio, 58 00:04:20,279 --> 00:04:27,720 close down the log cat. Now I'm going to remove some of this logging in the onCreateOptionsMenu function, and set up the listeners 59 00:04:27,720 --> 00:04:30,530 for the SearchView events that we need to respond to. 60 00:04:30,720 --> 00:04:34,180 And this is exactly the same as the other listeners that we've implemented, 61 00:04:34,350 --> 00:04:39,000 when doing things like checking for a button being clicked. We could get our search activity class to 62 00:04:39,030 --> 00:04:42,970 implement both interfaces and just add the function to the class. 63 00:04:43,080 --> 00:04:44,490 Now we took that approach earlier 64 00:04:44,490 --> 00:04:50,250 so just to mix things up, I'm going to implement the two interfaces using anonymous classes, like we did 65 00:04:50,250 --> 00:04:53,390 for the negate button in the calculator app challenge. 66 00:04:53,430 --> 00:04:54,340 So I'll comment out 67 00:04:54,340 --> 00:05:01,690 the log entries first, these three here, then after this line, the isIconified line. 68 00:05:02,370 --> 00:05:06,820 Let's go ahead and do that. So we're going to do searchView, 69 00:05:09,120 --> 00:05:11,070 question mark dot, 70 00:05:11,280 --> 00:05:24,630 and it's going to be setOnQueryTextListener, and it's going to be an object colon SearchView dot OnQueryText 71 00:05:24,630 --> 00:05:29,320 Listener. then we'll add a code block. 72 00:05:29,320 --> 00:05:34,540 So we're going to call the setOnQueryTextListener function and pass an anonymous class that implements 73 00:05:34,540 --> 00:05:37,290 the OnQueryTextListener interface. 74 00:05:37,390 --> 00:05:42,680 Again, just like we did when setting the onClickListener for the negate button in the calculator challenge. 75 00:05:42,910 --> 00:05:47,680 So this is a standard pattern when implementing listeners and the most common one to use when you want 76 00:05:47,680 --> 00:05:51,060 to apply the listener to just a single object. 77 00:05:51,370 --> 00:05:55,590 Alright so we've added that call, the to setOnQueryTextListener to that function. 78 00:05:55,710 --> 00:05:59,150 So let's get Android Studio to generate the stubs using control 79 00:05:59,330 --> 00:06:05,790 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 80 00:06:05,800 --> 00:06:06,340 not working. 81 00:06:06,330 --> 00:06:11,100 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 82 00:06:11,170 --> 00:06:16,600 actually added the closing parentheses, closing parentheses there. 83 00:06:16,600 --> 00:06:21,490 Rather what I should be doing is closing the parentheses tag there, like so, and once we do 84 00:06:21,550 --> 00:06:26,110 that, we should find that control i works, and you can see that it has worked. 85 00:06:26,150 --> 00:06:31,160 So again I've done that to get Android Studio to generate the stubs. I'll select both and click OK. 86 00:06:31,660 --> 00:06:36,610 So as I've mentioned we're not going to do anything in the onQueryTextchange function, so we can let that 87 00:06:36,610 --> 00:06:37,680 return false. 88 00:06:37,840 --> 00:06:39,970 Let's go ahead and do that. 89 00:06:39,970 --> 00:06:46,130 So I'll get rid of the TODO then we'll just return false, because we're not dealing with that. 90 00:06:46,690 --> 00:06:52,240 But the one that we do want to work on is this onQueryTextSubmit, which is only called back when the 91 00:06:52,240 --> 00:06:54,350 user submits the search. 92 00:06:54,490 --> 00:07:03,480 So we'll add some logging first, so Log.d parentheses TAG comma double quotes dot onQueryText 93 00:07:03,500 --> 00:07:07,350 submit colon called. 94 00:07:09,160 --> 00:07:13,420 So the only other kind I'm going to put in there other than the logging, is a call to the activity finish 95 00:07:13,420 --> 00:07:14,140 function. 96 00:07:14,280 --> 00:07:20,440 Now finish closes the activity and returns to whichever activity launched it. In our case that's MainActivity so 97 00:07:20,590 --> 00:07:24,140 we can do finish parentheses to call that function, 98 00:07:24,210 --> 00:07:26,930 then we're going to return true. It gets rid of that other error. 99 00:07:27,280 --> 00:07:30,540 Now it's going to be useful to check what happens in MainActivity too. 100 00:07:30,730 --> 00:07:35,620 So let's go back to MainActivity, override its resume function, and add some logging in there as well. 101 00:07:35,800 --> 00:07:38,020 So MainActivity, come down to the bottom, 102 00:07:41,070 --> 00:07:47,250 command o and we want onResume, which is this one here, onResume. 103 00:07:48,260 --> 00:07:51,360 And what we want to do is leave the super call in there for now and just add some logging. 104 00:07:51,360 --> 00:08:02,700 So log.d parentheses TAG comma double quotes dot onResume starts. Alright, so now that we've done that let's actually 105 00:08:02,700 --> 00:08:05,900 have a look at how this behaves when we submit a search query. 106 00:08:06,330 --> 00:08:07,380 So I'm going to run the app again. 107 00:08:10,460 --> 00:08:13,520 OK I'm also going to open log cat, 108 00:08:13,680 --> 00:08:19,120 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 109 00:08:19,120 --> 00:08:26,460 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 110 00:08:26,460 --> 00:08:31,830 get the proper functionality, and that's because normally when you're actually using a real device, 111 00:08:32,130 --> 00:08:34,630 you've come down here and clicked this button. So I'm going to tap this 112 00:08:35,049 --> 00:08:35,610 right arrow 113 00:08:35,700 --> 00:08:37,400 on the keypad down the bottom here. 114 00:08:38,309 --> 00:08:40,970 And you can see that we've returned to main activity. 115 00:08:40,980 --> 00:08:47,210 Now it's still showing these Oreo photos, because we haven't passed the query results back yet, but the 116 00:08:47,250 --> 00:08:49,220 log cat is and should be interesting. 117 00:08:49,270 --> 00:08:53,250 So I'm going to scroll back to the top, coming up to the top there. 118 00:08:53,470 --> 00:08:59,460 And if you come down and have a bit of a look here, you can see we've got SearchActivity onCreate and onOptions 119 00:08:59,460 --> 00:09:02,640 ItemSelected, both being called. Going down a little bit further, 120 00:09:02,640 --> 00:09:10,330 we've got our onCreateOptionsMenu starting and closing. But a bit further down we've got our onQueryTextSubmit 121 00:09:10,330 --> 00:09:15,730 called, and when that finishes and returns, scrolling down a bit further you can see MainActivity onResume 122 00:09:15,730 --> 00:09:17,330 has been started as well. 123 00:09:17,770 --> 00:09:22,020 So that's pretty interesting. The flow through our program is exactly what we want. 124 00:09:22,300 --> 00:09:28,180 So all we have to do now before search activity finishes, is store the query text somewhere that Main 125 00:09:28,180 --> 00:09:29,890 Activity can retrieve it from. 126 00:09:30,010 --> 00:09:31,960 So let's work on that in the next video.