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.

