1 00:00:00,000 --> 00:00:02,398 (light music) 2 00:00:02,398 --> 00:00:05,570 (typing sounds) 3 00:00:05,570 --> 00:00:06,550 Our app should now display 4 00:00:06,550 --> 00:00:08,670 task details when we edit one, 5 00:00:08,670 --> 00:00:10,500 unfortunately, though, we can't test that 6 00:00:10,500 --> 00:00:13,760 until we've got some tasks appearing in the RecyclerView. 7 00:00:13,760 --> 00:00:15,890 Until then, we don't get the edit button. 8 00:00:15,890 --> 00:00:18,050 We need to save the new records to the database 9 00:00:18,050 --> 00:00:21,350 before we can test the code from the last video. 10 00:00:21,350 --> 00:00:23,180 We've seen the code to save data, 11 00:00:23,180 --> 00:00:25,620 when we were testing our content provider earlier, 12 00:00:25,620 --> 00:00:27,710 the code in this app's very similar, 13 00:00:27,710 --> 00:00:30,220 I'm gonna put saveTask, the saveTask function, 14 00:00:30,220 --> 00:00:34,253 after the onviewCreated function in AddEditFragment. 15 00:00:36,050 --> 00:00:41,050 Gonna create it here, private fun, space, saveTask, 16 00:00:41,600 --> 00:00:45,870 parentheses, then left and right curly braces per normal, 17 00:00:45,870 --> 00:00:47,890 let's put a comment in as to what this is actually doing, 18 00:00:47,890 --> 00:00:49,853 so we're gonna update the database, 19 00:00:51,310 --> 00:00:53,010 if at least one field has changed. 20 00:00:58,609 --> 00:01:01,692 And the next line, so there's no need 21 00:01:02,690 --> 00:01:05,663 to hit the database unless this has happened. 22 00:01:14,305 --> 00:01:16,388 Okay, move this up a bit. 23 00:01:17,370 --> 00:01:20,200 So we'll take the values in our EditText widgets 24 00:01:20,200 --> 00:01:23,090 and store them in the database using a content provider. 25 00:01:23,090 --> 00:01:25,350 We're only gonna save values that have changed 26 00:01:25,350 --> 00:01:28,620 to avoid unnecessary database access. 27 00:01:28,620 --> 00:01:30,210 So what we'll do is we'll start by converting 28 00:01:30,210 --> 00:01:32,880 the sortOrder to an Int, because we'll use it 29 00:01:32,880 --> 00:01:35,352 a few times in our code, we're gonna type 30 00:01:35,352 --> 00:01:40,352 val sortOrder = if, parentheses, 31 00:01:44,349 --> 00:01:49,349 addedit_sortOrder, then period, text, 32 00:01:49,630 --> 00:01:51,417 then period, .isNotEmpty, 33 00:01:52,830 --> 00:01:55,313 call to that, and close off the parentheses, 34 00:01:56,240 --> 00:01:58,470 left curly brace, and we're gonna put 35 00:01:58,470 --> 00:02:02,110 Integer.parseInt, so basically, 36 00:02:02,110 --> 00:02:06,440 if it's not empty, you're gonna convert it to an integer, 37 00:02:06,440 --> 00:02:10,967 and we're parsing addedit_sortorder again, 38 00:02:10,967 --> 00:02:13,756 .text this time, though, and convert it to a string, 39 00:02:13,756 --> 00:02:14,589 toString. 40 00:02:17,381 --> 00:02:18,460 And we need an else there, 41 00:02:18,460 --> 00:02:20,853 and the else is simply gonna be the value zero. 42 00:02:22,140 --> 00:02:24,720 Alright, so next we need a couple of variables, 43 00:02:24,720 --> 00:02:26,730 we'll be using a ContentValues object 44 00:02:26,730 --> 00:02:28,530 to store the updated details, 45 00:02:28,530 --> 00:02:30,460 and we'll also be using a local task value 46 00:02:30,460 --> 00:02:32,440 to avoid having to use the !! operator, 47 00:02:32,440 --> 00:02:34,590 as discussed in the last video. 48 00:02:34,590 --> 00:02:38,743 So val values = ContentValues, 49 00:02:40,990 --> 00:02:43,890 then val task = task, 50 00:02:43,890 --> 00:02:46,480 which I've talked about now a few times, 51 00:02:46,480 --> 00:02:48,630 alright so, if any of the values in the widgets 52 00:02:48,630 --> 00:02:50,690 no longer match our original task, 53 00:02:50,690 --> 00:02:53,580 we'll add those values to the ContentValues. 54 00:02:53,580 --> 00:02:56,300 Of course, this only applies when editing a task, 55 00:02:56,300 --> 00:02:58,230 if we are creating a new task, 56 00:02:58,230 --> 00:03:00,430 and the task argument was null, 57 00:03:00,430 --> 00:03:02,200 then we'll only save it if at least 58 00:03:02,200 --> 00:03:04,050 a task name is available. 59 00:03:04,050 --> 00:03:06,560 That's the only mandatory column in our database, 60 00:03:06,560 --> 00:03:09,520 the description and sortOrder aren't required. 61 00:03:09,520 --> 00:03:12,210 Alright, so we'll start with our tests for task, 62 00:03:12,210 --> 00:03:15,087 so if, parentheses, task != null, 63 00:03:18,671 --> 00:03:21,168 I'll start with a log, so Log.d, parentheses, 64 00:03:21,168 --> 00:03:23,562 TAG, comma, then double quotes, 65 00:03:23,562 --> 00:03:27,075 saveTask: updating existing task, 66 00:03:27,075 --> 00:03:30,350 we know that because task is not equal to zero, 67 00:03:30,350 --> 00:03:31,380 in terms of the code, it'll be 68 00:03:31,380 --> 00:03:33,790 if, and we'll do a test for the name first, 69 00:03:33,790 --> 00:03:38,723 so addedit_name.text.toString, 70 00:03:39,810 --> 00:03:42,423 that's not equal to task.name, 71 00:03:44,340 --> 00:03:48,159 then we do a values.put, parentheses, 72 00:03:48,159 --> 00:03:53,159 tasksContract.Columns.TASK_NAME, comma, 73 00:03:55,610 --> 00:04:00,103 then addedit_name.text.toString. 74 00:04:03,940 --> 00:04:05,600 Okay, then we close off that line. 75 00:04:05,600 --> 00:04:07,380 In the next line, we're gonna do much the same, 76 00:04:07,380 --> 00:04:08,420 but this time, for description, 77 00:04:08,420 --> 00:04:13,420 so if, if addedit_description.text.toString, 78 00:04:15,320 --> 00:04:18,483 if that's not equal to task.description, 79 00:04:21,769 --> 00:04:24,303 then we'll do a values.put again, 80 00:04:25,870 --> 00:04:30,870 parentheses, and it's TasksContract.Columns.TASK_DESCRIPTION 81 00:04:30,933 --> 00:04:35,933 this time, comma, then addedit_description.text.toString. 82 00:04:41,320 --> 00:04:45,660 And I'll just move that so you can see that all on screen. 83 00:04:45,660 --> 00:04:48,720 It's a little bit long with the name. 84 00:04:48,720 --> 00:04:51,690 Alright, and then we need to do a test now for sortOrder, 85 00:04:51,690 --> 00:04:54,150 so we'll do it outside of the if block, 86 00:04:54,150 --> 00:04:54,990 it needs its own if block, 87 00:04:54,990 --> 00:04:58,490 so if, parentheses, sortOrder, 88 00:04:59,890 --> 00:05:03,250 that's not equal to task.sortorders, 89 00:05:03,250 --> 00:05:04,890 sortOrder I should say, and remember, 90 00:05:04,890 --> 00:05:07,870 we defined sortOrder on line 68, 91 00:05:07,870 --> 00:05:10,580 so if that's the case, we need to also add it 92 00:05:10,580 --> 00:05:13,413 to our ContentValues object, so, values.put, 93 00:05:16,043 --> 00:05:19,337 TasksContract.Columns.TASK_SORT_ORDER, 94 00:05:22,005 --> 00:05:23,422 comma, sortOrder. 95 00:05:25,946 --> 00:05:27,530 Alright, so now we need to do a test, 96 00:05:27,530 --> 00:05:29,592 to see whether we've got something to save, 97 00:05:29,592 --> 00:05:32,410 and we can do that by putting if, parentheses, 98 00:05:32,410 --> 00:05:35,993 values.size, if that's not equal to zero, 99 00:05:37,330 --> 00:05:38,770 then we know we've got something to save, 100 00:05:38,770 --> 00:05:41,910 so we'll do a Log.d, parentheses, TAG, comma, 101 00:05:41,910 --> 00:05:45,670 double quotes, saveTask, colon, we'll put Updating task, 102 00:05:45,670 --> 00:05:47,263 'cause that's what's happening here, 103 00:05:49,060 --> 00:05:50,370 and in terms of the code, it's gonna be 104 00:05:50,370 --> 00:05:54,223 activity?.contentResolver?.update, parentheses, 105 00:05:58,760 --> 00:06:00,910 it's gonna be TasksContract.buildUrifromId, 106 00:06:07,120 --> 00:06:11,530 parentheses, task.id, close your parentheses, 107 00:06:11,530 --> 00:06:12,830 and I'm gonna put the rest on the next line, 108 00:06:12,830 --> 00:06:14,899 so I'm gonna put a comma there, 109 00:06:14,899 --> 00:06:16,560 then on the next line, we're gonna continue that, 110 00:06:16,560 --> 00:06:19,330 and it'll be values for the second argument, 111 00:06:19,330 --> 00:06:21,360 and the next two arguments are both null, 112 00:06:21,360 --> 00:06:25,320 null and null, alright, and that's basically all the code 113 00:06:25,320 --> 00:06:27,763 if we were editing an existing task. 114 00:06:28,690 --> 00:06:29,950 Just to put it all back on screen again, 115 00:06:29,950 --> 00:06:32,080 so if the task is not equal to null, 116 00:06:32,080 --> 00:06:34,290 then we're basically checking each field, 117 00:06:34,290 --> 00:06:36,640 our name, description, and sort order, 118 00:06:36,640 --> 00:06:38,730 and we're adding it to our ContentValues object 119 00:06:38,730 --> 00:06:40,950 if it has been changed, if it's not the same 120 00:06:40,950 --> 00:06:43,750 as the task that we're currently editing, 121 00:06:43,750 --> 00:06:44,583 and then we're checking to see 122 00:06:44,583 --> 00:06:46,160 whether we've got anything to save, 123 00:06:46,160 --> 00:06:49,370 and then we're calling the AppType function 124 00:06:49,370 --> 00:06:50,350 if we've got something to save. 125 00:06:50,350 --> 00:06:52,810 So that's in the case of editing, 126 00:06:52,810 --> 00:06:55,048 now we want to look at the case of adding a new record, 127 00:06:55,048 --> 00:06:57,240 so we'll do an else there, which is now basically, 128 00:06:57,240 --> 00:07:00,500 if task is equal to null, remembering that task being null 129 00:07:00,500 --> 00:07:03,233 indicates a new record, so we're gonna do else there, 130 00:07:04,760 --> 00:07:07,800 and our code's gonna be Log.d, parentheses, 131 00:07:07,800 --> 00:07:12,800 TAG, comma, saveTask, this time we're adding new task, 132 00:07:16,110 --> 00:07:18,070 now, we'll do a similar thing, 133 00:07:18,070 --> 00:07:19,470 but again, we're only checking out to see 134 00:07:19,470 --> 00:07:20,630 whether the name isn't empty 135 00:07:20,630 --> 00:07:25,413 so if, parentheses, addedit_name.text.isNotEmpty, 136 00:07:29,650 --> 00:07:31,530 so in other words, we have got something to add, 137 00:07:31,530 --> 00:07:32,950 that's the only one we need to check, 138 00:07:32,950 --> 00:07:35,610 because remembering that description is sortOrder 139 00:07:35,610 --> 00:07:37,530 and not mandatory in the database, 140 00:07:37,530 --> 00:07:38,820 so that's the case, we're going to do 141 00:07:38,820 --> 00:07:43,820 a values.put, parentheses, TasksContract.Columns.Task_NAME, 142 00:07:49,799 --> 00:07:52,049 addedit.name.text.toString, 143 00:07:53,720 --> 00:07:56,723 so adding that to our values object. 144 00:07:58,480 --> 00:08:00,420 Alright, we'll check to see whether 145 00:08:00,420 --> 00:08:02,090 we've got something in description, 146 00:08:02,090 --> 00:08:04,040 noting that the if test is within the test for names, 147 00:08:04,040 --> 00:08:06,070 so we're only going to be try and process this 148 00:08:06,070 --> 00:08:08,550 if we found a name, in other words, something was top, 149 00:08:08,550 --> 00:08:12,917 so if, parentheses, addedit_description now, 150 00:08:12,917 --> 00:08:16,060 .text.isNotEmpty, so if there's something 151 00:08:16,060 --> 00:08:18,500 entered for description, we'll also add it 152 00:08:18,500 --> 00:08:21,923 to our ContentValues object, values.put, parentheses, 153 00:08:22,830 --> 00:08:27,167 TasksContract.Columns.TASK_DESCRIPTION, comma, 154 00:08:29,589 --> 00:08:33,830 addedit_description, and we'll do this on the next line, 155 00:08:33,830 --> 00:08:38,193 'cause we'll run out of space there, it'll be .text, 156 00:08:39,687 --> 00:08:44,687 .text.toString, alright, so I've added the description, 157 00:08:44,870 --> 00:08:47,400 and because sortOrder defaults to zero if empty, 158 00:08:47,400 --> 00:08:48,360 we don't need an if test there, 159 00:08:48,360 --> 00:08:50,050 we're just going to add it irrespective, 160 00:08:50,050 --> 00:08:52,713 so values.put, parentheses, 161 00:08:53,610 --> 00:08:58,010 TasksContract.Columns.TASK_SORT_ORDER, sortOrder. 162 00:09:01,720 --> 00:09:06,423 And we can put a comment there, defaults to zero if empty. 163 00:09:09,710 --> 00:09:13,990 Alright, final thing we need to do is save. 164 00:09:13,990 --> 00:09:17,857 So activity?.contentResolver?, .insert this time, 165 00:09:21,180 --> 00:09:23,570 not update, parentheses, and it's gonna be 166 00:09:23,570 --> 00:09:28,570 TasksContract.CONTENT_URI, comma, values. 167 00:09:30,650 --> 00:09:34,020 Alright, so, there's probably not a lot more 168 00:09:34,020 --> 00:09:36,350 to say about that, we're updating the database 169 00:09:36,350 --> 00:09:37,940 if we're editing an existing task, 170 00:09:37,940 --> 00:09:39,840 otherwise, we're using insert, 171 00:09:39,840 --> 00:09:44,390 now I've used activity, as you can see on lines 91 and 103, 172 00:09:44,390 --> 00:09:46,600 to get a reference to the contentResolver. 173 00:09:46,600 --> 00:09:48,980 We could've used the listener, but that would've required 174 00:09:48,980 --> 00:09:51,410 casting it to an AppCompatActivity, 175 00:09:51,410 --> 00:09:54,340 and I think the code's clearer using activity instead. 176 00:09:54,340 --> 00:09:56,870 It's just more obvious what we're referring to. 177 00:09:56,870 --> 00:09:57,840 And we're still needing to use 178 00:09:57,840 --> 00:10:01,080 the safe call operator in case activity's null. 179 00:10:01,080 --> 00:10:03,520 Okay, we've already set the buttons on ClickListener, 180 00:10:03,520 --> 00:10:06,120 in our onActivityCreated function, 181 00:10:06,120 --> 00:10:08,680 what we can do is add a call to this new saveTask function 182 00:10:08,680 --> 00:10:10,630 there, so let's go ahead and do that, 183 00:10:10,630 --> 00:10:12,873 so again, that's in onActivityCreated, 184 00:10:16,053 --> 00:10:17,050 so we're gonna add it before the Listener 185 00:10:17,050 --> 00:10:18,823 that's onSaveClicked, so we're gonna add it in there, 186 00:10:18,823 --> 00:10:21,300 saveTask, parentheses, so we're calling 187 00:10:21,300 --> 00:10:23,120 the saveTask to actually save it. 188 00:10:23,120 --> 00:10:26,630 Alright, so that's the code, now to save our data, 189 00:10:26,630 --> 00:10:28,450 in the next video, let's test everything 190 00:10:28,450 --> 00:10:29,870 to make sure it works. 191 00:10:29,870 --> 00:10:31,520 We'll see you in that next video.