1 00:00:00,350 --> 00:00:04,780 Now that we've got the UI working, let's get working on the database. 2 00:00:04,780 --> 00:00:09,352 The first thing we'll need to do is add a couple imports to our build.gradle file. 3 00:00:09,352 --> 00:00:11,355 I've already got them on the clipboard, but 4 00:00:11,355 --> 00:00:13,791 they're the same ones we used in the pizza keeper app. 5 00:00:21,549 --> 00:00:27,389 Then we need to sync the project, and we can close the build.gradle file. 6 00:00:27,389 --> 00:00:32,590 Next, I'll add a data package, for organizing all of our database files. 7 00:00:38,519 --> 00:00:42,679 And I'll start with the bottom, by creating entity to represent a note. 8 00:00:47,202 --> 00:00:52,217 We call this class Note, then we need to make it a data class. 9 00:00:52,217 --> 00:00:57,910 And instead of the brackets, we'll use the parenthesis, and then we'll give it an id. 10 00:00:57,910 --> 00:01:01,771 And actually first let's give it the @Entity the annotation. 11 00:01:03,960 --> 00:01:08,945 Then let's give it an auto generating primary key, 12 00:01:08,945 --> 00:01:11,890 so this will be @Primary key, 13 00:01:11,890 --> 00:01:16,670 autoGenerate = true, and we'll call it val id. 14 00:01:18,390 --> 00:01:22,418 And it can be an integer which might be null, and 15 00:01:22,418 --> 00:01:27,072 then we will have the text of the ID, which is a string. 16 00:01:27,072 --> 00:01:28,128 Let's see what we've got here. 17 00:01:28,128 --> 00:01:33,762 This doesn't equal an int, there we go. 18 00:01:37,908 --> 00:01:39,260 I'll wind this up. 19 00:01:39,260 --> 00:01:42,620 Awesome, so a really simple table for our note. 20 00:01:42,620 --> 00:01:45,860 It's got an id which we're going to auto generate by passing in null, 21 00:01:45,860 --> 00:01:48,800 and we'll store the text as a string. 22 00:01:48,800 --> 00:01:52,864 Then we'll need a data access object to access our note. 23 00:01:52,864 --> 00:01:56,238 So let's make a new interface. 24 00:01:56,238 --> 00:02:03,364 This would be NoteDao, and let's give it the @Dao annotation And 25 00:02:03,364 --> 00:02:07,820 inside let's write a get all function. 26 00:02:07,820 --> 00:02:14,450 So that'll be query select star from, it'll be note. 27 00:02:16,640 --> 00:02:19,820 And the function will be called getAll. 28 00:02:21,870 --> 00:02:27,257 And you will want this 29 00:02:27,257 --> 00:02:32,345 to return a LiveData 30 00:02:32,345 --> 00:02:37,150 of a list of notes. 31 00:02:37,150 --> 00:02:41,313 And then in order to have the OK button work, we need an insert function. 32 00:02:41,313 --> 00:02:47,429 So we insert and fun insert takes in a note, and that's it. 33 00:02:53,761 --> 00:02:57,638 Then to tie it in altogether we need a database class. 34 00:02:57,638 --> 00:03:00,821 So lets create MyDatabase. 35 00:03:03,235 --> 00:03:08,325 That will be a class and its actually an abstract class, 36 00:03:08,325 --> 00:03:14,076 and we wanna use @Database, then we need to add the entities. 37 00:03:14,076 --> 00:03:20,097 So, let's do this as an array of K classes, So, Kotlin classes, 38 00:03:20,097 --> 00:03:25,060 meaning we do Note::class instead of class.java. 39 00:03:25,060 --> 00:03:28,364 And then for the version, set it to 1. 40 00:03:28,364 --> 00:03:32,572 And this needs to extend from RoomDatabase, 41 00:03:35,715 --> 00:03:40,712 And the constructor invocation, then we need to add an abstract 42 00:03:40,712 --> 00:03:44,795 function called noteDao, that returns a NoteDao. 43 00:03:51,212 --> 00:03:54,810 Right, have to add the parentheses for our functions. 44 00:03:56,390 --> 00:03:58,978 Okay, and that should do it for the database. 45 00:04:04,313 --> 00:04:06,190 So now let's add the view model. 46 00:04:06,190 --> 00:04:13,740 So let's add here a new view model class for our main activity, MainViewModel. 47 00:04:13,740 --> 00:04:15,088 This is a class. 48 00:04:17,671 --> 00:04:19,917 So I'll hide the project pane for a second, and 49 00:04:19,917 --> 00:04:22,006 make this extend from the view model class. 50 00:04:26,041 --> 00:04:30,200 And we'll need to add the parentheses, and then let's get to our view model. 51 00:04:31,280 --> 00:04:38,089 Let's start by declaring a private variable, Named notes, 52 00:04:38,089 --> 00:04:46,750 which is a live data of a list of notes of our note class. 53 00:04:46,750 --> 00:04:50,300 So, just like we we're returning in the noteDao, 54 00:04:50,300 --> 00:04:53,290 we'll give this the ability to be null, and initialize it to null, 55 00:04:53,290 --> 00:04:56,930 and then we'll have a function to populate this notes variable. 56 00:04:57,970 --> 00:05:02,170 So, let's do function, get notes, and 57 00:05:02,170 --> 00:05:06,700 this returns a LiveData of a list of notes. 58 00:05:11,053 --> 00:05:12,750 Though note, this one cannot be null. 59 00:05:14,630 --> 00:05:19,725 And inside this function, if notes is null, 60 00:05:19,725 --> 00:05:23,490 then we'll retrieve the notes. 61 00:05:26,365 --> 00:05:29,165 And otherwise we will return, 62 00:05:32,453 --> 00:05:38,300 The notes and assert that they're true, or rather assert that they're not null. 63 00:05:38,300 --> 00:05:44,580 So inside here we'll need to add code to retrieve our notes from the database. 64 00:05:44,580 --> 00:05:46,290 To get access to the database, 65 00:05:46,290 --> 00:05:49,350 let's do the same thing we did in the Pizza Keeper app. 66 00:05:49,350 --> 00:05:57,063 Let's create a new app class, Which extends from application. 67 00:06:04,241 --> 00:06:10,892 And then let's override, so Control O The onCreate method. 68 00:06:10,892 --> 00:06:16,965 And let's add our lateinit var db. 69 00:06:21,883 --> 00:06:26,819 MyDatabase, so we are adding our database variable again, 70 00:06:26,819 --> 00:06:31,771 scoped to the entire project, and we're using a lateinit. 71 00:06:31,771 --> 00:06:37,241 So inside onCreate, before the call to supper.onCreate, 72 00:06:37,241 --> 00:06:43,820 let's set db = Room, which we'll need to import .databaseBuilder. 73 00:06:43,820 --> 00:06:49,918 And then provide a context, application context, the class of the database. 74 00:06:49,918 --> 00:06:55,593 So MyDatabase::class.java, and the name of the database, 75 00:06:55,593 --> 00:06:59,804 so, MyDatabase, and then we need to build it. 76 00:07:03,884 --> 00:07:06,788 And since this comes before the call to super.onCreate, 77 00:07:06,788 --> 00:07:10,061 we'll have access to our database from anywhere within the app. 78 00:07:13,380 --> 00:07:15,328 Like in our main view model. 79 00:07:15,328 --> 00:07:19,231 So if we call getNotes and notes from our view model is null, 80 00:07:19,231 --> 00:07:24,210 let's go ahead and retrieve those notes from the database. 81 00:07:24,210 --> 00:07:30,112 Let's set notes = db.otesDoa.getall. 82 00:07:30,112 --> 00:07:31,670 Perfect. 83 00:07:34,174 --> 00:07:36,660 Our view model is all set up ready to go. 84 00:07:36,660 --> 00:07:40,182 Let's head back into main activity, and I'll hide the Project pane. 85 00:07:45,075 --> 00:07:47,935 And below where we set our OnClickListener, 86 00:07:47,935 --> 00:07:51,783 let's add a couple lines, and get access to our viewModel. 87 00:07:51,783 --> 00:07:56,957 So, val viewModel = ViewModelProviders, 88 00:07:59,441 --> 00:08:03,553 With an S, .of, and pass in this for 89 00:08:03,553 --> 00:08:07,799 the activity, and then, .get, and 90 00:08:07,799 --> 00:08:12,590 pass in MainViewModel :: class.java. 91 00:08:14,620 --> 00:08:20,765 Then to get a live data of our list of notes we can call viewModel.getNotes. 92 00:08:22,150 --> 00:08:26,192 And then to observe t we just need to add a call to observe, 93 00:08:26,192 --> 00:08:33,965 pass in a lifecycle owner like the activity And then pass in an observer. 94 00:08:33,965 --> 00:08:37,995 We can create a new one by just typing in, Observer, with a capital O, and 95 00:08:37,995 --> 00:08:39,490 accepting Autocomplete. 96 00:08:41,160 --> 00:08:45,900 Inside the observer, we are dealing with a list of notes that might be null. 97 00:08:45,900 --> 00:08:49,055 So let's start by first making sure that list is not null. 98 00:08:49,055 --> 00:08:54,590 If, it, not equals null. 99 00:08:54,590 --> 00:08:59,523 Once we make sure that our list of notes isn't null, let's go into the adapter and 100 00:08:59,523 --> 00:09:03,042 clear the list, and then add back in each of the elements. 101 00:09:03,042 --> 00:09:08,109 So, we'll do adapter.list.clear, 102 00:09:08,109 --> 00:09:12,583 and then adapter.list.addAll. 103 00:09:12,583 --> 00:09:18,671 And we'll need to pass in the string portion of all of our notes. 104 00:09:18,671 --> 00:09:23,234 So here we have a list of notes, so let's take this and let's call .map. 105 00:09:25,400 --> 00:09:29,084 And this will take our list of notes and map it to something else. 106 00:09:29,084 --> 00:09:35,757 So lets map it to it, so in here we have a note, let's take that .text. 107 00:09:35,757 --> 00:09:40,876 And now we've taken our list of notes and transformed into a list of strings, 108 00:09:40,876 --> 00:09:44,999 where each item in the list just contains the text of the note. 109 00:09:46,450 --> 00:09:49,572 So once we've done that we just need to call 110 00:09:49,572 --> 00:09:54,104 adaptor.notifyDataSetChange to make the changes happen. 111 00:09:54,104 --> 00:09:57,485 And now that we're updating UI, based on our viewModel, 112 00:09:57,485 --> 00:10:02,384 all that's left is that when we click the button, instead of updating the adaptor, 113 00:10:02,384 --> 00:10:04,247 we should save to the database. 114 00:10:04,247 --> 00:10:11,405 So let's delete these two adapter lines and call DB, or rather a new thread, 115 00:10:11,405 --> 00:10:16,926 and inside that thread we'll call db.noteDao.insert. 116 00:10:16,926 --> 00:10:19,936 And we'll have to insert a new note, so up here let's create a new note. 117 00:10:19,936 --> 00:10:25,235 And for the ID we'll pass in null, and for the text, 118 00:10:25,235 --> 00:10:30,159 we will give it, A value of note. 119 00:10:30,159 --> 00:10:37,626 So we can't reuse this variable, so let's rename this one actually to noteText. 120 00:10:37,626 --> 00:10:41,201 So this is used, noteText, noteText is now blank, 121 00:10:41,201 --> 00:10:45,766 and that's all that's used for so let's pass noteText in there. 122 00:10:45,766 --> 00:10:49,916 And we can input the note class, great. 123 00:10:49,916 --> 00:10:55,430 Then we've got a note that we'll be inserting into our database. 124 00:10:58,057 --> 00:11:00,252 And all right, let's see what it looks like. 125 00:11:03,472 --> 00:11:10,720 And we're getting some error about a line we need to add to the build.gradle file. 126 00:11:10,720 --> 00:11:12,475 Not sure what that's about, but we can do that. 127 00:11:21,838 --> 00:11:25,018 And the app synced, so hopefully that took care of that issue, let's run the app. 128 00:11:30,621 --> 00:11:31,477 And see what I did wrong. 129 00:11:45,681 --> 00:11:50,960 It looks like our db variable was never initialized, and I think I know why. 130 00:11:52,060 --> 00:11:56,740 I didn't add the application to the manifest, and 131 00:11:56,740 --> 00:11:58,040 it warns me of that right here. 132 00:11:59,760 --> 00:12:05,942 So we come into the manifest, we type android name and app. 133 00:12:05,942 --> 00:12:10,383 Now when we run the app, we will at least get a different error. 134 00:12:10,383 --> 00:12:15,817 All right we've got text let's type hello world and 135 00:12:15,817 --> 00:12:18,790 hit OK, and it's in there. 136 00:12:18,790 --> 00:12:23,128 And if we rotate the app it's still there, it's still there. 137 00:12:23,128 --> 00:12:28,486 I'll send another message like, This is pretty cool, 138 00:12:28,486 --> 00:12:35,331 and one exclamation point, and then we'll say OK, got that in there. 139 00:12:35,331 --> 00:12:38,850 Still doing the rotation, let's leave the app using the back button, 140 00:12:38,850 --> 00:12:42,254 cuz remember that will cause a full destruction of the activity, and 141 00:12:42,254 --> 00:12:49,227 then let's reopen it Might be faster just to hit the Run button in Android Studio. 142 00:12:49,227 --> 00:12:51,053 And awesome, there it is.