1
00:00:05,660 --> 00:00:11,320
Our app's nearly finished. We just want to provide some sort of notification to the user if no photos match

2
00:00:11,320 --> 00:00:12,630
their search query.

3
00:00:12,910 --> 00:00:18,570
Now the class that provides the data to the recycler view for displaying, is our flickr recycler view

4
00:00:18,640 --> 00:00:19,910
adapter class.

5
00:00:19,930 --> 00:00:24,310
Now that's the easiest place to add a notification if there's nothing to display.

6
00:00:24,540 --> 00:00:32,070
So let's open up that class.

7
00:00:32,100 --> 00:00:37,890
Now the data's provided to the recycler view when it calls the onBindViewHolder function.

8
00:00:37,950 --> 00:00:42,710
So all we have to do is check the list of photos and provide a suitably formatted holder

9
00:00:42,900 --> 00:00:49,720
if there's nothing to display. Let's go ahead and do that, so on bind view holder.

10
00:00:49,910 --> 00:00:52,670
So what we're going to do is add some code here at the start.

11
00:00:52,690 --> 00:01:02,560
We're going to put if parentheses photoList.isEmpty closing parentheses and open a codeblock, and I'm

12
00:01:02,570 --> 00:01:11,450
going to do a holder dot thumbnail dot setImageResource parentheses. And it's going to be R dot

13
00:01:11,470 --> 00:01:25,100
drawerable.placeholder, and then we're going to put holder.title.text equals, in two double quotes, No photos

14
00:01:25,620 --> 00:01:26,620
match your criteria,

15
00:01:29,250 --> 00:01:31,870
or match your search is probably easier to understand.

16
00:01:31,870 --> 00:01:39,770
Full stop backslash n backslash n Use the search icon to search for photos.

17
00:01:42,560 --> 00:01:48,150
Then what we're going to do is change this at the end of the code block, code block and I'm going to put an else, and then another code block.

18
00:01:48,610 --> 00:01:53,580
Then we're going to put the rest of the code up to, but not including, that final line of the holder dot title

19
00:01:53,580 --> 00:02:00,960
dot text. We can put all this code in that code block. Paste it in there like so.

20
00:02:01,890 --> 00:02:05,810
So basically that's now only going to be executed on the else.

21
00:02:05,880 --> 00:02:12,270
So we're testing the photos first, and if it's null or contains no photos, we set the image to the placeholder

22
00:02:12,270 --> 00:02:15,120
image and provide an informative message in the photo's

23
00:02:15,120 --> 00:02:20,550
title text view. But if there is data we just execute the same code as before.

24
00:02:20,780 --> 00:02:27,960
Now the set image resource function that I'm calling here on line 43, that loads the placeholder

25
00:02:27,960 --> 00:02:30,890
image from the resources and puts it into the image view.

26
00:02:31,040 --> 00:02:36,590
Now these backslash n characters, slash n slash n characters, they represent line breaks, and they're

27
00:02:36,600 --> 00:02:38,670
a simple way to format text.

28
00:02:38,700 --> 00:02:44,040
So Kotlin will replace the backslash n with a newline character when the text is displayed.

29
00:02:44,040 --> 00:02:47,810
Now we've got this warning over here about a hardcoded string,

30
00:02:47,970 --> 00:02:50,620
and we really should put that into a string resource.

31
00:02:50,790 --> 00:02:55,200
And as we saw in a previous video, Android Studio does make that very easy for us.

32
00:02:55,260 --> 00:03:01,700
So I'm just going to click on the text, like so, and do alt enter. Then I can come over here and use the lightbulb.

33
00:03:01,870 --> 00:03:05,730
Now we saw that working earlier but at the moment it's not working here.

34
00:03:06,000 --> 00:03:09,190
Now that's annoying but it's possibly not a bad thing.

35
00:03:09,430 --> 00:03:15,510
Over-reliance on the code generators can lead to us not understanding the code, and it is useful to be

36
00:03:15,510 --> 00:03:17,910
able to do things without using the code generator.

37
00:03:17,910 --> 00:03:20,270
And yes I'm trying to be positive about this.

38
00:03:20,310 --> 00:03:23,720
Sometimes things just don't work until Google releases a fix.

39
00:03:23,790 --> 00:03:28,130
Now I may be trying to be positive about this problem, but don't think I'm making light of it.

40
00:03:28,230 --> 00:03:32,440
When you're learning about all this, it can be very hard to work out if you're doing something wrong.

41
00:03:32,550 --> 00:03:34,920
Most of the time you will be doing something wrong.

42
00:03:35,040 --> 00:03:40,680
Bugs like this are actually quite rare, but when they do happen they can be very frustrating.

43
00:03:40,680 --> 00:03:45,280
Now one thing that may help is to focus on what you're really trying to achieve.

44
00:03:45,420 --> 00:03:50,700
Are we trying to get Android Studio to create a string resource for us, or do we just want to use a

45
00:03:50,700 --> 00:03:54,810
string resource. So it would be nice if Android Studio did it for us,

46
00:03:54,810 --> 00:03:56,060
but that's not our aim here.

47
00:03:56,160 --> 00:04:00,700
Our aim is to remove those warnings and get the text into a resource.

48
00:04:00,900 --> 00:04:04,110
So I'm not going to fight the tool here. We'll end up getting frustrated.

49
00:04:04,400 --> 00:04:08,690
Instead what I'm going to do is cut the text out of the code, leaving the speech marks, like

50
00:04:08,710 --> 00:04:16,790
so. Then I'm going to go to my strings.xml file, which is in our res folder and then the value

51
00:04:16,790 --> 00:04:17,740
subfolder.

52
00:04:18,060 --> 00:04:19,320
Double click on that.

53
00:04:19,320 --> 00:04:25,890
We're going to add it right at the end here, and we're going to put, open a string tag, so string name equals,

54
00:04:27,000 --> 00:04:28,530
and we'll call it empty underscore

55
00:04:28,690 --> 00:04:38,190
photo, close the tag and I'm going to paste in the string, and you saw that pasting in text that contains

56
00:04:38,260 --> 00:04:40,450
line breaks doesn't always work too well.

57
00:04:40,490 --> 00:04:46,610
So if you get the text split over several lines as I have, then just remove those extra lines.

58
00:04:46,880 --> 00:04:50,730
Basically just delete the line breaks and type in the slash in manually. So I'm going to go ahead and do that

59
00:04:52,590 --> 00:04:57,150
and put in my two backslash n's there like so, and we're good to go there.

60
00:04:57,400 --> 00:05:00,640
Now the next thing is to change the code to use the resource.

61
00:05:00,690 --> 00:05:05,810
So go back to our flickr recycler view adapter and to our onBindViewHolder method.

62
00:05:06,080 --> 00:05:08,510
So we want to change this code now to use the resource.

63
00:05:08,610 --> 00:05:14,280
Now we can't do that by signing directly to the text property, but we can pass a resource ID to the set

64
00:05:14,280 --> 00:05:19,080
text function, and that's easier than trying to get a resource object and extracting the string from

65
00:05:19,080 --> 00:05:27,810
the resources. Now that worked fine in an activity, but isn't so easy in our adapter class. So I'm going to type, inside

66
00:05:27,820 --> 00:05:28,980
the double quotes, holder dot

67
00:05:28,990 --> 00:05:38,280
title. We can't use dot text, we use dot setText, parentheses R.string.empty underscore

68
00:05:38,310 --> 00:05:39,040
photo.

69
00:05:39,450 --> 00:05:42,260
So even without Android Studio's help that wasn't too hard.

70
00:05:42,480 --> 00:05:44,930
There's really no excuse for hardcoding strings in your code.

71
00:05:44,940 --> 00:05:46,260
That's the bottom line.

72
00:05:46,290 --> 00:05:51,690
Alright so that should work, but the recycler view calls the getItemCount function to check if there's

73
00:05:51,690 --> 00:05:54,580
any data to display, and it does that a lot.

74
00:05:54,660 --> 00:06:01,860
So often in fact, that we commented out the logging in that function to keep the log cat a bit tidier.

75
00:06:02,090 --> 00:06:05,850
This is the getItemCount, you can see that we've commented out the logging.

76
00:06:05,850 --> 00:06:09,440
Now if there's no data, getItemCount will return 0,

77
00:06:09,670 --> 00:06:12,120
and the recycler view won't attempt to display anything.

78
00:06:12,460 --> 00:06:18,940
So we have to get our adapter to fib and tell he recycler view that there is at least one data item for it

79
00:06:18,940 --> 00:06:20,310
to display.

80
00:06:20,320 --> 00:06:23,460
Now the recycler view won't know or care that it's not a real flickr photo.

81
00:06:23,570 --> 00:06:27,300
It'll just know that there's one item, and will go ahead and display it.

82
00:06:27,310 --> 00:06:29,480
So let's actually add some code for that.

83
00:06:29,500 --> 00:06:30,330
So on this line here,

84
00:06:30,400 --> 00:06:33,920
all we're going to do is change the 0 to a 1.

85
00:06:34,750 --> 00:06:40,360
So now if no photos match the tags that we search for, we get the placeholder image and a message.

86
00:06:40,910 --> 00:06:45,850
Now that previous search for the Porsche driving monkeys should still be saved.

87
00:06:45,850 --> 00:06:48,060
So let's run the app and see what happens.

88
00:06:52,690 --> 00:06:57,690
So as you can see when I run the app, there still aren't any, and we're now getting this message and the placeholder

89
00:06:57,700 --> 00:06:58,420
image.

90
00:06:58,570 --> 00:07:01,710
So that's a better user experience than the blank screen we had before,

91
00:07:01,850 --> 00:07:04,370
and it's actually well worth the extra effort to code it.

92
00:07:04,420 --> 00:07:07,350
Alright so that's the end of this section.

93
00:07:07,470 --> 00:07:09,710
So we've covered a lot of ground in this section.

94
00:07:09,750 --> 00:07:15,360
We had to look at a different way to use async tasks to download data from the internet, then parse the json

95
00:07:15,360 --> 00:07:19,920
data rather than the xml that we used in the top 10 downloader app.

96
00:07:20,070 --> 00:07:25,260
Now the downloading and parsing involved using callback functions to notify the calling process that data

97
00:07:25,260 --> 00:07:26,730
was available.

98
00:07:26,730 --> 00:07:27,480
Now in the process,

99
00:07:27,490 --> 00:07:32,820
we created our own interfaces for classes to implement, so that they could reliably provide callback

100
00:07:32,820 --> 00:07:35,600
functions to the async classes.

101
00:07:35,600 --> 00:07:41,520
And then we looked at using the recycler view, and recvcler view adapter classes, to display the data in

102
00:07:41,520 --> 00:07:43,560
a scrolling list on the device.

103
00:07:44,010 --> 00:07:46,700
And in order to view the photos at a larger size,

104
00:07:46,860 --> 00:07:51,590
we had to use a gesture detector to work out what kind of input we were getting from the user.

105
00:07:51,900 --> 00:07:57,700
And we responded to taps and long presses, while still allowing scroll events to be handled by the system.

106
00:07:58,080 --> 00:08:02,910
We then had a good look at material design, before using it to style our flickr browser app,

107
00:08:03,030 --> 00:08:07,770
along material design lines. Now in order to do that we had to learn about themes and styles,

108
00:08:08,160 --> 00:08:11,630
and keeping a consistent look across different versions of Android.

109
00:08:12,110 --> 00:08:17,010
And we finished off by looking at using string resources, rather than hardcoding text into our code

110
00:08:17,160 --> 00:08:18,310
and layouts.

111
00:08:18,510 --> 00:08:23,460
And finally we added a search feature to the app so that we could download different photos by specifying

112
00:08:23,460 --> 00:08:25,230
different tags to select them.

113
00:08:25,320 --> 00:08:26,870
So again that's the end of this section.

114
00:08:26,920 --> 00:08:28,300
I'll see you in the next one.

