(light music)
(typing sounds)
Our app should now display
task details when we edit one,
unfortunately, though, we can't test that
until we've got some tasks appearing in the RecyclerView.
Until then, we don't get the edit button.
We need to save the new records to the database
before we can test the code from the last video.
We've seen the code to save data,
when we were testing our content provider earlier,
the code in this app's very similar,
I'm gonna put saveTask, the saveTask function,
after the onviewCreated function in AddEditFragment.
Gonna create it here, private fun, space, saveTask,
parentheses, then left and right curly braces per normal,
let's put a comment in as to what this is actually doing,
so we're gonna update the database,
if at least one field has changed.
And the next line, so there's no need
to hit the database unless this has happened.
Okay, move this up a bit.
So we'll take the values in our EditText widgets
and store them in the database using a content provider.
We're only gonna save values that have changed
to avoid unnecessary database access.
So what we'll do is we'll start by converting
the sortOrder to an Int, because we'll use it
a few times in our code, we're gonna type
val sortOrder = if, parentheses,
addedit_sortOrder, then period, text,
then period, .isNotEmpty,
call to that, and close off the parentheses,
left curly brace, and we're gonna put
Integer.parseInt, so basically,
if it's not empty, you're gonna convert it to an integer,
and we're parsing addedit_sortorder again,
.text this time, though, and convert it to a string,
toString.
And we need an else there,
and the else is simply gonna be the value zero.
Alright, so next we need a couple of variables,
we'll be using a ContentValues object
to store the updated details,
and we'll also be using a local task value
to avoid having to use the !! operator,
as discussed in the last video.
So val values = ContentValues,
then val task = task,
which I've talked about now a few times,
alright so, if any of the values in the widgets
no longer match our original task,
we'll add those values to the ContentValues.
Of course, this only applies when editing a task,
if we are creating a new task,
and the task argument was null,
then we'll only save it if at least
a task name is available.
That's the only mandatory column in our database,
the description and sortOrder aren't required.
Alright, so we'll start with our tests for task,
so if, parentheses, task != null,
I'll start with a log, so Log.d, parentheses,
TAG, comma, then double quotes,
saveTask: updating existing task,
we know that because task is not equal to zero,
in terms of the code, it'll be
if, and we'll do a test for the name first,
so addedit_name.text.toString,
that's not equal to task.name,
then we do a values.put, parentheses,
tasksContract.Columns.TASK_NAME, comma,
then addedit_name.text.toString.
Okay, then we close off that line.
In the next line, we're gonna do much the same,
but this time, for description,
so if, if addedit_description.text.toString,
if that's not equal to task.description,
then we'll do a values.put again,
parentheses, and it's TasksContract.Columns.TASK_DESCRIPTION
this time, comma, then addedit_description.text.toString.
And I'll just move that so you can see that all on screen.
It's a little bit long with the name.
Alright, and then we need to do a test now for sortOrder,
so we'll do it outside of the if block,
it needs its own if block,
so if, parentheses, sortOrder,
that's not equal to task.sortorders,
sortOrder I should say, and remember,
we defined sortOrder on line 68,
so if that's the case, we need to also add it
to our ContentValues object, so, values.put,
TasksContract.Columns.TASK_SORT_ORDER,
comma, sortOrder.
Alright, so now we need to do a test,
to see whether we've got something to save,
and we can do that by putting if, parentheses,
values.size, if that's not equal to zero,
then we know we've got something to save,
so we'll do a Log.d, parentheses, TAG, comma,
double quotes, saveTask, colon, we'll put Updating task,
'cause that's what's happening here,
and in terms of the code, it's gonna be
activity?.contentResolver?.update, parentheses,
it's gonna be TasksContract.buildUrifromId,
parentheses, task.id, close your parentheses,
and I'm gonna put the rest on the next line,
so I'm gonna put a comma there,
then on the next line, we're gonna continue that,
and it'll be values for the second argument,
and the next two arguments are both null,
null and null, alright, and that's basically all the code
if we were editing an existing task.
Just to put it all back on screen again,
so if the task is not equal to null,
then we're basically checking each field,
our name, description, and sort order,
and we're adding it to our ContentValues object
if it has been changed, if it's not the same
as the task that we're currently editing,
and then we're checking to see
whether we've got anything to save,
and then we're calling the AppType function
if we've got something to save.
So that's in the case of editing,
now we want to look at the case of adding a new record,
so we'll do an else there, which is now basically,
if task is equal to null, remembering that task being null
indicates a new record, so we're gonna do else there,
and our code's gonna be Log.d, parentheses,
TAG, comma, saveTask, this time we're adding new task,
now, we'll do a similar thing,
but again, we're only checking out to see
whether the name isn't empty
so if, parentheses, addedit_name.text.isNotEmpty,
so in other words, we have got something to add,
that's the only one we need to check,
because remembering that description is sortOrder
and not mandatory in the database,
so that's the case, we're going to do
a values.put, parentheses, TasksContract.Columns.Task_NAME,
addedit.name.text.toString,
so adding that to our values object.
Alright, we'll check to see whether
we've got something in description,
noting that the if test is within the test for names,
so we're only going to be try and process this
if we found a name, in other words, something was top,
so if, parentheses, addedit_description now,
.text.isNotEmpty, so if there's something
entered for description, we'll also add it
to our ContentValues object, values.put, parentheses,
TasksContract.Columns.TASK_DESCRIPTION, comma,
addedit_description, and we'll do this on the next line,
'cause we'll run out of space there, it'll be .text,
.text.toString, alright, so I've added the description,
and because sortOrder defaults to zero if empty,
we don't need an if test there,
we're just going to add it irrespective,
so values.put, parentheses,
TasksContract.Columns.TASK_SORT_ORDER, sortOrder.
And we can put a comment there, defaults to zero if empty.
Alright, final thing we need to do is save.
So activity?.contentResolver?, .insert this time,
not update, parentheses, and it's gonna be
TasksContract.CONTENT_URI, comma, values.
Alright, so, there's probably not a lot more
to say about that, we're updating the database
if we're editing an existing task,
otherwise, we're using insert,
now I've used activity, as you can see on lines 91 and 103,
to get a reference to the contentResolver.
We could've used the listener, but that would've required
casting it to an AppCompatActivity,
and I think the code's clearer using activity instead.
It's just more obvious what we're referring to.
And we're still needing to use
the safe call operator in case activity's null.
Okay, we've already set the buttons on ClickListener,
in our onActivityCreated function,
what we can do is add a call to this new saveTask function
there, so let's go ahead and do that,
so again, that's in onActivityCreated,
so we're gonna add it before the Listener
that's onSaveClicked, so we're gonna add it in there,
saveTask, parentheses, so we're calling
the saveTask to actually save it.
Alright, so that's the code, now to save our data,
in the next video, let's test everything
to make sure it works.
We'll see you in that next video.