1 00:00:00,870 --> 00:00:03,760 Everything is good here except the last page of our story. 2 00:00:03,760 --> 00:00:06,060 If we try to go all the way to one of those right now then we'll get 3 00:00:06,060 --> 00:00:10,460 an exception because we don't have any data in our choice objects. 4 00:00:10,460 --> 00:00:12,610 Ugh, unhandled exceptions are the worst. 5 00:00:12,610 --> 00:00:13,110 Let's fix it. 6 00:00:14,440 --> 00:00:18,170 Hopefully you were able to take a look at the log and see what the error was. 7 00:00:18,170 --> 00:00:19,500 Let's go back to Android Studio and 8 00:00:19,500 --> 00:00:22,600 bring up the logcat view with the Android Monitor tab down here. 9 00:00:24,100 --> 00:00:27,370 And we can see pretty quickly here at the bottom that we're running into a null 10 00:00:27,370 --> 00:00:29,060 pointer exception. 11 00:00:29,060 --> 00:00:31,610 If we keep reading, we can find out that it's happening 12 00:00:31,610 --> 00:00:36,400 when we try to call getTextID on a null object here. 13 00:00:36,400 --> 00:00:39,170 So basically what is happening is when we get to one of our pages that 14 00:00:39,170 --> 00:00:43,070 doesn't have any choice objects, we're getting this null pointer exception. 15 00:00:43,070 --> 00:00:46,350 Remember, the last page of the story we decided won't have any choices. 16 00:00:46,350 --> 00:00:50,070 And instead have a boolean flag that says if it's the final page or not. 17 00:00:50,070 --> 00:00:51,210 Okay, let's fix it. 18 00:00:51,210 --> 00:00:54,040 Just for quick review, let's take a look at the page class. 19 00:00:54,040 --> 00:00:56,760 So let's close this, open up Page. 20 00:00:56,760 --> 00:00:59,860 And remember, we added this isFinalPage flag and 21 00:00:59,860 --> 00:01:02,525 some methods that tells us if it's a final page or not. 22 00:01:02,525 --> 00:01:06,470 And right now, if we scroll down here, it says that it is not being used. 23 00:01:06,470 --> 00:01:07,340 So let's use it. 24 00:01:07,340 --> 00:01:09,580 Let's go back to StoryActivity. 25 00:01:09,580 --> 00:01:13,790 So back here in our loadPage method is where we are setting all the information 26 00:01:13,790 --> 00:01:15,720 related to the choice buttons. 27 00:01:15,720 --> 00:01:19,110 So here, before line 61, let's add a new line, and 28 00:01:19,110 --> 00:01:24,380 a check if (page.isFinalPage()). 29 00:01:24,380 --> 00:01:26,860 And then inside here, if it's the final page, 30 00:01:26,860 --> 00:01:30,300 we want to execute some code to handle the buttons a little bit differently. 31 00:01:30,300 --> 00:01:33,080 If it's not final then we still want to do the rest of all this work. 32 00:01:33,080 --> 00:01:35,038 So let's make that the else block. 33 00:01:35,038 --> 00:01:37,938 We'll add else, curly brace, scroll down a little bit and 34 00:01:37,938 --> 00:01:39,971 I'll put another curly brace down here. 35 00:01:41,987 --> 00:01:45,520 And everything is indented automatically, thank you Android Studio. 36 00:01:45,520 --> 00:01:48,960 Actually, this loadPage method is getting a little bit long for my taste. 37 00:01:48,960 --> 00:01:50,860 It's doing too much work at this point. 38 00:01:50,860 --> 00:01:54,800 Let's refactor this else block into a new method just to load the buttons. 39 00:01:54,800 --> 00:01:58,162 So I'm going to select everything in here, click on refactor, 40 00:01:58,162 --> 00:02:02,960 extract, method. 41 00:02:02,960 --> 00:02:07,380 And let's call this loadButtons and click OK. 42 00:02:07,380 --> 00:02:10,260 All right, so coming back to our if statement, 43 00:02:10,260 --> 00:02:13,930 how exactly should we handle this situation of the final pages? 44 00:02:13,930 --> 00:02:15,630 Well, let's take a look at the mock ups again. 45 00:02:15,630 --> 00:02:17,920 Our designer and I talked about this specific scenario. 46 00:02:17,920 --> 00:02:20,510 And you can see here on the last two pages, 47 00:02:20,510 --> 00:02:24,440 we decided to have one button that just says, Play Again. 48 00:02:24,440 --> 00:02:27,700 Tapping on that will take the user back to the initial screen. 49 00:02:27,700 --> 00:02:30,520 So, to accomplish this, we are going to have to hide the top button, and 50 00:02:30,520 --> 00:02:34,000 then change the text on the bottom button, and change its target. 51 00:02:34,000 --> 00:02:35,380 Hiding the button is really easy. 52 00:02:35,380 --> 00:02:37,130 There are two different ways we can do it. 53 00:02:37,130 --> 00:02:39,140 The choice one button is the top button. 54 00:02:39,140 --> 00:02:43,690 So let's do choice1Button., and then we'll use 55 00:02:43,690 --> 00:02:47,200 a method called setVisibility, and you can guess what it does. 56 00:02:47,200 --> 00:02:49,620 It sets things to visible or invisible. 57 00:02:49,620 --> 00:02:51,290 Now the parameter isn't in parameter, but 58 00:02:51,290 --> 00:02:54,890 there are a couple different constants in the view class that we can use. 59 00:02:54,890 --> 00:02:58,120 So start typing view with a capital V, dot, and 60 00:02:58,120 --> 00:03:00,930 we have VISIBLE and INVISIBLE right here at the top. 61 00:03:00,930 --> 00:03:02,740 These two should be pretty obvious about what they do. 62 00:03:02,740 --> 00:03:06,010 They make the view either visible or invisible. 63 00:03:06,010 --> 00:03:08,050 There's another one, View.gone, 64 00:03:08,050 --> 00:03:10,340 that removes the view completely from it's parent. 65 00:03:10,340 --> 00:03:12,490 Which can effect how things are laid out on the screen. 66 00:03:12,490 --> 00:03:16,970 Especially if other views are positioned relative to the view that we call this on. 67 00:03:16,970 --> 00:03:18,900 So we wanna make sure we use the right one. 68 00:03:18,900 --> 00:03:21,390 We just wanna make this INVISIBLE. 69 00:03:21,390 --> 00:03:25,860 Next we want to set the text of the other button, the one that is still visible. 70 00:03:25,860 --> 00:03:29,550 So we can go choice2Button.setText and 71 00:03:29,550 --> 00:03:34,490 the text in this case is simply "PLAY AGAIN". 72 00:03:36,910 --> 00:03:37,490 And check this out. 73 00:03:37,490 --> 00:03:40,830 We can refactor from code directly into a string resource too. 74 00:03:40,830 --> 00:03:43,746 So it's highlighted in yellow for us, we can hit Alt + Enter, 75 00:03:43,746 --> 00:03:47,723 go down here to extract string resource, and for the resource name let's call this. 76 00:03:49,950 --> 00:03:52,969 Play_again_button_text. 77 00:03:52,969 --> 00:03:57,230 And there we go, it gets popped in here instead of the hard coded string. 78 00:03:57,230 --> 00:03:58,900 Okay, let's run this and see how it works. 79 00:04:00,490 --> 00:04:02,651 All right, let's keep testing different names. 80 00:04:05,242 --> 00:04:07,706 We'll have Brittney start the story this time, and 81 00:04:07,706 --> 00:04:10,410 let's go through to one of the end points. 82 00:04:10,410 --> 00:04:12,910 Explore the coordinates, and there we go, PLAY AGAIN. 83 00:04:12,910 --> 00:04:17,370 And if we tap on the button it takes us to another page, that's because the on click 84 00:04:17,370 --> 00:04:21,140 listener for the button was still pointing to the old target. 85 00:04:21,140 --> 00:04:22,930 Now if I tap on it here nothing will happen. 86 00:04:22,930 --> 00:04:25,370 All right, so we have two final things to take care of. 87 00:04:25,370 --> 00:04:27,600 We need to make this PLAY AGAIN button work correctly and 88 00:04:27,600 --> 00:04:31,870 take us back to the start, and we need to fix our back navigation. 89 00:04:31,870 --> 00:04:33,400 Check this out. If we hit the back button, 90 00:04:33,400 --> 00:04:35,370 instead of going back through the pages of a story, 91 00:04:35,370 --> 00:04:38,010 it's going to take us back to the beginning. 92 00:04:38,010 --> 00:04:39,110 That's not what we want. 93 00:04:39,110 --> 00:04:39,890 Let's break for a moment. 94 00:04:39,890 --> 00:04:43,090 And then when we come back, we will tackle the PLAY AGAIN button first.