1 00:00:00,084 --> 00:00:02,584 (light music) 2 00:00:05,330 --> 00:00:07,920 All right, so before we continue with the app 3 00:00:07,920 --> 00:00:10,210 there's a few small typos that I've made, 4 00:00:10,210 --> 00:00:12,090 I wanna actually correct those. 5 00:00:12,090 --> 00:00:14,563 Firstly, in the app provider class, 6 00:00:15,840 --> 00:00:18,510 in the delete function right down the end, 7 00:00:18,510 --> 00:00:20,170 I've got that on the screen here, 8 00:00:20,170 --> 00:00:22,400 I accidentally left in the word update 9 00:00:22,400 --> 00:00:25,483 as the logging tag, so I'm gonna change that to delete. 10 00:00:27,570 --> 00:00:30,620 And also the other thing that I want to fix 11 00:00:30,620 --> 00:00:34,700 is in fragment main, fragment_main.xml, 12 00:00:34,700 --> 00:00:35,960 you've might've seen this at the time 13 00:00:35,960 --> 00:00:37,870 and I think I actually put an annotation on the video 14 00:00:37,870 --> 00:00:40,390 about it, but we'll click in and have a look. 15 00:00:40,390 --> 00:00:43,000 I actually left in the text for Hello World 16 00:00:43,000 --> 00:00:45,940 and I actually pasted, I created a string resource 17 00:00:45,940 --> 00:00:49,490 not for the main text, but for the second attribute 18 00:00:49,490 --> 00:00:52,380 which is actually used just to show something 19 00:00:52,380 --> 00:00:54,670 where there isn't anything on the screen for develop, 20 00:00:54,670 --> 00:00:56,850 for development use in other words. 21 00:00:56,850 --> 00:00:59,010 So I'm gonna copy that, I'm gonna paste that, 22 00:00:59,010 --> 00:01:01,320 sorry, cut that out of there, I should say, not copy. 23 00:01:01,320 --> 00:01:04,030 I'm gonna delete the Hello World and we're gonna paste that 24 00:01:04,030 --> 00:01:06,740 there into our regular text property. 25 00:01:06,740 --> 00:01:08,760 And now that's actually set up correctly 26 00:01:08,760 --> 00:01:10,710 and we won't have Hello World showing on the screen. 27 00:01:10,710 --> 00:01:13,230 All right, so I can close that down for now, 28 00:01:13,230 --> 00:01:15,600 we've done that, and closing that provider as well. 29 00:01:15,600 --> 00:01:18,600 Now there's also been another update of the content plugin, 30 00:01:18,600 --> 00:01:21,220 so I wanna show you that there is a way of actually checking 31 00:01:21,220 --> 00:01:24,480 whether a new plugin has been updated in IntelliJ 32 00:01:24,480 --> 00:01:26,590 and you can come up here to tools when you're in the project 33 00:01:26,590 --> 00:01:28,480 and the project is opened. 34 00:01:28,480 --> 00:01:30,620 Come down to Kotlin and you can actually select 35 00:01:30,620 --> 00:01:33,040 Configure Kotlin Plugin Updates, 36 00:01:33,040 --> 00:01:34,750 and when you do that it'll usually tell you 37 00:01:34,750 --> 00:01:37,040 whether there's a new version, and you can just click on 38 00:01:37,040 --> 00:01:38,680 recheck now if you need it too, 39 00:01:38,680 --> 00:01:43,160 but it actually says here that a new version, 1.2.51, 40 00:01:43,160 --> 00:01:45,260 is available so I'm gonna instal that 41 00:01:45,260 --> 00:01:46,990 noting that this will often come up 42 00:01:46,990 --> 00:01:49,580 and actually prompt you to be updated anyway, 43 00:01:49,580 --> 00:01:50,720 but I'm just showing you how you can come there 44 00:01:50,720 --> 00:01:53,800 and check it yourself, so I'm going to download that plugin 45 00:01:53,800 --> 00:01:56,210 remembering that there's a two-step process here. 46 00:01:56,210 --> 00:01:59,020 At the moment the updated version of the plugin 47 00:01:59,020 --> 00:02:01,460 won't be updated in our built Gradle files, 48 00:02:01,460 --> 00:02:03,600 we'll need to actually go through and do that, 49 00:02:03,600 --> 00:02:05,660 and you can see there that it's saying that 50 00:02:05,660 --> 00:02:08,550 the plugin will be activated after the restart. 51 00:02:08,550 --> 00:02:09,430 So I'm just going to do that, 52 00:02:09,430 --> 00:02:11,080 I'm gonna restart Android Studio. 53 00:02:13,510 --> 00:02:15,360 And eventually that'll fix this, so I suspect so 54 00:02:15,360 --> 00:02:17,530 that the Gradle files will be updated automatically 55 00:02:17,530 --> 00:02:20,320 or you'll be prompted in some way if you get it updated, 56 00:02:20,320 --> 00:02:21,780 but at the moment if we go in there now 57 00:02:21,780 --> 00:02:24,750 to our Project: TastTimer, 58 00:02:24,750 --> 00:02:27,580 you can see that there's no indication that on here, 59 00:02:27,580 --> 00:02:29,680 in here where at the moment that there's been an update, 60 00:02:29,680 --> 00:02:33,020 but here it's now telling us it's an outdated Kotlin Runtime 61 00:02:33,020 --> 00:02:35,650 so in other words, it hasn't prompted us to update 62 00:02:35,650 --> 00:02:38,380 the plugin automatically, but it is now smart enough 63 00:02:38,380 --> 00:02:40,000 to know that there's a new version. 64 00:02:40,000 --> 00:02:41,020 So here it's actually saying it, 65 00:02:41,020 --> 00:02:43,210 we can just expand it and have a look. 66 00:02:43,210 --> 00:02:44,500 No surprises there because I've only 67 00:02:44,500 --> 00:02:47,160 just installed it, 1.2.51, 68 00:02:47,160 --> 00:02:49,260 if I click, care to click up that Runtime 69 00:02:49,260 --> 00:02:51,560 that's the part I'm talking about that's not updated 70 00:02:51,560 --> 00:02:54,150 automatically, so in this case we're just gonna go in there, 71 00:02:54,150 --> 00:02:57,333 change the 50 to a 51, do a resync, 72 00:02:58,282 --> 00:02:59,150 and that will then update it 73 00:02:59,150 --> 00:03:00,750 to the latest version of Kotlin. 74 00:03:02,810 --> 00:03:06,650 And sometimes it might be necessary to do a complete rebuild 75 00:03:06,650 --> 00:03:09,310 and you can come up to build and select rebuild project 76 00:03:09,310 --> 00:03:11,650 if you need to do that, that'll be if you get an error 77 00:03:11,650 --> 00:03:14,640 or something weird happens, and on rare occasions also 78 00:03:14,640 --> 00:03:16,400 you're making errors in a project that worked 79 00:03:16,400 --> 00:03:18,170 before the update and you may have to go 80 00:03:18,170 --> 00:03:20,090 up into the file menu up here 81 00:03:20,090 --> 00:03:22,933 and select Invalidate Caches/Restart. 82 00:03:25,070 --> 00:03:27,580 And you click on Validate and Restart which I won't do now 83 00:03:27,580 --> 00:03:29,540 unless I get errors, and that's another way 84 00:03:29,540 --> 00:03:30,630 of actually fixing things if you get 85 00:03:30,630 --> 00:03:31,630 some weird errors after. 86 00:03:31,630 --> 00:03:35,317 So I'm gonna click on Cancel to get out of that. 87 00:03:35,317 --> 00:03:36,210 So you can see, in my case, 88 00:03:36,210 --> 00:03:38,440 there hasn't been any errors added. 89 00:03:38,440 --> 00:03:40,960 There's no more notes there about being outdated, 90 00:03:40,960 --> 00:03:43,330 we can close that, close down the output 91 00:03:43,330 --> 00:03:44,163 down the bottom there, 92 00:03:44,163 --> 00:03:46,530 and let's continue on with the project now. 93 00:03:46,530 --> 00:03:48,040 All right, so we've created our fragment, 94 00:03:48,040 --> 00:03:50,780 we wanna write the code now to swap it in and out 95 00:03:50,780 --> 00:03:53,610 when the user edits a task or adds a new one. 96 00:03:53,610 --> 00:03:56,040 Now the code for that will go in main activity 97 00:03:56,040 --> 00:03:57,940 which I've got open on the screen here. 98 00:03:57,940 --> 00:04:00,270 Now at the moment, if we can scroll up to the top, 99 00:04:00,270 --> 00:04:02,550 we've got a load of information, 100 00:04:02,550 --> 00:04:05,930 a load of test code up here in on create. 101 00:04:05,930 --> 00:04:08,630 So what I'm going to do first is delete that. 102 00:04:08,630 --> 00:04:11,530 Basically gonna copy everything on what I've been working on 103 00:04:11,530 --> 00:04:14,110 below the set support action byline 104 00:04:14,110 --> 00:04:15,490 right through to the end of the function 105 00:04:15,490 --> 00:04:17,072 including the closing log. 106 00:04:18,560 --> 00:04:19,392 Delete that. 107 00:04:21,700 --> 00:04:24,020 And let's also delete the various functions 108 00:04:24,020 --> 00:04:27,390 that we created for testing our content provider, 109 00:04:27,390 --> 00:04:31,430 that's the test delete, one on two, test update one on two, 110 00:04:31,430 --> 00:04:35,190 and also our test inserts, so I'm gonna delete all of those, 111 00:04:35,190 --> 00:04:36,890 'cause we're not gonna need those. 112 00:04:38,390 --> 00:04:40,250 And we're left with now a much cleaner file 113 00:04:40,250 --> 00:04:42,050 than what we've had before. 114 00:04:42,050 --> 00:04:44,500 All right, so now at this point we're going to add 115 00:04:44,500 --> 00:04:47,120 a new task when the menu item's tapped, 116 00:04:47,120 --> 00:04:49,860 so we need to check that in the onOptionsItemSelected 117 00:04:49,860 --> 00:04:52,290 which is where the menu processing occurs. 118 00:04:52,290 --> 00:04:54,140 You could see that the code that Android Studio 119 00:04:54,140 --> 00:04:57,150 generated returns the result of the one expression, 120 00:04:57,150 --> 00:04:59,760 but that's not really suitable for how we'll be using it 121 00:04:59,760 --> 00:05:01,210 so I'm gonna make some changes there to that. 122 00:05:01,210 --> 00:05:03,560 So instead of having the return there, 123 00:05:03,560 --> 00:05:05,060 I'm actually gonna delete that 124 00:05:06,170 --> 00:05:08,347 and have a regular when loop there. 125 00:05:08,347 --> 00:05:10,267 And on the next line I'm gonna start doing 126 00:05:10,267 --> 00:05:13,723 and test firstly for R.id.menu_main_addTask. 127 00:05:18,030 --> 00:05:21,930 And if that's selected then we want to call that, 128 00:05:21,930 --> 00:05:25,167 call a function test, task rather, EditRequest, 129 00:05:27,410 --> 00:05:31,010 passing null to that, and that's because it's a new task, 130 00:05:31,010 --> 00:05:33,590 I'm gonna comment at the next line, the menu settings, 131 00:05:33,590 --> 00:05:36,390 for now, I'm also again gonna change the else, 132 00:05:36,390 --> 00:05:38,570 I'm gonna delete the else in fact. 133 00:05:38,570 --> 00:05:42,270 I'm gonna copy the super.onOptionsItemSelected line, 134 00:05:42,270 --> 00:05:44,620 I'm gonna cut that out, I said copy, 135 00:05:44,620 --> 00:05:45,970 but I'm gonna cut that out. 136 00:05:47,130 --> 00:05:52,130 And I gotta return, and the line that I cut out 137 00:05:52,370 --> 00:05:53,203 and paste it back in there, 138 00:05:53,203 --> 00:05:55,517 so it turns super onOptions ItemSelected. 139 00:05:56,664 --> 00:05:58,170 So as you can see now we've got an option there 140 00:05:58,170 --> 00:06:01,120 so if the user has clicked on the add option 141 00:06:01,120 --> 00:06:03,800 that we've added, which is the plus icon for our menu, 142 00:06:03,800 --> 00:06:05,033 we're going to call this function 143 00:06:05,033 --> 00:06:08,940 that we haven't yet created, Task Edit Request. 144 00:06:08,940 --> 00:06:10,590 So let's go ahead and create that now, 145 00:06:10,590 --> 00:06:11,760 I'll put that immediately below 146 00:06:11,760 --> 00:06:14,727 the onOptions ItemSelected function, 147 00:06:14,727 --> 00:06:17,580 so it's gonna be a private fun, taskEditRequest, 148 00:06:19,310 --> 00:06:23,083 and the argument will be task: Task? 149 00:06:25,890 --> 00:06:29,343 And we'll start with the log, the Log.d(TAG, 150 00:06:30,680 --> 00:06:35,110 and taskEditRequest: starts, 151 00:06:35,110 --> 00:06:37,860 so some indication of the function starting. 152 00:06:37,860 --> 00:06:39,720 And what I might wanna do next, I'm putting a comment here 153 00:06:39,720 --> 00:06:41,820 is create a new fragment to edit the task. 154 00:06:45,250 --> 00:06:47,860 Remembering that this function will be used for both adding 155 00:06:47,860 --> 00:06:52,373 and editing tasks, so we're gonna go val_newFragment 156 00:06:54,430 --> 00:06:57,617 is equal to AddEditFragment.newInstance, 157 00:07:00,134 --> 00:07:03,960 and we're gonna pass the task to that function. 158 00:07:03,960 --> 00:07:06,260 Then the next line we're gonna go with support 159 00:07:07,338 --> 00:07:11,959 FragmentManager.beginTransaction() 160 00:07:11,959 --> 00:07:13,547 and then the next line, and put a dot, replace, 161 00:07:15,692 --> 00:07:19,609 then in parenthesis R.id.fragment, newFragment. 162 00:07:22,300 --> 00:07:25,000 It's the one we just created on the previous line. 163 00:07:25,000 --> 00:07:27,147 Then on the next line .commit(). 164 00:07:28,958 --> 00:07:30,810 And that'll be it, then we'll just put a Log.d 165 00:07:30,810 --> 00:07:35,293 on the last line, (TAG, Exiting taskEditRequest) 166 00:07:39,650 --> 00:07:41,440 All right, so that's just about all we need 167 00:07:41,440 --> 00:07:43,780 to test the adding of a new task, 168 00:07:43,780 --> 00:07:46,730 except though the code will crash at the moment. 169 00:07:46,730 --> 00:07:48,660 And now if you remember in addEditFragments 170 00:07:48,660 --> 00:07:51,650 on attach function we check to see if the activity 171 00:07:51,650 --> 00:07:54,520 implemented the required interface. 172 00:07:54,520 --> 00:07:57,170 Now any activity that wants to use addEditFragment 173 00:07:57,170 --> 00:08:00,430 must implement its own saved click interface. 174 00:08:00,430 --> 00:08:03,830 So let's do that for this class now for that reason. 175 00:08:03,830 --> 00:08:06,160 So I'm gonna add it to the class declaration line 176 00:08:06,160 --> 00:08:09,180 after the AppCompactActivity, parenthesis, 177 00:08:09,180 --> 00:08:14,003 we're gonna put a comma, AddEditFragment.OnSaveClicked. 178 00:08:14,973 --> 00:08:17,113 All right, and we now need to implement, 179 00:08:18,030 --> 00:08:19,450 in this case just the one function, 180 00:08:19,450 --> 00:08:21,860 so I'm gonna do that immediately below the, 181 00:08:21,860 --> 00:08:23,680 actually I'll put it below the OnCreate function 182 00:08:26,363 --> 00:08:28,760 and the onSavedClicked function 183 00:08:28,760 --> 00:08:30,950 to be implemented to make it valid. 184 00:08:30,950 --> 00:08:33,630 We've now got it to do in there as you can see. 185 00:08:33,630 --> 00:08:35,419 All right, so at this point now we can run the programme 186 00:08:35,419 --> 00:08:37,770 in the emulator, so let's go ahead and do that. 187 00:08:40,475 --> 00:08:44,975 All right, just fast forward this bit until it starts. 188 00:08:47,230 --> 00:08:49,160 All right, so the app's still running, as you can see, 189 00:08:49,160 --> 00:08:53,140 so I wanna come over here and tap on the plus button, 190 00:08:53,140 --> 00:08:54,270 you can see the AddEditFragment 191 00:08:54,270 --> 00:08:56,240 is now appearing on the screen. 192 00:08:56,240 --> 00:08:58,010 Now it's obviously not finished yet, 193 00:08:58,010 --> 00:09:00,930 it's appearing on top of the main activity fragment, 194 00:09:00,930 --> 00:09:03,840 as you can see, but we can see how easy it is 195 00:09:03,840 --> 00:09:06,330 to add a new fragment to an app. 196 00:09:06,330 --> 00:09:08,180 And just to confirm that I can actually come over here. 197 00:09:08,180 --> 00:09:09,013 Woops. 198 00:09:09,013 --> 00:09:14,013 I can type in the edit text boxes, Tim Was, 199 00:09:14,070 --> 00:09:17,290 and just a number, you can see that's all working nicely, 200 00:09:17,290 --> 00:09:19,170 so the edit's definitely working in our fragment, 201 00:09:19,170 --> 00:09:21,260 but, again, obviously it's overwriting 202 00:09:21,260 --> 00:09:23,070 the main activity fragment. 203 00:09:23,070 --> 00:09:26,440 Now don't be tempted to rotate the device at this stage, 204 00:09:26,440 --> 00:09:27,750 we've still got some work to do, 205 00:09:27,750 --> 00:09:30,750 so the app will crash if you change orientation. 206 00:09:30,750 --> 00:09:32,285 So I'm just gonna close it for now 207 00:09:32,285 --> 00:09:34,040 and we'll go back to our code. 208 00:09:34,040 --> 00:09:36,830 And before we finish the video I want to just have 209 00:09:36,830 --> 00:09:40,820 a look at what we've done in the task edit request function, 210 00:09:40,820 --> 00:09:43,000 so let's go and have a look at that again, 211 00:09:43,000 --> 00:09:45,260 and work out why it hasn't worked as well as what we wanted, 212 00:09:45,260 --> 00:09:47,330 so in other words, why it's overlaying, 213 00:09:47,330 --> 00:09:49,640 and we can still see that fragment behind it. 214 00:09:49,640 --> 00:09:52,740 So we've created a new AddEditFragment 215 00:09:52,740 --> 00:09:56,830 using the new instance function on line 46. 216 00:09:56,830 --> 00:09:59,300 We then get the support fragment manager for our app 217 00:09:59,300 --> 00:10:01,160 and then begin a transaction. 218 00:10:01,160 --> 00:10:02,790 Now the transaction, as you can see, 219 00:10:02,790 --> 00:10:07,380 attempts to replace the contents of R.id.fragment 220 00:10:07,380 --> 00:10:09,760 with our newly created fragment. 221 00:10:09,760 --> 00:10:11,700 Now it's sort of worked, as you saw, 222 00:10:11,700 --> 00:10:13,010 but it also sort of didn't, 223 00:10:13,010 --> 00:10:15,570 because we ended up with the original content showing, 224 00:10:15,570 --> 00:10:17,300 as well as our new fragment. 225 00:10:17,300 --> 00:10:19,563 So let's check out this replace function. 226 00:10:22,530 --> 00:10:23,990 Now don't be put off when you get something 227 00:10:23,990 --> 00:10:25,860 that doesn't seem very informative. 228 00:10:25,860 --> 00:10:29,610 This version of Replace is an overwritten version of Replace 229 00:10:29,610 --> 00:10:31,030 with three parameters. 230 00:10:31,030 --> 00:10:32,560 When you get something that just mentions 231 00:10:32,560 --> 00:10:34,360 calling another method, follow the link 232 00:10:34,360 --> 00:10:35,320 to get the information you need. 233 00:10:35,320 --> 00:10:38,960 Again, you can see here that Calls, there's a link there, 234 00:10:38,960 --> 00:10:41,440 and replace with three arguments there. 235 00:10:41,440 --> 00:10:43,660 So I'm just going to click on that one 236 00:10:43,660 --> 00:10:46,180 and this is ultimately the one that's actually called 237 00:10:46,180 --> 00:10:48,670 with the three arguments. 238 00:10:48,670 --> 00:10:50,200 And I'll just bring that up so we can see that, 239 00:10:50,200 --> 00:10:52,620 so we can see the documentation for that, 240 00:10:52,620 --> 00:10:54,500 and you can see that it says that it replaces 241 00:10:54,500 --> 00:10:57,930 an existing fragment that was added to a container, 242 00:10:57,930 --> 00:11:00,230 and if you read the description it talks about 243 00:11:00,230 --> 00:11:02,800 removing all the currently added fragments, 244 00:11:02,800 --> 00:11:04,370 then adding the new one. 245 00:11:04,370 --> 00:11:07,100 But obviously that didn't work because the existing fragment 246 00:11:07,100 --> 00:11:09,520 wasn't removed and if you just get back and check this out 247 00:11:09,520 --> 00:11:12,960 we'll have a look at our content, .xml, 248 00:11:12,960 --> 00:11:17,033 in our resources section, and layout, content_main. 249 00:11:19,593 --> 00:11:21,410 And if you click on the fragment here, 250 00:11:21,410 --> 00:11:23,680 the componentry under the name, 251 00:11:23,680 --> 00:11:26,050 we've got learnprogramming.academy, 252 00:11:26,050 --> 00:11:29,010 then we've got MainActivityFragment 253 00:11:29,010 --> 00:11:31,630 that we specified for the main attribute. 254 00:11:31,630 --> 00:11:32,950 So that was correct. 255 00:11:32,950 --> 00:11:35,130 It has got a fragment widget, as you can see, 256 00:11:35,130 --> 00:11:38,800 but what's not obvious is that this one can't be removed. 257 00:11:38,800 --> 00:11:41,330 Now we're gonna have a look at the Google Guide in a moment, 258 00:11:41,330 --> 00:11:44,370 it talks about adding, removing, and replacing fragments 259 00:11:44,370 --> 00:11:47,570 in a fragment container, but what it doesn't say 260 00:11:47,570 --> 00:11:50,860 is that it means any container except a fragment widget 261 00:11:50,860 --> 00:11:53,120 which of course we're actually using. 262 00:11:53,120 --> 00:11:55,240 So let's just check out the guide. 263 00:11:55,240 --> 00:11:56,390 Quickly open a browser. 264 00:12:02,490 --> 00:12:04,520 All right, so we'll just scroll down a little bit, 265 00:12:04,520 --> 00:12:07,310 a short way down, there's a note about adding a fragment 266 00:12:07,310 --> 00:12:08,143 to an activity. 267 00:12:09,220 --> 00:12:12,280 Here we go, adding a fragment to the activity. 268 00:12:12,280 --> 00:12:15,050 It's talking about two ways of including a fragment 269 00:12:15,050 --> 00:12:16,760 in the view hierarchy. 270 00:12:16,760 --> 00:12:19,860 The first way uses these fragment widgets, 271 00:12:19,860 --> 00:12:22,610 as we've done so far, but below that, 272 00:12:22,610 --> 00:12:24,050 just scroll down a little bit more, 273 00:12:24,050 --> 00:12:27,720 it talks down here about pragmatically adding a fragment 274 00:12:27,720 --> 00:12:29,280 to an existing ViewGroup. 275 00:12:29,280 --> 00:12:31,470 So it's worth having a read through this page, 276 00:12:31,470 --> 00:12:34,500 but just remember that when you include a fragment widget 277 00:12:34,500 --> 00:12:38,320 in a layout it can have its original fragment removed. 278 00:12:38,320 --> 00:12:41,100 What we can do and what we'll do in the next video 279 00:12:41,100 --> 00:12:43,470 is use something like a frame instead. 280 00:12:43,470 --> 00:12:45,270 So I will see you in the next video.