1 00:00:02,250 --> 00:00:07,290 Now that we got the basics about navigation down, that we're able to pass data around, 2 00:00:07,350 --> 00:00:14,200 let's take a step back and focus on the app we're building which is of course not looking that great 3 00:00:14,190 --> 00:00:18,450 and let's focus on these category items here in the grid. 4 00:00:18,450 --> 00:00:21,210 We can tap them but obviously this is not an app 5 00:00:21,210 --> 00:00:27,200 you would like to use. Now to make that more usable in the categories screen here, 6 00:00:27,240 --> 00:00:30,400 I'll actually grab this item here, 7 00:00:30,490 --> 00:00:36,030 this touchable opacity, so this grid item and outsource this into a separate component, not something you 8 00:00:36,030 --> 00:00:43,210 must do but something you might want to consider doing simply to keep your components leaner and cleaner. 9 00:00:43,260 --> 00:00:49,890 For that in the components folder, I'll add a CategoryGridTile.js file, the name is of course totally 10 00:00:49,890 --> 00:00:56,400 up to you and in there, we need to import React from React, we'll certainly also need some stuff from 11 00:00:56,400 --> 00:01:03,990 React Native to build a component in there, namely we'll need touchable opacity of course, we'll need 12 00:01:04,020 --> 00:01:11,550 the view, we'll need text and we'll need a stylesheet so that we can also style this here and now we can 13 00:01:11,550 --> 00:01:14,900 create the category 14 00:01:14,940 --> 00:01:22,980 grid tile component here which receives some props. We will need a stylesheet here which I'll store 15 00:01:22,980 --> 00:01:31,110 in the styles constant and of course as always, we can thereafter export the component and inside of 16 00:01:31,110 --> 00:01:39,810 this component function, I'll return the jsx code I just cut out of the categories screen 17 00:01:39,810 --> 00:01:46,810 here. So in here, the touchable opacity set up, this grid item is set up but we'll have to change a couple 18 00:01:46,810 --> 00:01:52,560 of things. In the categories screen for example, I'm setting up the grid item style here. Now we could leave 19 00:01:52,560 --> 00:01:58,530 it here and kind of pass it into our grid tile and then merge it together there as you learned it but 20 00:01:58,530 --> 00:02:03,510 I will simply set up all the styling in the component itself because we'll only use the category grid 21 00:02:03,540 --> 00:02:09,810 tile in the grid on the categories screen. So I'll add the grid item style here to the stylesheet 22 00:02:09,870 --> 00:02:10,830 in this file, 23 00:02:10,860 --> 00:02:17,280 hence this works again, the onPress handler will not work yet, we'll fix this soon and now we can go 24 00:02:17,280 --> 00:02:24,720 back to the categories screen and of course, import our component. So import the category grid tile component 25 00:02:24,750 --> 00:02:28,250 there from the components folder and there, 26 00:02:28,290 --> 00:02:37,080 category grid tile and now simply return this here when we render a new item. 27 00:02:37,080 --> 00:02:38,990 Now of course like this it won't work, 28 00:02:39,000 --> 00:02:45,300 we need to forward some data into the grid tile for it to work correctly there and we also need to make 29 00:02:45,300 --> 00:02:53,880 sure that pressing this does navigate us. Now for that, I'll pass in the data which we need there which 30 00:02:53,880 --> 00:03:01,140 is the title, so that's itemData.item.title and that's now a prop we can use in the category 31 00:03:01,140 --> 00:03:08,910 grid tile and I also want to pass in another prop which passes in a function which we then can execute 32 00:03:08,940 --> 00:03:18,240 to navigate and I'll name this onSelect but you can name this whatever you want and in there, I just want 33 00:03:18,240 --> 00:03:26,700 to execute the code which I currently execute in onPress. So I'll cut this from here out of the category 34 00:03:26,700 --> 00:03:33,000 grid tile, move this back into the categories screen, into this function I pass to onSelect and now all 35 00:03:33,000 --> 00:03:38,700 we have to do is trigger onSelect from inside the category grid tile, that's of course a normal pattern 36 00:03:38,730 --> 00:03:48,110 you'd know from React. So back in the category grid tile, onPress can simply point at props onSelect 37 00:03:48,320 --> 00:03:52,390 to trigger the function that's passed in the onSelect prop. 38 00:03:52,550 --> 00:03:57,370 Now the title I'm outputting here also can just be props.title 39 00:03:57,380 --> 00:04:03,380 because we're getting this title prop as a prop on our category grid tile we're passing it here. 40 00:04:05,100 --> 00:04:11,460 With that, we split our component a little bit but of course now I also want to work on the styling a 41 00:04:11,460 --> 00:04:17,130 bit more. So back in the category grid tile, I for example want to use the color I'm setting up because 42 00:04:17,130 --> 00:04:21,580 every category gets a color stored in that color property here, 43 00:04:21,660 --> 00:04:28,620 so it would be nice to use that. Hence we can forward the category grid tile as well, forward color 44 00:04:28,620 --> 00:04:34,070 here, you can of course name this prop whatever you want on the item.color property 45 00:04:34,200 --> 00:04:40,950 and here, it has to be .color because we named the property color here in the model and now in a category 46 00:04:40,950 --> 00:04:44,360 grid tile, we can use that color to style this here. 47 00:04:44,460 --> 00:04:50,760 So how do then style this, how should this look like? By adding a style to the view we have inside of 48 00:04:50,760 --> 00:04:56,460 the touchable opacity because the touchable opacity component itself is invisible but the view 49 00:04:56,460 --> 00:05:01,250 isn't and there, we can pass in an object and set the background color here 50 00:05:01,260 --> 00:05:04,620 to props.color. 51 00:05:04,740 --> 00:05:08,860 Well let's see how that looks like, if we save that and we wait for this to reload, 52 00:05:08,950 --> 00:05:11,080 doesn't look too bad but it's too small, 53 00:05:11,110 --> 00:05:15,970 it should fill out the entire grid item and not just the row with the text in there. 54 00:05:16,180 --> 00:05:25,210 So to improve that, I'll actually have this inline style here but I'll merge this together into a surrounding 55 00:05:25,210 --> 00:05:33,770 object with another styling configuration which I set up in the stylesheet and I'll name this container, 56 00:05:33,790 --> 00:05:35,610 you can name it whatever you want, 57 00:05:35,680 --> 00:05:39,270 styles container, 58 00:05:39,620 --> 00:05:47,450 pull out all the key-value pairs in there as well so that we merge these styles here and now, container 59 00:05:47,540 --> 00:05:54,530 is a stylesheet object we can add down there and in here, we can set flex one to make sure that every 60 00:05:54,530 --> 00:05:58,880 item fills out all the space it gets and now this looks way better. 61 00:05:59,030 --> 00:06:02,330 Now I'm still not 100% happy, 62 00:06:03,080 --> 00:06:10,080 I want to add a little bit of a border radius here, let's say of 10 to have some rounded corners 63 00:06:10,400 --> 00:06:14,310 and of course, you can set up any styling you want here, you prefer, 64 00:06:14,570 --> 00:06:28,320 I will also set up a shadow color of black and a shadow opacity of .26 and a shadow offset of 65 00:06:28,380 --> 00:06:37,010 width 0, height 2 and a shadow radius of 10 and an elevation of 3, elevation for Android 66 00:06:37,020 --> 00:06:42,720 if you remember because these shadow properties only affect iOS, so that we get a little bit of this 67 00:06:42,810 --> 00:06:48,680 three-dimensional card look and of course as I mentioned, you can style this in whichever way you want. 68 00:06:48,690 --> 00:06:54,240 Now in addition, I want to make sure that this text here sits in the bottom right corner and has a little 69 00:06:54,240 --> 00:06:55,380 bit of padding around it 70 00:06:55,380 --> 00:07:00,960 of course, a little bit of spacing around it. So I'll add a little bit of padding here, 71 00:07:01,140 --> 00:07:08,730 let's say of 10 and now set justify content to flex-end, the flex direction in the container of course 72 00:07:08,730 --> 00:07:14,340 is top to bottom because it's column, so flex end will move this to the bottom here and now to also 73 00:07:14,340 --> 00:07:17,100 move it to the right on the horizontal axis, 74 00:07:17,220 --> 00:07:22,770 I set align items to flex end as well and this moves that to the end of the cross axis which is left 75 00:07:22,800 --> 00:07:29,900 to right in a normal view where you didn't change the flex direction. With that, we get this look which 76 00:07:29,930 --> 00:07:36,230 I'd say is better but of course, the text here, the text styling could also change and a little bit 77 00:07:36,230 --> 00:07:37,430 more padding might look good, 78 00:07:37,430 --> 00:07:43,100 maybe 15 but of course we can experiment with that and also one important side note, in this app I'll 79 00:07:43,100 --> 00:07:47,330 not focus on building a totally responsive experience here, 80 00:07:47,330 --> 00:07:53,450 I'll try to keep this short and concise because the main focus of this module of course is navigation, 81 00:07:53,690 --> 00:07:58,720 hence I'll not optimize this for all possible screens and platforms. 82 00:07:58,720 --> 00:08:01,200 This is something you can of course do as a practice, 83 00:08:01,250 --> 00:08:06,860 I'll not do adhere to not unnecessarily bloat this module, so I'll just set up some styling that looks 84 00:08:06,860 --> 00:08:08,450 good on these emulators. 85 00:08:08,450 --> 00:08:14,520 That being said, a little bit more padding might make sense and I also want to style the title here, 86 00:08:14,720 --> 00:08:17,740 hence I'll add let's say title style here, 87 00:08:17,810 --> 00:08:19,330 set up in the stylesheet, 88 00:08:19,430 --> 00:08:22,040 let's add it here and there, 89 00:08:22,040 --> 00:08:28,670 I want to use my font family, open sans bold which I can use of course because I'm registering it here 90 00:08:28,670 --> 00:08:39,110 in app.js, so open sans bold is added now here and maybe also change the font size a little 91 00:08:39,110 --> 00:08:42,870 bit to 22. We save 92 00:08:42,880 --> 00:08:45,340 this, this looks quite decent. 93 00:08:45,470 --> 00:08:48,560 Now there's one last thing which I want to do 94 00:08:49,750 --> 00:08:58,330 on my category grid tile, on the text here, I'll set the number of lines to 2 so that any text that would 95 00:08:58,330 --> 00:09:07,800 be longer than that actually just gets cut off which I think looks a bit nicer. And last but not least, 96 00:09:07,870 --> 00:09:14,560 you might notice that on Android for light and lovely, this is on the left here because it's broken 97 00:09:14,560 --> 00:09:19,670 into two lines, to make sure that this is also on the right, on the title here, 98 00:09:19,720 --> 00:09:27,900 I'll set text align to right to force this to be on the right. 99 00:09:28,000 --> 00:09:30,420 So let's wait for that to reload 100 00:09:33,070 --> 00:09:35,720 and now that's looking the way it should. 101 00:09:35,720 --> 00:09:38,020 Now that's not too bad here, 102 00:09:38,060 --> 00:09:43,850 now you might notice that the effect looks a bit strange if I tap an item here, we get this strange extra 103 00:09:43,850 --> 00:09:46,520 border around it. 104 00:09:46,550 --> 00:09:53,750 Now one thing I will still do here which is totally optional but still, I'll add it here, I'll add the platform 105 00:09:53,750 --> 00:10:00,710 API and also add touchable native feedback to actually use the ripple effect instead of touchable opacity 106 00:10:00,710 --> 00:10:02,090 if supported. 107 00:10:02,090 --> 00:10:11,600 So here, I'll have my touchable component which by default is touchable opacity 108 00:10:11,790 --> 00:10:21,510 but if platform.os equals Android and as you learned earlier in the course, the version is greater 109 00:10:21,510 --> 00:10:26,340 or equal than 21, then we know that touchable native feedback is supported, 110 00:10:26,340 --> 00:10:31,100 so then I'll set touchable component equal to touchable native feedback, like this. 111 00:10:31,290 --> 00:10:35,820 Use touchable component here instead of touchable opacity 112 00:10:35,820 --> 00:10:38,730 and with that, we should have a nice ripple effect on Android, on iOS 113 00:10:38,730 --> 00:10:41,000 we have the opacity effect which we want 114 00:10:41,130 --> 00:10:46,070 and on Android, we now have a ripple effect 115 00:10:46,080 --> 00:10:50,520 but styling is off now. 116 00:10:50,550 --> 00:10:57,830 This however is something we can fix by adding an extra view around this which receives our grid items 117 00:10:57,840 --> 00:11:01,840 style instead of the touchable component here 118 00:11:02,010 --> 00:11:08,220 and with that, we just need to add one extra style property on the touchable component and set flex 119 00:11:08,220 --> 00:11:08,700 one. 120 00:11:08,730 --> 00:11:10,430 I'm doing it with an inline style here 121 00:11:10,440 --> 00:11:16,770 quick and dirty, you could add a separate style in the stylesheet. With that it looks and feels the same 122 00:11:16,800 --> 00:11:17,800 on iOS 123 00:11:17,910 --> 00:11:21,370 and now also on Android, ripple effect is there. 124 00:11:21,370 --> 00:11:27,870 Now it's not using our rounded corners though, instead it renders a square or a rectangle 125 00:11:28,080 --> 00:11:31,100 and you also learned earlier how to fix that. To fix it, 126 00:11:31,110 --> 00:11:35,820 all we have to do is on the grid item, we add the border radius of 10 127 00:11:35,910 --> 00:11:42,930 and then we actually add overflow hidden to make sure that child items can't be rendered outside of 128 00:11:42,930 --> 00:11:43,950 that wrapping view 129 00:11:43,950 --> 00:11:49,010 which means that the ripple effect can't go outside of that rounded box. 130 00:11:49,020 --> 00:11:54,540 Now we have that look and that's the one adjustment I want to make here for different platforms 131 00:11:54,540 --> 00:11:58,050 and with that, that doesn't look too bad I'd say. 132 00:11:58,050 --> 00:12:04,110 Now of course, you can tweak the look of that, you can tweak the font size and so on, make that look really 133 00:12:04,110 --> 00:12:07,080 good on your devices you you're testing. 134 00:12:07,080 --> 00:12:11,940 I'm happy with this look and now it's really time to also render some recipes 135 00:12:11,970 --> 00:12:13,470 when we select a category here.