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.