1
00:00:05,400 --> 00:00:10,860
Now you may have noticed that we had some warnings about hardcoded strings when we created the browse and  

2
00:00:10,940 --> 00:00:14,360
content underscore photo underscore details layouts.

3
00:00:14,480 --> 00:00:17,590
So let's actually have a look at the one in browse.xml.

4
00:00:17,850 --> 00:00:22,000
So I'm going to open up browse.xml in the res layout folder.

5
00:00:22,130 --> 00:00:26,750
Now at the top right of the designer pane is a little exclamation mark, now over here.

6
00:00:27,130 --> 00:00:30,310
Now that's normally grey, but it turns orange or red

7
00:00:30,350 --> 00:00:35,300
whenever there are errors or warnings, and if I hover over it you can see that it's changing to orange. And you can

8
00:00:35,300 --> 00:00:37,390
click on it in either case to find out what they are.

9
00:00:37,390 --> 00:00:43,610
So let's do that, and I'm just going to make a bit more space here to read it. Now we're interested in the one complaining

10
00:00:43,610 --> 00:00:45,860
about hardcoded text down the bottom there,

11
00:00:46,210 --> 00:00:52,680
and you can get more details by expanding the heading, using the triangle on it's left. And you can see there

12
00:00:52,680 --> 00:00:59,130
that it actually talks about the Hardcoded string "TextView" should use the @string resource.

13
00:00:59,140 --> 00:01:03,600
Now we don't display the text TextView, so we can ignore this one.

14
00:01:03,730 --> 00:01:06,710
The correct text is provided by the title of the photo

15
00:01:06,820 --> 00:01:13,630
when this layout's used, but what it does mean though, is that text shouldn't really be hardcoded into layouts or into

16
00:01:13,630 --> 00:01:15,080
code for that matter.

17
00:01:15,160 --> 00:01:17,250
And there are a couple reasons for this.

18
00:01:17,260 --> 00:01:23,020
The main one is that it makes it very hard to translate the app into different languages, but by using

19
00:01:23,020 --> 00:01:27,140
string resources, all the text for the app is in one place,

20
00:01:27,280 --> 00:01:30,620
and Android can use a different resource file for different languages.

21
00:01:31,030 --> 00:01:36,130
And what's better is that Android will do this automatically if you've provided a string resource for

22
00:01:36,130 --> 00:01:37,100
the user's language.

23
00:01:37,100 --> 00:01:38,520
I think that's pretty cool.

24
00:01:38,560 --> 00:01:44,560
Now you still do have to do the translation, and also create the alternative resource files, but that's a

25
00:01:44,560 --> 00:01:49,720
lot easier than modifying all the text in the app, and then distributing different language versions

26
00:01:49,720 --> 00:01:50,800
of your app.

27
00:01:50,830 --> 00:01:55,450
So in this video, we're going to go through and move all our text into a string resource so that you

28
00:01:55,450 --> 00:01:56,860
can see how it's done.

29
00:01:56,860 --> 00:02:01,780
So what we're going to do is close off this little triangle, and we're going to start with this top one, which

30
00:02:01,780 --> 00:02:04,830
is complaining that there's no content description image,

31
00:02:05,060 --> 00:02:11,050
there's no content description property for the image - Missing contentDescription attribute

32
00:02:11,050 --> 00:02:11,940
on image.

33
00:02:11,950 --> 00:02:18,250
Now the contentDescription is used by people who can't see the screen, and you use screen reading software

34
00:02:18,250 --> 00:02:21,970
to read out what's appearing on the screen while the app's running.

35
00:02:22,030 --> 00:02:27,950
It's a pretty cool feature that allows partially sighted people to use computers and mobile devices. Now

36
00:02:27,950 --> 00:02:33,370
Android Studio is encouraging us here to provide a description of the image, so the screen reader

37
00:02:33,370 --> 00:02:35,020
can read out the description.

38
00:02:35,080 --> 00:02:38,250
So let's go ahead and provide some text for the contentDescription,

39
00:02:38,440 --> 00:02:43,500
and at the same time, see how to store text in a string resource instead of hardcoding it.

40
00:02:43,660 --> 00:02:46,420
So select the ImageView, which should be selected if you've clicked over here,

41
00:02:46,450 --> 00:02:47,480
but I'm going to do that anyway.

42
00:02:47,750 --> 00:02:51,880
And you can see over here to the right, contentDescription, well that property's currently one of

43
00:02:51,880 --> 00:02:55,630
the ones that appears without expanding the properties pane.

44
00:02:55,630 --> 00:03:01,120
Now the description I'm going to use is downloaded Flickr photos, but instead of typing it as text in

45
00:03:01,120 --> 00:03:05,920
the property, I'm going to come over here and to the right of it, and click on the ellipses to get the

46
00:03:05,920 --> 00:03:07,160
resources dialogue.

47
00:03:07,480 --> 00:03:12,450
Now we haven't already stored this text anywhere, so I'm going to click on the Add new resource over here.

48
00:03:12,450 --> 00:03:19,700
I'm going to choose New string value. Now at this point we have to specify the text we want,

49
00:03:20,000 --> 00:03:24,800
which is the resource value, and we also have to provide a resource name to allow Android to find the

50
00:03:24,800 --> 00:03:25,750
string.

51
00:03:25,760 --> 00:03:34,010
So we'll use browse_image_description for the resource name, and

52
00:03:34,010 --> 00:03:40,490
for the value, we're going to use Downloaded Flickr photo.

53
00:03:41,540 --> 00:03:46,280
Now the file name's automatically selected. You can see here, down here, under File name, it's using strings dot

54
00:03:46,280 --> 00:03:47,840
xml in the values folder.

55
00:03:47,930 --> 00:03:48,680
So that's correct.

56
00:03:48,680 --> 00:03:54,700
At this point we now need to just click on OK. Now the contentDescription over here is now set

57
00:03:54,700 --> 00:04:00,310
to @string slash browse image, and you can't quite see the rest but it's actually browsse image description, which you'll

58
00:04:00,330 --> 00:04:06,040
recognize as the normal way of referring to a resource, rather, a string resource in this case. So @string

59
00:04:06,400 --> 00:04:08,350
slash and then the name.

60
00:04:08,530 --> 00:04:13,390
And now that we've actually done that, and saved that in the contentDescription attribute, we should

61
00:04:13,570 --> 00:04:18,910
now be able to see the text stored as a resource in the strings.xml file, and that's over here in the

62
00:04:18,910 --> 00:04:26,020
res and values folder. So I'm going to open that up, the values, and double click strings.xml, and you can see down the bottom

63
00:04:26,020 --> 00:04:31,420
now, string name equals browse_image_description, and our downloaded Flickr photo

64
00:04:31,840 --> 00:04:32,720
value.

65
00:04:33,190 --> 00:04:38,160
Now we also got the app name and the titles of our activities stored in here as well,

66
00:04:38,230 --> 00:04:43,150
and the wizard did that automatically when we created the activities. And remember that we changed the

67
00:04:43,150 --> 00:04:46,560
default title for the photo details activity,

68
00:04:46,590 --> 00:04:52,740
and there's the change line there, Photo Details. So placing text into string resources, rather than hard

69
00:04:52,750 --> 00:04:54,810
coding isn't a lot of extra work.

70
00:04:55,000 --> 00:05:00,820
It makes translating the app much easier. But the second reason for doing this is, it also allows text

71
00:05:00,820 --> 00:05:04,830
to be reused and that can make things more consistent across activities,

72
00:05:04,870 --> 00:05:09,550
when you refer to the same thing more than once. And it also saves memory because the same string

73
00:05:09,550 --> 00:05:11,750
doesn't have to be stored repeatedly.

74
00:05:11,760 --> 00:05:14,900
Alright so I'm going to close down strings.xml for now.

75
00:05:14,920 --> 00:05:19,750
Now we're not really bothered about that TextView text in browse.xml, so let's actually clear

76
00:05:19,750 --> 00:05:20,680
that warning.

77
00:05:20,910 --> 00:05:26,200
Now the obvious way to do that would be to create a string resource for the text, but we really don't

78
00:05:26,200 --> 00:05:28,210
want to use the string text view anymore.

79
00:05:28,420 --> 00:05:32,800
The only reason we've left it in this case, is so we can see where the TestView widget is on the

80
00:05:32,800 --> 00:05:33,600
design.

81
00:05:33,800 --> 00:05:40,330
Now to show you what I mean, I'm firstly going to make a bit more space here by closing down the project pane.

82
00:05:40,780 --> 00:05:43,000
I'm going to click on the TestView,

83
00:05:43,270 --> 00:05:48,450
and again, we're currently using the text there just so we can see where the TextView is on screen.

84
00:05:48,700 --> 00:05:54,210
So if I come over here to text, and actually delete that and then press enter to accept the change, and then

85
00:05:54,400 --> 00:06:00,250
click now somewhere else on the design to unselect the TestView. You can see that's a little bit

86
00:06:00,250 --> 00:06:05,540
hard to try and figure out where the TestView is,

87
00:06:05,570 --> 00:06:10,010
for example there. You can still see it in the blueprint, but in the design it's pretty hard to see.

88
00:06:10,580 --> 00:06:14,200
So having text in the app just so we can see where the widget it isn't ideal,

89
00:06:14,360 --> 00:06:17,750
and fortunately Android Studio provides another solution.

90
00:06:17,750 --> 00:06:24,530
So I want to go back and select the TextView title in the component tree. There's two text properties for

91
00:06:24,530 --> 00:06:25,040
it.

92
00:06:25,040 --> 00:06:29,300
You can see over here to the right, there's text, and the second one's got a spanner or wrench next to it.

93
00:06:29,310 --> 00:06:35,800
So text, text and this little wrench as you can see here. Now that property uses the tool's name space

94
00:06:36,050 --> 00:06:41,990
and won't be compiled into the app. Any property actually that uses the tool's namespace, is just for use

95
00:06:41,990 --> 00:06:45,710
by the Android Studio tools, such as this layout designer.

96
00:06:45,950 --> 00:06:51,650
So we can put some text in there and it'll show up in the designer, but won't be included in the finished

97
00:06:51,650 --> 00:06:52,160
app.

98
00:06:52,490 --> 00:06:58,190
So if I come over here to this second text, the one with the wrench, and type in Empty TextView

99
00:07:01,710 --> 00:07:06,250
and press enter, and you can see over here now that that becomes visible on

100
00:07:06,280 --> 00:07:12,610
the design. Now that tools text property won't be part of our compiled app again, but it's a useful

101
00:07:12,610 --> 00:07:18,620
way to check how things will look, without risking having some sample text in the finished app. So basically

102
00:07:18,640 --> 00:07:21,460
we can now see that TextView a bit more clearly in the design,

103
00:07:21,460 --> 00:07:25,550
and also we no longer have a warning down here about string resources.

104
00:07:25,690 --> 00:07:27,690
So we're going to leave this particular warning there for now.

105
00:07:27,700 --> 00:07:31,520
We're going to get back and have a look in our content_photo_details.

106
00:07:33,240 --> 00:07:38,280
Well actually I've got this open up here anyway so I'm going to click on that, but open that one, and come over here

107
00:07:38,340 --> 00:07:38,840
and have a look.

108
00:07:38,850 --> 00:07:40,330
We've got some warnings as well.

109
00:07:42,220 --> 00:07:47,170
There's basically warnings there as you can see, Hardcoded text for all three TestView widgets.

110
00:07:47,180 --> 00:07:52,160
Now we're not actually worried about them either, because that text should never appear on the screen, but we

111
00:07:52,160 --> 00:07:56,070
can clear the warnings by putting the text into the tools properly as we've just seen.

112
00:07:56,230 --> 00:08:01,220
And there's also a quick way to do that. So we can select all the text in the text property by clicking

113
00:08:01,220 --> 00:08:03,830
in the box. So if I open one,

114
00:08:04,100 --> 00:08:09,230
say the first one, and I'm going to do the same thing but just do it a little bit quicker. So basically by clicking on

115
00:08:09,230 --> 00:08:11,330
the box, that selects it as you can see there,

116
00:08:11,550 --> 00:08:14,960
and holding the mouse button down I should be able to drag that into the second box, like so,

117
00:08:14,960 --> 00:08:18,550
and release it, and you can see it's automatically moved that for us.

118
00:08:18,750 --> 00:08:23,990
Now that should have moved the TextView text but I've found it necessary to click back into the text property

119
00:08:23,990 --> 00:08:27,940
again, into the normal one, to prevent Android Studio from putting the text back in there.

120
00:08:27,950 --> 00:08:32,659
It may or may not be doing the same thing when you come to test this on your current version of Android

121
00:08:32,659 --> 00:08:35,990
Studio, but by clicking in there at the moment while it's blank,

122
00:08:35,990 --> 00:08:40,710
that seems to get Android Studio to record the fact that the text has been deleted.

123
00:08:40,850 --> 00:08:45,940
So for each of the TestViews, you want to drag the text from the text property down to the tools text property, again the one

124
00:08:46,110 --> 00:08:47,820
with the spanner as I've done here,

125
00:08:48,010 --> 00:08:53,500
and click back into text to make sure it stays blank. Then I'm going to do the next one now,

126
00:08:53,940 --> 00:09:00,590
photo title, drag it, and I'm going to click back in there to make sure the change has been reflected.

127
00:09:00,730 --> 00:09:09,070
And the third one, the tags, click, drag release, click back into the original one again. OK and just

128
00:09:09,070 --> 00:09:14,350
click somewhere else, then that warning disappears. So that's reduced the number of errors.

129
00:09:14,410 --> 00:09:15,580
and again, if this wasn't open you could

130
00:09:15,590 --> 00:09:20,560
click over here to reopen and see what those errors are, but I've still got that screen open down here, down the

131
00:09:20,560 --> 00:09:21,360
bottom.

132
00:09:21,360 --> 00:09:25,300
And there's a warning about the missing content description on the ImageView as well,

133
00:09:25,300 --> 00:09:29,590
so if we use the same string resource that we created for the content description this time.

134
00:09:29,590 --> 00:09:35,210
So we can click on the image, we just select it, then we can come over here to the ellipses, to the right of our

135
00:09:35,210 --> 00:09:38,920
content description.

136
00:09:38,980 --> 00:09:43,990
And we can come down here and choose the browse image description this time from the list of resources, and

137
00:09:43,990 --> 00:09:44,720
click OK.

138
00:09:46,460 --> 00:09:49,230
And you can see we've no longer got any errors showing up there now,

139
00:09:49,260 --> 00:09:55,760
and we're now using the same string resource to browse image description for both layouts.

140
00:09:55,810 --> 00:10:01,240
Now this may not be a great idea from an accessibility point of view, but in this app most of the information

141
00:10:01,240 --> 00:10:04,670
about the pictures come from the title and tags fields.

142
00:10:04,810 --> 00:10:08,190
So there's not really a lot more we can say about the image itself. Obviously

143
00:10:08,280 --> 00:10:13,380
though in other apps, you should give a bit of thought into what description you want to provide to people who

144
00:10:13,390 --> 00:10:15,180
can't actually see the image.

145
00:10:15,280 --> 00:10:18,760
So that's how you go about creating string resource values and how to use them.

146
00:10:18,760 --> 00:10:20,470
They are actually a bit more powerful than that though, and

147
00:10:20,480 --> 00:10:23,150
we're going to look at that in more detail in the next video.

