1 00:00:03,719 --> 00:00:06,939 G'day, welcome back everyone. 2 00:00:06,939 --> 00:00:09,870 So the challenge was to fix the app's About 3 00:00:09,870 --> 00:00:17,200 dialogue, to make the web links clickable in all versions of Android from API 17 up. 4 00:00:17,200 --> 00:00:21,240 I'm going to keep the layout changes to a minimum, and I won't be creating 5 00:00:21,240 --> 00:00:27,450 complete versions of the layout for API 21. If you've done that, and your solution 6 00:00:27,450 --> 00:00:33,210 works, then that's fine. If you have too many variants of your resource files, it 7 00:00:33,210 --> 00:00:38,730 makes maintenance harder. In my solution, I'm going to minimize the duplication as 8 00:00:38,730 --> 00:00:44,489 much as possible. I'll start with the string resources and we need to separate 9 00:00:44,489 --> 00:00:51,600 the text from the URL, for the pre API 21 devices. Android Studio lets you 10 00:00:51,600 --> 00:00:57,989 duplicate a line, using ctrl D, command D on a Mac, to create a duplicate 11 00:00:57,989 --> 00:01:04,599 of the about_weblink string resource to start with. 12 00:01:04,599 --> 00:01:06,760 The new string resource will be for 13 00:01:06,760 --> 00:01:18,240 devices running Android versions before API 21, but the name about_weblink_pre_21, for example, is a bit clumsy. 14 00:01:18,240 --> 00:01:29,340 So I'll rename the original to about_weblink_v21. 15 00:01:29,340 --> 00:01:34,170 It doesn't really matter, but naming things like that fits in better with the way 16 00:01:34,170 --> 00:01:38,730 Android deals with resources. The convention is to have a base version, 17 00:01:38,730 --> 00:01:43,770 then create a new resource for later Android versions, so I'm following that 18 00:01:43,770 --> 00:01:52,540 convention. We'll split our pre version 21 about_weblink into two parts. 19 00:01:55,280 --> 00:01:58,840 Cut the URL 20 00:01:58,840 --> 00:02:02,900 and then add another string resource. 21 00:02:18,640 --> 00:02:22,900 You may not have noticed, but in the layout designer we can change a TextView's text 22 00:02:22,900 --> 00:02:28,030 to be bold, but there's no option to underline it. I'm going to add 23 00:02:28,030 --> 00:02:39,100 a tag around the text. 24 00:02:39,100 --> 00:02:42,370 We saw that inan earlier video, and we used it in the 25 00:02:42,370 --> 00:02:47,980 about_credit string resource to embolden just parts of the text. 26 00:02:47,980 --> 00:02:54,820 One thing I haven't done, is added the https:// to the URL. 27 00:02:54,820 --> 00:02:59,660 As I hinted in the challenge description, that's going to crash the program. 28 00:02:59,660 --> 00:03:04,180 We could read through all the documentation to find out the exact exception that'll be 29 00:03:04,180 --> 00:03:10,840 thrown, but it's easier to just let the app crash, and get the exception from logcat. 30 00:03:10,840 --> 00:03:15,520 Okay, time to look at the about layout. 31 00:03:23,360 --> 00:03:28,380 We've got five TextViews in there, and we're interested in the 32 00:03:28,380 --> 00:03:36,300 about_weblink one. For API 21 and higher, that's fine as it is. For earlier 33 00:03:36,300 --> 00:03:41,540 Android versions, we're going to use two TextViews instead of one. 34 00:03:41,540 --> 00:03:47,430 The first TextView will contain the text: instructions available at, and the 35 00:03:47,430 --> 00:03:52,709 second one will hold the URL. You could duplicate the entire layout and create a 36 00:03:52,709 --> 00:03:58,980 v21 variant, and if you've done that, then that's fine. As I said, I prefer to keep 37 00:03:58,980 --> 00:04:03,989 duplication to a minimum, so that maintenance is easier. We know that one 38 00:04:03,989 --> 00:04:10,260 layout file can be included in another. That's what activity_main does, 39 00:04:10,260 --> 00:04:15,140 to keep the toolbar and floating action button separate from your widgets. 40 00:04:15,140 --> 00:04:20,959 It adds your widgets to the layout by including content_main. 41 00:04:20,959 --> 00:04:27,840 What I'm going to do here, is create two new layouts; one for API 21 and above, and one 42 00:04:27,840 --> 00:04:32,760 for the earlier versions. The API 21 layout will contain just a single 43 00:04:32,760 --> 00:04:38,700 TextView, and the earlier one will have two TextViews. Create a new layout 44 00:04:38,700 --> 00:04:46,620 resource file and call it about_web_url 45 00:04:56,500 --> 00:05:04,000 Make sure that the root element is a LinearLayout, and click OK. 46 00:05:04,000 --> 00:05:08,960 We could follow the normal steps of dragging TextViews onto the layout, then configuring 47 00:05:08,960 --> 00:05:13,550 the properties. But we've already got a TextView with all the properties set, 48 00:05:13,550 --> 00:05:20,180 in our About layout. I'll copy the XML for the about_weblink widget, 49 00:05:20,180 --> 00:05:26,960 and paste it into the XML for our new layout. In fact, I'll paste it twice, then change 50 00:05:26,960 --> 00:05:33,610 the ID of the second copy to about_url. 51 00:06:02,289 --> 00:06:06,849 As long as you paste the widgets between the opening and closing LinearLayout 52 00:06:06,849 --> 00:06:11,660 tags, this is much quicker than configuring all the properties again. 53 00:06:11,660 --> 00:06:19,200 Back in the designer, and make sure that the LinearLayout's set to vertical, with the 54 00:06:19,200 --> 00:06:25,300 layout_width as match_parent, and the layout_height set to wrap_content. 55 00:06:25,300 --> 00:06:30,900 We need to remove all the margins and padding from both the widgets. It's obvious why 56 00:06:30,909 --> 00:06:35,889 we don't want a top margin on the about_url widget. We want it to 57 00:06:35,889 --> 00:06:41,199 appear directly below about_weblink, so that the text looks like 58 00:06:41,199 --> 00:06:46,509 it's part of the same widget. What's not obvious, is why we're removing the top 59 00:06:46,509 --> 00:06:52,120 margin from about_weblink, and I'll come back to that later. 60 00:06:52,120 --> 00:06:56,520 I didn't discover that this was necessary, until after running the app for the 61 00:06:56,529 --> 00:07:02,849 first time, but I'm changing it now to save us having to come back in here. 62 00:07:26,580 --> 00:07:33,620 Both widgets also have the autoLink property set, so untick web. 63 00:07:43,710 --> 00:07:47,340 On older devices, we're going to use an onClickListener 64 00:07:47,340 --> 00:07:51,720 to launch the browser. That means we don't want autoLink. It doesn't work anyway, 65 00:07:51,720 --> 00:07:55,650 that's why we're doing this. There's a couple of other changes to 66 00:07:55,650 --> 00:08:02,580 make to about_url, which we can do in the reduced attributes pane. 67 00:08:02,580 --> 00:08:07,080 The first thing is the text. 68 00:08:07,080 --> 00:08:10,600 Use the symbol 69 00:08:10,600 --> 00:08:16,980 to choose the string, about_url. 70 00:08:16,980 --> 00:08:27,620 Next, is the textColor property. That should be our accent color, so that it's obviously clickable. 71 00:08:27,620 --> 00:08:32,419 Set textColor to colorAccent. 72 00:08:32,419 --> 00:08:34,559 You can use the symbol to choose the color, 73 00:08:34,559 --> 00:08:38,900 rather than remembering that resource ID. 74 00:08:39,260 --> 00:08:45,930 Notice that the text style lets us use bold, italic and small caps, but that there's 75 00:08:45,930 --> 00:08:50,100 no underline. That's why I added the tag in the 76 00:08:50,100 --> 00:08:54,500 string resource. There's a convention that links are underlined, 77 00:08:54,500 --> 00:09:00,560 and their email and web links were underlined on the API 25 emulator. 78 00:09:00,560 --> 00:09:02,860 We want to keep things consistent. 79 00:09:02,860 --> 00:09:08,480 Okay, we want an API 21 version of this layout, 80 00:09:08,480 --> 00:09:13,840 and Android Studio makes it very easy to create different versions of layouts. 81 00:09:13,840 --> 00:09:19,700 The button to do this is currently the second one in the designers toolbar, the one that 82 00:09:19,710 --> 00:09:23,520 looks like a device being rotated. It gives options to create a landscape 83 00:09:23,520 --> 00:09:29,940 variant, a version for devices with extra-large screens, and the one we want, 84 00:09:29,940 --> 00:09:38,500 Create Other. In the dialogue that appears, scroll down to Version, 85 00:09:40,300 --> 00:09:47,280 and use the top button to add an Android version-specific variant. The platform API level 86 00:09:47,280 --> 00:09:52,200 we want is 21, and click OK. 87 00:09:52,200 --> 00:09:59,200 That's created a v21/about_web_url layout, 88 00:09:59,200 --> 00:10:02,300 and we can check the name in the editor tab. 89 00:10:02,300 --> 00:10:09,140 All we have to do to make things work, is delete the about_url TextView, 90 00:10:09,140 --> 00:10:14,620 and change the resource string in about_weblink's text property 91 00:10:14,620 --> 00:10:20,160 to about_weblink_v21. However, as 92 00:10:20,160 --> 00:10:25,110 there's only going to be a single textView in this layout, we don't need to 93 00:10:25,110 --> 00:10:29,910 wrap it all in a LinearLayout. We'll be including this file in about.xml, 94 00:10:29,910 --> 00:10:35,490 which already has a LinearLayout as its root. If we use another one here, 95 00:10:35,490 --> 00:10:40,410 then we're nesting layouts unnecessarily, and as we know, nesting layout should be 96 00:10:40,410 --> 00:10:45,180 avoided for performance reasons. We had no choice with the first version of 97 00:10:45,180 --> 00:10:50,430 about_web_url, because you can't have two widgets in a 98 00:10:50,430 --> 00:10:54,112 layout, without putting them inside a single root. 99 00:10:54,112 --> 00:10:56,100 But here, all we need is one textView. 100 00:10:56,100 --> 00:11:01,460 It's worth pausing here and keeping things in perspective. 101 00:11:01,460 --> 00:11:07,740 We're creating a layout to be used in an About dialogue. We're not attempting to show 60 102 00:11:07,740 --> 00:11:12,420 of these every second, and if the user has to wait a few extra milliseconds for 103 00:11:12,420 --> 00:11:18,200 the dialogue to appear, or even a few hundredths of a second, they won't even notice. 104 00:11:18,200 --> 00:11:23,520 So, if you left a LinearLayout in and just deleted the second TextView, 105 00:11:23,520 --> 00:11:29,740 about_url in my example, then congratulations on completing the challenge. 106 00:11:29,740 --> 00:11:33,720 I'm going to make the layout as efficient as possible, so that if you 107 00:11:33,720 --> 00:11:38,250 use this approach where performance does matter, you'll have seen how to do it to 108 00:11:38,250 --> 00:11:43,200 avoid nesting where possible. It's also a chance to show you something you can do 109 00:11:43,200 --> 00:11:49,380 in Android Studio, that may not be obvious. So just to be clear, generating 110 00:11:49,380 --> 00:11:55,980 alternative variants of your layout, using that button, is fine most of the time. 111 00:11:55,980 --> 00:11:59,800 Occasionally, you'll want to create the variant from scratch, and that's what 112 00:11:59,800 --> 00:12:04,480 I'm going to do here. Close the layout file, 113 00:12:04,480 --> 00:12:14,180 then delete the v21 layout that we've just generated. 114 00:12:14,180 --> 00:12:20,240 Answer no if you're prompted to delete the alternative resource files for other 115 00:12:20,240 --> 00:12:26,640 configurations, otherwise we'll remove the other web_url layout file as well. 116 00:12:26,640 --> 00:12:32,540 Next, create a new layout resource file 117 00:12:35,580 --> 00:12:44,320 and call it about_web_url. 118 00:12:44,320 --> 00:12:45,640 That's the same name as we used 119 00:12:45,650 --> 00:12:52,070 for the pre API 21 version of the layout. Scroll down and at the end of the 120 00:12:52,070 --> 00:12:55,300 list of available qualifiers, 121 00:12:55,300 --> 00:13:00,220 use the top button to add version. As we did before, 122 00:13:00,220 --> 00:13:07,460 type 21 for the platform API level. Don't press Enter or you'll just create 123 00:13:07,460 --> 00:13:13,070 another LinearLayout. The bit that isn't obvious. is that you can use any widget 124 00:13:13,070 --> 00:13:17,930 as the root element. It doesn't have to be a layout. Change the root element 125 00:13:17,930 --> 00:13:25,200 from LinearLayout to TextView. 126 00:13:25,200 --> 00:13:29,240 Click OK 127 00:13:29,240 --> 00:13:32,000 and an API 21 version of the layout is 128 00:13:32,000 --> 00:13:38,560 created for us. This layout contains just a TextView, which is what we want. 129 00:13:38,560 --> 00:13:43,420 We just need to configure the TextView to match the one that it will replace, 130 00:13:43,420 --> 00:13:48,240 in the About dialogue. 131 00:13:48,240 --> 00:13:56,800 The ID will be about_weblink, 132 00:13:56,800 --> 00:14:03,980 and the layout_width should be match_parent. For the text property, use the symbol to choose our 133 00:14:03,980 --> 00:14:10,870 new about_weblink_21 string resource. 134 00:14:14,810 --> 00:14:20,840 The entire text is showing in the accent color, so we need to change text color to 135 00:14:20,840 --> 00:14:27,760 colorPrimary. 136 00:14:27,760 --> 00:14:32,520 We're just about done. The final change is to go into the 137 00:14:32,520 --> 00:14:42,380 all attributes section and set the autoLink property to web. 138 00:14:42,380 --> 00:14:48,440 Now we've got two versions of about_web_url; 139 00:14:48,440 --> 00:14:52,200 one containing two textViews inside a linear layout, 140 00:14:52,200 --> 00:14:55,960 and the other, the v21 version, just containing a 141 00:14:55,960 --> 00:14:58,300 single textView. 142 00:14:58,300 --> 00:15:04,320 Right, let's end this video here, and I'll see you in the next one.