1 00:00:03,860 --> 00:00:06,820 G'day everyone, welcome back. 2 00:00:06,820 --> 00:00:10,100 One of the neat things that Kotlin lets us do, is to add 3 00:00:10,110 --> 00:00:14,930 functions to existing classes without modifying the class. It does this using 4 00:00:14,930 --> 00:00:20,700 extension functions. Let's have a look at the onBackPressed function in Mainactivity. 5 00:00:20,700 --> 00:00:27,300 In there we call the showConfirmationDialog function, just as 6 00:00:27,300 --> 00:00:32,430 though it was a function of the activity. In fact, it now is a function of the 7 00:00:32,430 --> 00:00:37,289 FragmentActivity class. We've extended the class without having to change its 8 00:00:37,289 --> 00:00:41,969 source code. We could do the same thing by creating a subclass of FragmentActivity, 9 00:00:41,969 --> 00:00:47,579 but extension functions save us from having to do that. The showConfirmationDialogue function 10 00:00:47,740 --> 00:00:52,400 is available in any fragment activity that 11 00:00:52,400 --> 00:00:56,940 we add to our app. It extends the FragmentActivity class because we've 12 00:00:56,940 --> 00:01:01,380 specified that when declaring the function. That's why we've got Fragment 13 00:01:01,380 --> 00:01:09,180 Activity dot before the function name, in extensionfunctions.kt. When you 14 00:01:09,180 --> 00:01:12,930 create an extension function, it's receiver is the instance of the class 15 00:01:12,930 --> 00:01:18,800 you call it on. Talking about a receiver like this, which you'll see in the Kotlin 16 00:01:18,800 --> 00:01:23,900 documentation, just means that the function automatically gets this. I'll 17 00:01:23,910 --> 00:01:29,280 demonstrate that quickly. This is a course on Android development, not on the 18 00:01:29,280 --> 00:01:33,630 Kotlin language, so I'm not going to go into great detail, but it's useful to 19 00:01:33,630 --> 00:01:38,000 understand the basics of these extension functions. I'll start by deleting 20 00:01:38,000 --> 00:01:45,860 FragmentActivity from the function declaration. That gives us an error when 21 00:01:45,860 --> 00:01:49,600 we attempt to get the supportFragmentManager. 22 00:01:49,600 --> 00:01:51,660 We're attempting to call the getSupportFragmentManager 23 00:01:51,660 --> 00:01:57,000 method of the FragmentActivity class, but we don't 24 00:01:57,000 --> 00:02:01,590 have an instance of the class to call the method on. I said method there, 25 00:02:01,620 --> 00:02:06,880 deliberately, because the FragmentActivity class is written in Java. 26 00:02:06,880 --> 00:02:12,780 We access supportFragmentManager as if it were a property, because Kotlin lets us 27 00:02:12,780 --> 00:02:17,560 use that syntax, but behind the scenes, it's using a Java method call. 28 00:02:17,560 --> 00:02:24,280 Okay, I'll undo that change to clear the error. Just in case that didn't make 29 00:02:24,280 --> 00:02:30,980 sense, what we're really doing, is this. 30 00:02:30,980 --> 00:02:34,320 We don't need to use this there. I've just 31 00:02:34,330 --> 00:02:39,720 done it to show that we do have an instance of FragmentActivity inside our 32 00:02:39,730 --> 00:02:44,080 extension function. Alright let's create a few more extension functions. 33 00:02:44,080 --> 00:02:49,450 Looking at MainActivity, we have to get a supportFragmentManager, 34 00:02:49,450 --> 00:02:55,980 in order to call findFragmentById, and we do that in quite a few places. 35 00:02:55,980 --> 00:02:59,920 We'll see them in a moment. First, I'll simply create an extension 36 00:02:59,920 --> 00:03:06,730 function to simplify that. I'll add it to the start of this file, before the 37 00:03:06,730 --> 00:03:10,520 showConfirmationDialog function. 38 00:03:18,880 --> 00:03:24,380 Remember to import from Android X if you are prompted for the import. 39 00:03:24,380 --> 00:03:30,560 The fragment may not exist, so we return a nullable Fragment type. Okay, let's see 40 00:03:30,560 --> 00:03:41,360 how that can clean up the code in MainActivity. 41 00:03:41,360 --> 00:03:51,460 The next place is in onSaveClicked. 42 00:03:51,460 --> 00:03:56,960 In fact, we could get rid of the fragment variable there. 43 00:04:08,640 --> 00:04:20,880 We've got another call in onOptionsItemSelected. 44 00:04:20,880 --> 00:04:28,360 There's another one in onBackPressed, 45 00:04:28,360 --> 00:04:37,960 and the last one is in onPositiveDialogueResult. 46 00:04:37,960 --> 00:04:44,480 Alright, that's all a little bit cleaner but it's hardly earth-shattering, but we can do 47 00:04:44,480 --> 00:04:49,740 more. Fragments are a bit messy to manipulate, as we can see from the code 48 00:04:49,740 --> 00:04:54,460 in the taskEditRequest function. 49 00:04:54,460 --> 00:04:57,200 In there, we have to get a reference to the 50 00:04:57,200 --> 00:05:03,000 supportFragmentManager, then call its begin transaction function to start a 51 00:05:03,000 --> 00:05:08,130 fragment transaction. Inside the transaction, we replace the fragment with 52 00:05:08,130 --> 00:05:12,900 a new one, and have to remember to call commit. Forgetting to commit the 53 00:05:12,900 --> 00:05:17,640 transaction is easily done and means the new fragment won't be shown. 54 00:05:17,640 --> 00:05:25,600 Wouldn't it be nice if we could just call a replaceFragment function, something like ... 55 00:05:39,540 --> 00:05:44,760 That looks a lot cleaner and would avoid the possibility of forgetting to commit the 56 00:05:44,760 --> 00:05:50,250 fragment transaction. We can do that by creating a replaceFragment extension 57 00:05:50,250 --> 00:05:54,980 function. The function would still be slightly complicated, but it can be 58 00:05:54,980 --> 00:05:59,900 simplified even further by creating another extension function on the 59 00:05:59,900 --> 00:06:06,600 FragmentManager class. In fact, someone's already done that. Dinesh Babahunky 60 00:06:06,600 --> 00:06:12,000 posted an article on medium. I'll paste some code that's based on that article 61 00:06:12,000 --> 00:06:16,440 after the other extension functions. 62 00:06:22,040 --> 00:06:26,790 We'll start with a comment; 1, because it's good to acknowledge other people's work, 63 00:06:26,790 --> 00:06:31,800 and 2, it means that if we ever come back to our code, we'll know where 64 00:06:31,800 --> 00:06:34,400 we got it from. 65 00:07:11,580 --> 00:07:17,430 If you're prompted for the imports, remember to choose the Android X libraries. 66 00:07:17,430 --> 00:07:21,900 We've migrated the app to Android X, and you shouldn't mix Android X with the old 67 00:07:21,900 --> 00:07:27,060 support libraries in the same app. You may also have to delete some unused 68 00:07:27,060 --> 00:07:31,800 imports manually. Check out Danesh's article for a description of how these 69 00:07:31,800 --> 00:07:37,310 functions work. The inTransaction functions differently to the early code 70 00:07:37,310 --> 00:07:43,200 in Danesh's article because he improved it later, as a result of comments on the article. 71 00:07:43,200 --> 00:07:50,800 Alright, back in MainActivity, that's fixed the error in the taskEditRequest function. 72 00:07:50,800 --> 00:07:55,740 Scrolling back up to the removeEditPane function, 73 00:08:02,700 --> 00:08:07,620 that's easier to read and once again, removes the risk of forgetting to commit 74 00:08:07,620 --> 00:08:12,810 the transaction. Okay that's a quick look at how extension functions can help to 75 00:08:12,810 --> 00:08:18,290 make your code more readable and also more reliable. I'll stop this video here, 76 00:08:18,290 --> 00:08:23,240 but remember to test the app to make sure our changes haven't broken anything. 77 00:08:23,240 --> 00:08:27,840 We'll continue with the dialogues because we've still got the About 78 00:08:27,840 --> 00:08:33,870 dialogue to add, and also a dialogue for the app settings. In the next video, we'll 79 00:08:33,870 --> 00:08:38,539 take a break from coding and look at how to add an app icon to the app. 80 00:08:38,539 --> 00:08:43,360 We're doing that now because we'll also need the icon for the About dialogue. 81 00:08:43,360 --> 00:08:46,420 See you in the next one.