1 00:00:00,420 --> 00:00:02,672 We have a little problem with our layout. 2 00:00:02,672 --> 00:00:05,895 What happens if our story text here takes up more space than we 3 00:00:05,895 --> 00:00:07,900 currently have available? 4 00:00:07,900 --> 00:00:10,700 Watch how it looks if we switch to a smaller screen size. 5 00:00:10,700 --> 00:00:12,980 Let's go with the Nexus 4, for example. 6 00:00:12,980 --> 00:00:14,210 Okay, that still fits all right. 7 00:00:14,210 --> 00:00:18,090 But let's go down to something smaller like the old Nexus 1. 8 00:00:18,090 --> 00:00:22,664 Okay, you can see that our story text is now showing up behind our buttons that's 9 00:00:22,664 --> 00:00:23,660 no good. 10 00:00:23,660 --> 00:00:26,480 Whenever we have more content than we can fit on the screen, 11 00:00:26,480 --> 00:00:30,230 we need to decide what to display and how to bring the rest onto the screen. 12 00:00:30,230 --> 00:00:33,180 In this case, let's allow the user to scroll the page as they read. 13 00:00:34,220 --> 00:00:37,160 Android provides a special view group called a ScrollView. 14 00:00:37,160 --> 00:00:38,080 The way it works is this. 15 00:00:38,080 --> 00:00:41,090 We define the ScrollView as a rectangle on the screen. 16 00:00:41,090 --> 00:00:44,878 And then anything we put inside it as child views can then be scrolled 17 00:00:44,878 --> 00:00:47,940 horizontally, vertically, or in both directions. 18 00:00:47,940 --> 00:00:51,287 In this case, let's keep the buttons on the screen at all times, but 19 00:00:51,287 --> 00:00:55,310 let's allow the user to scroll both the image and the text as needed. 20 00:00:55,310 --> 00:00:58,650 We won't need this for most of the pages in the story on most phones. 21 00:00:58,650 --> 00:01:01,970 But again, we always wanna be proactive about how things will look for 22 00:01:01,970 --> 00:01:03,580 all types of devices. 23 00:01:03,580 --> 00:01:06,120 So let's get a scroll view from our palette. 24 00:01:06,120 --> 00:01:10,920 We can search for it, or go to Containers, and then here we find a ScrollView. 25 00:01:10,920 --> 00:01:14,340 And we want the Vertical ScrollView, not the Horizontal ScrollView. 26 00:01:14,340 --> 00:01:17,920 Although you can make a ScrollView scroll in both directions. 27 00:01:17,920 --> 00:01:21,510 So let's drag this onto the screen and go ahead and just drop it anywhere. 28 00:01:21,510 --> 00:01:24,810 Now before we even begin formatting this I do wanna warn you that 29 00:01:24,810 --> 00:01:28,950 laying things out with ScrollViews especially within a constrained layout 30 00:01:28,950 --> 00:01:30,500 can get a little frustrating. 31 00:01:30,500 --> 00:01:33,768 It's not necessarily hard but often I'll constrain or 32 00:01:33,768 --> 00:01:37,670 move something incorrectly and it will mess up a number of things. 33 00:01:37,670 --> 00:01:41,920 If you ever get really stuck like that it's usually easier just to start over. 34 00:01:41,920 --> 00:01:44,360 All right, so the first thing we want to do with our new 35 00:01:44,360 --> 00:01:45,880 scroll view is constrain all the edges. 36 00:01:45,880 --> 00:01:48,000 It's a little bit small I'll pull the right side over. 37 00:01:49,060 --> 00:01:51,310 Pull the left side back. 38 00:01:51,310 --> 00:01:53,525 Pull the bottom all the way to the bottom. 39 00:01:53,525 --> 00:01:55,045 Oops, that's not what I meant to do. 40 00:01:55,045 --> 00:01:57,971 Let's see, Command + Z undos that constraint and 41 00:01:57,971 --> 00:02:00,225 Ctrl + Z on Windows should do the same. 42 00:02:00,225 --> 00:02:02,657 I wanna pull the bottom on top of the buttons, 43 00:02:02,657 --> 00:02:05,670 not all the way to the bottom of the screen, there we go. 44 00:02:05,670 --> 00:02:09,630 And then I'll take the top all the way to the top. 45 00:02:09,630 --> 00:02:12,010 This is where a blueprint view can actually help. 46 00:02:12,010 --> 00:02:15,980 You can see the ScrollView while it's still kind of hard to see, but 47 00:02:15,980 --> 00:02:19,340 it's a little bit easier to see once you remove some of the clutter. 48 00:02:19,340 --> 00:02:22,028 As usual, we're going to switch the margins to 0 for 49 00:02:22,028 --> 00:02:27,940 everything, And now before we put anything in this ScrollView, 50 00:02:27,940 --> 00:02:32,420 it's important to note that a ScrollView can only have one direct child view. 51 00:02:32,420 --> 00:02:36,150 Now in our case, we want both the image and the text to scroll together. 52 00:02:36,150 --> 00:02:39,220 That means we need to group them together in some kind of view group, 53 00:02:39,220 --> 00:02:41,602 like a linear layout or a relative layout. 54 00:02:41,602 --> 00:02:44,680 This ScrollView if we scroll down to this component tree, this ScrollView 55 00:02:44,680 --> 00:02:49,140 has a linear layout already in it by default and that will work perfectly for 56 00:02:49,140 --> 00:02:53,010 us because we want these two views laid out one on top of the other. 57 00:02:53,010 --> 00:02:55,760 So now we're going to make use of this component tree. 58 00:02:55,760 --> 00:03:00,571 This shows us the hierarchy of our layout so at the root we have a constraint layout 59 00:03:00,571 --> 00:03:04,870 and within that we have these five views including our new ScrollView. 60 00:03:04,870 --> 00:03:07,800 Then if we keep drilling down, our ScrollView has the linear layout. 61 00:03:07,800 --> 00:03:10,885 So what we wanna do is move the storyImageView and 62 00:03:10,885 --> 00:03:13,530 the textView inside this linear layout. 63 00:03:13,530 --> 00:03:15,950 Actually, it's bothering me that we forgot to rename the ID. 64 00:03:15,950 --> 00:03:18,490 So let's click on textView, go up to the top. 65 00:03:18,490 --> 00:03:22,590 And let's call this storyTextView to make it more consistent. 66 00:03:22,590 --> 00:03:26,180 Okay, so now we can drag things directly in this component tree. 67 00:03:26,180 --> 00:03:30,350 And this is again, what I was cautioning about this can sometimes mess thing up. 68 00:03:30,350 --> 00:03:33,900 You might drag it into the wrong place or it'll break a constraint. 69 00:03:33,900 --> 00:03:36,560 Don't worry if any of that happens, you can either undo with the keyboard 70 00:03:36,560 --> 00:03:39,750 shortcuts or just rebuild your layout from scratch. 71 00:03:39,750 --> 00:03:43,270 So let's take storyImageView, pull it down here, and try and 72 00:03:43,270 --> 00:03:44,960 drop it on top of LinearLayout. 73 00:03:44,960 --> 00:03:46,570 And sure enough, there it goes. 74 00:03:46,570 --> 00:03:48,790 It's now within our LinearLayout. 75 00:03:48,790 --> 00:03:51,111 And storyTextView, we will do the same thing and 76 00:03:51,111 --> 00:03:53,510 we can maybe put it underneath the bottom there. 77 00:03:53,510 --> 00:03:56,703 Yup there goes now it's underneath, okay that's a good 78 00:03:56,703 --> 00:04:01,162 sign everything looks consistent over here, so our ScrollView is still taking 79 00:04:01,162 --> 00:04:05,283 up this rectangle from the top down to the top of the buttons and within this 80 00:04:05,283 --> 00:04:09,370 ScrollView we're now displaying ImageView followed by the textView. 81 00:04:09,370 --> 00:04:12,653 So I'm hesitant to run this yet without a little bit of review let's take a look 82 00:04:12,653 --> 00:04:15,250 at properties for the individual components. 83 00:04:15,250 --> 00:04:18,480 Okay, so here we have 0dp for both the width and the height. 84 00:04:18,480 --> 00:04:22,750 That's because a ScrollView always needs to calculate both of these dimensions. 85 00:04:22,750 --> 00:04:24,250 This is what we want to see here. 86 00:04:24,250 --> 00:04:26,330 There are some additional things we can customize, 87 00:04:26,330 --> 00:04:29,990 but I'm gonna check this box called fillViewport. 88 00:04:29,990 --> 00:04:33,800 This is somewhat similar to the adjust view bounds we've seen for images, but 89 00:04:33,800 --> 00:04:35,860 it doesn't actually change anything in our layout right here. 90 00:04:36,970 --> 00:04:39,830 Let's click on view all properties, and 91 00:04:39,830 --> 00:04:43,680 let's set the background of this ScrollView to white. 92 00:04:43,680 --> 00:04:47,255 I noticed when I was testing on the device that the background of the ScrollView is 93 00:04:47,255 --> 00:04:49,991 transparent, but the background of the textView was white so 94 00:04:49,991 --> 00:04:51,960 it looked a little bit funny. 95 00:04:51,960 --> 00:04:54,230 So down here we have a couple different backgrounds let's pull this over and 96 00:04:54,230 --> 00:04:57,460 see we want the regular background property here. 97 00:04:57,460 --> 00:04:59,600 And we can select white again just like we've been doing. 98 00:05:00,770 --> 00:05:04,508 And we haven't really explored over here yet but we can also take a look at 99 00:05:04,508 --> 00:05:08,882 the constraints here in this section in our properties so let's just double check. 100 00:05:08,882 --> 00:05:11,073 You gotta pull it even further to read but 101 00:05:11,073 --> 00:05:15,530 it says constrain the bottom to the top of our first button, good. 102 00:05:15,530 --> 00:05:18,020 Left and right to the parent and top also to the parent. 103 00:05:18,020 --> 00:05:20,230 Cool, so the constraints are how we want them to be. 104 00:05:21,310 --> 00:05:23,035 Next, let's review our LinearLayout. 105 00:05:24,130 --> 00:05:27,130 And I'm going to start by going back to the Fewer Properties view. 106 00:05:27,130 --> 00:05:29,740 So you probably haven't seen a LinearLayout yet 107 00:05:29,740 --> 00:05:31,670 in our courses here at Treehouse. 108 00:05:31,670 --> 00:05:35,860 It's similar to how a relative layout works, except it's more simple. 109 00:05:35,860 --> 00:05:38,300 We can only lay items out in a linear fashion, 110 00:05:38,300 --> 00:05:39,790 either horizontally or vertically. 111 00:05:39,790 --> 00:05:43,490 So what that means is, just like in this case, Vertically we have one item, and 112 00:05:43,490 --> 00:05:45,480 then when it's done the next is displayed, etc. 113 00:05:45,480 --> 00:05:48,290 And we could keep going for as many items as we wanted. 114 00:05:48,290 --> 00:05:50,784 So here we see that the orientation is set to vertical, 115 00:05:50,784 --> 00:05:52,910 although we could switch this to horizontal. 116 00:05:52,910 --> 00:05:57,052 And here, because it is no longer the direct child of a ConstraintLayout, 117 00:05:57,052 --> 00:05:58,910 we don't have any constraints. 118 00:05:58,910 --> 00:06:00,950 We have the old layout, width and height. 119 00:06:00,950 --> 00:06:04,100 We want it to match the parent, which means it will stretch from left to right 120 00:06:04,100 --> 00:06:06,240 and the height will wrap the content of what's inside, 121 00:06:06,240 --> 00:06:08,630 which in this case, is the image in the text view. 122 00:06:08,630 --> 00:06:11,140 Now what's the parent of the LinearLayout? 123 00:06:11,140 --> 00:06:12,500 That's right, it's the ScrollView itself. 124 00:06:12,500 --> 00:06:14,568 So the ScrollView is constrained, but 125 00:06:14,568 --> 00:06:19,300 then the LinearLayout is relative to how it's positioned in the ScrollView. 126 00:06:19,300 --> 00:06:22,260 We could put an optional ID up here, but we don't need that, so let's skip that. 127 00:06:24,490 --> 00:06:29,120 Now for the ImageView and textView themselves, let's switch to the XML view. 128 00:06:29,120 --> 00:06:31,190 All right, so we still have our buttons here. 129 00:06:31,190 --> 00:06:33,260 And then we have the ScrollView. 130 00:06:33,260 --> 00:06:34,790 And remember the order doesn't matter. 131 00:06:34,790 --> 00:06:38,030 At this point, we are within the ConstraintLayout. 132 00:06:38,030 --> 00:06:41,900 So as long as these children are constrained relative to each other, 133 00:06:41,900 --> 00:06:42,840 then we are okay. 134 00:06:43,870 --> 00:06:44,970 So here's our LinearLayout. 135 00:06:44,970 --> 00:06:46,810 Within it is our ImageView. 136 00:06:46,810 --> 00:06:48,780 It's got all the attributes of before. 137 00:06:48,780 --> 00:06:52,938 And we could actually get rid of the constraints now because it's no longer 138 00:06:52,938 --> 00:06:54,660 a child of the ContraintView. 139 00:06:54,660 --> 00:06:57,500 Same thing for the TextView let's get rid of these constraints. 140 00:06:58,730 --> 00:07:01,950 And just to make sure I'm not lying, let's look at the design view. 141 00:07:01,950 --> 00:07:03,830 Yep, still looks the same. 142 00:07:03,830 --> 00:07:07,310 So one more thing here in the TextView just like before we have 143 00:07:07,310 --> 00:07:09,630 a missing content description. 144 00:07:09,630 --> 00:07:13,920 So let's add a new line, and type android:contentDescription. 145 00:07:13,920 --> 00:07:16,686 And let's just call this Story page image, 146 00:07:16,686 --> 00:07:19,615 just to simply describe what it's there for. 147 00:07:19,615 --> 00:07:24,859 Now the next warning is about converting this to a string resource, 148 00:07:24,859 --> 00:07:29,827 so hit Alt + Enter for a quick fix, Strict string resource, and 149 00:07:29,827 --> 00:07:34,450 let's call this story_image_ content_description. 150 00:07:34,450 --> 00:07:38,897 Okay I think we're actually set here, let's click on design, and 151 00:07:38,897 --> 00:07:42,890 let's run this on the Pixel 5 emulator and see how it looks. 152 00:07:42,890 --> 00:07:47,414 Okay here we go, I'm gonna enter my name, start my adventure, That's right, 153 00:07:47,414 --> 00:07:50,647 we are only using placeholder data in our layout right now, 154 00:07:50,647 --> 00:07:53,460 that's why we don't see anything here. 155 00:07:53,460 --> 00:07:56,410 Well that's a perfect segway because coming up next we're going to see how 156 00:07:56,410 --> 00:08:00,400 to load the data for our first page for our story into our view here.