Kotlin Sealed Classes & Custom State Managment (VLog)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
welcome back to another one of my vlogs in this vlog I'm gonna talk about Kotlin shield classes and a couple of the ways that I like to use them mainly pertaining to state management now if you don't know what Collin steel classes are you literally have never used them before never seen them before don't worry about it I'm gonna actually show you code samples as we go through this video so my goal in this video isn't to show you technically speaking how Kotlin steel classes work or how to use them I want to either a if you've never seen them before I want to inspire you to Co and you know research them because I think they're definitely worthwhile to take a look at or B if you have seen them before to give you some ideas of how you can use them in your projects so if you've been following along with my vlogging series you know that I've been working on a course with dynamic feature modules and clean architecture so on the weekend I came in because I I feel like I'm getting a little bit behind on this course I guess because there's a lot of things that I haven't kind of used before obviously I've never used dynamic feature modules before it's a totally new thing so there's not a ton of information on it I've never used clean architecture before again although it's not it turns out it's not much different to how I was structuring code before it is still different and I also haven't used work manager before and I was trying to use that so a lot of things I haven't used before so I started to feel kind of overwhelmed and I came in over the weekend get some extra stuff done so I ended up having a very productive weekend and I want to talk about some of the things that I worked on so let's take a look at the app that I've been building and again if you haven't watched my other vlogs this app is gonna be very foreign to you you've never seen it before but if you have been watching my vlogs this is gonna look very familiar so let's take a look so the first fragment that comes into view is this list of notes this fragment that contains a list of notes so if you've never seen this app before it's pretty simple it's just like a note taking application there's a list of notes you click on the note you can edit them you can update them delete them create them all that kind of stuff the feature that I was implementing over the weekend was being able to select multiple notes inside of the list and also be able to delete them so if I wanted to for example hold down long click on these notes I should enter this kind of I guess selection mode where the tool bar changes to have an X up here a trashcan and then if I click any notes that have not been selected yet they get highlighted if I click on one that has already been highlighted it gets highlighted this was the behavior that I was trying to implement now if you've been around Android development for any amount of time you know that typically this behavior is handled with gestures so maybe inside of the view holder in your recyclerview you would set up a non touch listener you would use a gesture detector you pass the touch event to the gesture detector and then you can detect any types of different gestures whether they're like swipes long clicks whatever then you can determine you know if the user holds down their finger on the list item then you would like enter some kind of selection mode and keep track of the list items that are selected and there's actually something new that came out I think this year or maybe in 2019 I didn't even know this thing existed it's called Android X recyclerview selection and apparently it is a recyclerview add-on library for providing support for item selection so I actually tried this thing out in my project because I thought oh this new thing I might as well use it but it turns out it doesn't really work well it works it works actually really good for just selecting items but if you have any kind of other behavior it's not that great and I'll tell you what I mean so I don't have it set up on my project right now but I'll just kind of outline generally what it did and then what the problems with that was so if I had it set up on this project I would be able to select items really easily it was actually worked really great for that it kind of lets you maintain like a list inside of the adapter and you could set the list items for active or not active inside the view holder and it's it was actually like really easy to set up and everything worked really good so if I hold down long click it would set the view the view holder to active and then it would highlight it and if I clicked it again it would set it to not active it was actually really awesome the problem with this was it interfered with the other gestures so like for example in this project if I click out of this I can swipe to delete notes so if I was to just like swipe this one out it deletes that note but if I was using the selector it interfered with other gestures so like for example I did if if I'm in selector mode so if I have these notes selected I don't want to be able to swipe these notes out which you don't see in this app because that's how I built it but when you were using the selector that kind of logic was really difficult to write in there and that goes for all of the other kind of gestures also basically at the end of the day it was really good for selecting things but if you were doing anything else with your list it exponential layers of complexity so at the end of the day I ended up implementing a custom system with Colin sealed classes and I'm very happy that it did because everything works really awesome and it's logically speaking I think it's really easy to follow so I want to show you how it works so first let's go through the app and I just want to show you the the behavior that is being implemented and then we're gonna look at the code and I'll kind of walk through it and show you how I did that so the end of the day essentially want what I want you to notice here is that there's there's two states that can be that this toolbar or this view can be in it can either be in what I'm calling a search view state which is what you see here you have the search view up here I could you know do a search search some content I could clear the search whatever oh I can also click a filter button up here and change the filters based on title or date ascending or descending and then there's also the other state which is like this selection mode so if I was to do a long click on one of these then we enter that selection mode I can click them I can unhighlight them I can delete them all that kind of behavior alright so this is a multi module project so I'm going into the notes module going into main the main package directory going into framework because we're going to be looking at one of the views going into the presentation layer note list because that is the feature or the yeah the feature that we're working on within the module the no list and I'm going to go into the the state package and I have a couple classes in here the first one I want to show you is this note list toolbar state so this is the sealed class that I was talking about that denotes the different states that the view can be in so let me just bring the app on the screen again just to remind you so we have search view state which kind of has this search view in the toolbar and then the the filter options and then if I was to click this and initiate the highlighting this is what I would call like the selection state so I called this multi selection State which is up here so these are the two kind of states that this view can be in so for those of you who do know what sealed classes are and you're comfortable with them you use them this is gonna look very simple to you you're gonna be like great this I understand completely but for those of you who have never seen a call and sealed class before this is going to be very confusing so let me just quickly go to the callin documentation and read a little bit about what Collin sealed classes are again I don't want to get into like technically speaking how they work what you can use them for I'm just trying to get you interested so that you will actually go and do these things on your own if you watch this video and you want to know more you want to see me go out and give you examples on Kotlin steel classes and how to use them leave a comment below and tell me that because if I get enough demand for any particular topic inevitably I make a video on it so let me know in the comments below okay so here's the definition I'm just gonna read a little I'm not gonna read the whole thing's gonna read a bit steel classes are used for representing restricted class hierarchies when a value can have one of these types from a limited set but cannot have any other type they are in a sense an extension of an enum class so this is a really good comparison the extension of an enum class comparison they're essentially enum classes with added features and those of you who know what an enum is it's essentially just a group of constants that are related I think that's a good way to think of it so a call in sealed class is a group of classes that are related they kind of they subclass one kind of parent class and they're all related but they have some added features that enums don't have now let's go back to my code and take a look at the that's the sealed class again so we have it's called note list toolbar state and there's two classes within it it's called multiselection state and the search view state I'll bring the app on the screen again here so again the search view state is when the toolbars in this state if I click on a note I'm taken to the details the multiselection state is if I hold down long click toolbar changes to this and I have kind of different behavior that I can use inside of this view the thing to notice here is that they both extend the parent class so they extend the note list toolbar state so you can think of them as two different states that are related yeah like a comparison of an enum it's like two constants that are within the same group of constants okay so now the question is how am i managing this stuff in the view because sure the sealed class looks fine but how is that actually practically being used so what I like to do when I use these call and seal classes to maintain some kind of state is generally I like to build like some kind of a manager class and then inside of the manager class I have a live data value that can be changed which is which holds that parent state and then I observe that in the UI so if it changes to say the search view state then I observe that changed and I changed the UI accordingly if it changes to the selection state I observe that change and I change the UI accordingly so let me show you what I mean by the manager so here is the manager that I built for managing the states at the toolbar I call that note list interaction manager so it has two mutable live data private mutable live data objects at the at the top one is selected notes which is just a list of notes and then the other one is the toolbar state so here's that call and seal class that I was talking about note list toolbar State it's a live data value and it holds that note list toolbar State so you know there's two possible States here we can either be the search view state or the multiselection state you can see that the initial value is the search view state then I just expose those live data objects to the UI through these two variables so selected notes or the toolbar state and then I observe that so this note list interaction manager is kept in the view model so if I was to open up the note list view model you can see at the top I have note list interaction manager and it's exposing the state through this variable right here so two of our state note list interaction manager toolbar state and then if you look in the UI I'm observing that so let's take a look at the UI just so you can actually see it so I'm gonna open up note list fragment if I scroll down to my subscribe subscribe observers function so let me go down you can see view model toolbar state there's the observer and there's just a when statement that says when the toolbar state is either in multiselection state or search view state it updates the UI accordingly with the corresponding functions so that's all it does so basically what I do in the UI is inside of the view holder I'm listening for on long clicks so when an on long click is detected if I hold that down it essentially changes the state in the view model changes the two of our state to the selection state and then the UI just updates accordingly if I was to click this X I'm saying change to the search view state and then the UI updates accordingly again and just so you can actually see it let's go into the note list adapter and I'll actually show you that so if I scroll down here to note view holder you can see that down here I'm detecting on long clicks and if there is an on long click I'm saying activate multi selection mode with this interface that's being provided to the constructor so if you scroll down you can see a definition of that interface it's just a bunch of functions debate multiselection mode is one of them now if I go into the note list fragment at the top I am implementing that interface so there's the interaction interface and I'm detecting that function that I just mentioned so again the function is activate multi selection mode let me just copy that and search for that inside of note list fragment and you can see here activate multi selection mode calls view model set toolbar state to the multi selection mode and then of course the observer would observe that change and update the UI accordingly now the last thing that I want to talk about is how I'm keeping track of the list items the selected list item so if I'm clicking on these or I'm highlighting them or not highlighting them how is that being tracked now you could do this like I said with the recyclerview selection thing but I wasn't my favorite because it interfered with the other gestures so let me show you how I did it because I think it's a really kind of unique solution to this problem and it ended up working really good so I'm kind of I'm kind of proud of it I want to show it off so if you go into my note list interaction manager you can see that I have a mutable live data list of notes and it's being observed in the UI through this variable here so this is saved in the view model like I showed you and then through the view model the UI is observing that so let's go into the note list adapter and I'll show you how I'm using this so if you scroll up to the top I have two kind of interesting values being passed to the constructor here and you you might be like hey am i are you supposed to do that I'm passing a lifecycle owner and also a list of live data values so you might have never seen this before I've personally never done this before this was the first time I ever passed like a lifecycle owner or a list of live data values into a recycler view adapter but it worked out really good so let me show you how I set this up so these selected notes are the ones from the manager so if I go into note list fragments and I look at my setup recycler view function if I scroll down here you can see I have listed Apter equals new note list adapter I'm passing the view lifecycle owner of the fragment as the lifecycle owner and then I'm passing the selected notes from the the manager the manager the note list interaction manager class and I'm passing that to the adapter so I'm essentially feeding the live data from the manager into the adapter now let's go back to the adapter and see how good used so if you scroll down to the view holder again we have the lifecycle owner being passed and that list of selected notes to the live data then if you look into the bind function so the bind function is being called in on by and view holder every time a new view comes into view for the recyclerview bind is called and it sets everything and sets the you know everything to do with the note if you look at the app you have like the title you have the date and then in this case it's setting the observers so if you scroll down there's that live data being observed I'm passing the lifecycle owner then there's just some simple logic down here that's saying if the list of notes that's being observed the the selected notes contains the note that's being set to that particular view holder then we want to change the background color to gray so that's this right here if it doesn't then we're just setting it to white which is this color primary so what I'm doing here is I'm putting an observer inside of each view holder and it's observing the list of selected notes so every time I click one that note gets added to the list of selected notes and then the view holder sees says oh hey look the list of selected notes has changed I wonder if the note that I'm holding is in that list if it is then it changes to gray if it isn't then it changes to white that's how it works and I was a little nervous about putting a list of live data inside of each of you holder but I inserted a thousand notes into my database just to see how it would work and I I scrolled all of them so that all of them were queried and everything was working good there was no like lag i selected random ones i unselected them I did a whole bunch of stuff I played around with it essentially tried to break it and everything worked really good so it turned out really good and there's there's no risk of like having a random observer floating around that you forgot to like unsubscribe because I'm using the view lifecycle owner as the subscriber so just to kind of reiterate what I did if you look in note list fragment I'm to the constructor of the adapter I'm passing the view lifecycle owner of the fragment so if the fragment was destroyed or goes out of view the lifecycle owner is also destroyed therefore the observers inside the view holders will unsubscribe so there's no risk of memory leaks or having observers floating around in memory that you forget about I guess since this is a I'll show you one last thing that I implemented in the app I added the ability to filter on the title or the date and then also do ascending or descending order so if you take a look at the app there's this icon in the top of the toolbar if I click it a dialog comes into view I can either filter by title or date or ascending or descending order so if I do you know say date descending hit apply you have the newest dates at the top so these are the newest notes that were inserted if I was to then change to ascending it does the opposite the oldest notes are at the top then I could do title of course to apply that would be alphabet let me see what is it ascending so alphabetical order and then if you were to do descending that would be anti alphabetical order if that's how you say that what you see because you see the W at the top that is everything that I have implemented since we last talked in the previous blog actually one last thing before we go if you've been following along with my vlogs you know that I asked you to follow an issue on the Google tracker because dynamic feature modules couldn't run a spresso test by default you would get an error that said no tests found if you tried to run one and a lot of you followed the issue which was awesome thank you very much you know most of you probably don't care but let me show you the effect that those of you who actually watch the vlog and start the issue so here's the issue it has 116 people who have started when I first made that vlog I think there was like six so well over a hundred people have started and I've been I've been getting a lot of updates on this issue so thank you very much also if you've been following along you know that down here or in my last vlog I said that if you install Android studio for beta that it should run you I test well I actually did install Android studio for beta I'll show you the version on my screen here right now you can see I have a Android studio for beta for installed well I tried to run UI test and it still didn't work it still said no tests found so I posted an update on that issue today so I'm still waiting to hear back hopefully they resolve this I mean they're definitely gonna resolve it it's it's such a big issue that there's no question that they're gonna resolve it it's just a matter of time but I wanted to say thank you for everybody who actually started that issue because you had an impact they are looking at it I think a lot more than they were looking at before now of course one thing before you go do not forget to like the video if you like these blogs if you like my videos if you want to support my channel in any way that you can please press the like button because it helps so much YouTube does not recommend my videos to other developers unless they think that people like them so please tell YouTube that that you like my videos you know if you don't tell YouTube that you like my videos this coding and flow guy is just gonna absolutely leave me in the dust take a look at his subscribers he has a hundred and sixteen thousand subscribers did you know that I was actually the one who influenced him to start a YouTube channel and now he is almost doubling my subscribers his videos get double the likes that mine do real please help me out otherwise he's gonna just leave me in the dust and I don't know I might I might have to quit I don't know what I'm gonna do maybe I should start a new business I've always wanted to be a professional dog walker thanks for watching and I'll see you in the next video [Music]
Info
Channel: CodingWithMitch
Views: 15,831
Rating: 4.9752579 out of 5
Keywords: codingwithmitch, codingwithmitch vlog, programmer, android programming, android engineer, learn android app development, dynamic feature modules, android development is hard, android developer life, software engineering, android clean architecture, kotlin sealed class, kotlin sealed classes
Id: YQqinABOH4w
Channel Id: undefined
Length: 19min 3sec (1143 seconds)
Published: Mon Apr 20 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.