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.

