G'day everyone, welcome back. Okay, we've got our edit button working so let's look at the delete button.
It's tempting to dive straight in and add some code to MainActivityFragment.
After all, it's now got an onDeleteClick function that gets called when the delete button is tapped.
If we delete the tasks from there, it will work fine.
The problem is that our app's architecture is starting to get a bit messy.
With the introduction of the ViewModel class, LiveData and data binding,
Google are making it much easier to implement an MVVM architecture.
I should point out that they've made sure these components will also work with other architectures.
Google aren't suggesting you should change your app's architecture.
We're sort of using MVVM in this app, so let's have a quick look at what it's all about.
This Wikipedia page gives a brief overview of MVVM.
It's not strange that the word, separation, appears very early on in their description.
All the architectures; mvvm, MVP, MVC and so on,
all advocate separation of functionality.
The UI component should deal only with the user interface, for example.
I'll click on that diagram at the top right,
and the first thing you may think is that Model View ViewModel isn't the best name.
View ViewModel Model more accurately reflects how the parts of the system communicate with each other,
but the acronym is not as good.
The View is the user interface, and it gets the data to display from the ViewModel.
The ViewModel requests data from the Model.
Looking at that diagram, the Model is also responsible for the business logic.
We haven't got a lot of business logic at the moment, but what there is exists in our database.
For example, the task name can't be blank.
That's business logic, and our database enforces that.
Okay, that's the theory of MVVM. Let's have a look at how our app fits into it.
Now that we've decided how things will work, we can add a function to the TaskTimerViewModel class, to delete a task
I'll add it after the loadTasks function.
We'll pass in the ID of the task to delete, and call the ContentResolver's delete function to perform the deletion.
Our ContentProvider will take care of deleting an individual task, if its ID is provided in the URI.
The buildURIFromId function that we added to the TasksContract class,
will return a URI with the ID appended.
Because we're providing the ID, we don't need to use the last two parameters;
the where clause and selection args.
We just build up the URI from the ID of the task that's been passed to the function,
then call the delete function of the Content resolver.
The onDeleteClick function in MainActivityFragment will then call the ViewModel's delete task function,
to tell the ViewModel to delete the task.
Let's see if it works. I'll restart the app, which, as I've mentioned is a good idea when working with databases,
when you've got several classes all working together like this.
Android Studio's instant run tries to avoid restarting the app,
and can speed up the development and testing cycle, but when anything asynchronous is going on,
I think it's a good idea to always start from scratch.
Ok, I'll click the delete button for task 5, and it vanishes from the list.
So that's looking good.
It's a bit drastic, and there's no prompt to make sure that you really wanted to delete the task.
In fact, there are a few enhancements we should make to the user interface,
and we'll be looking at them a bit later on.
Now, to test this more fully, we should go on to delete random tasks.
We need to make sure that things like deleting the first and the last one in the list, work successfully,
then keep going to make sure that deleting the final task works as well,
and the results in the instructions are being displayed again.
It does, but I'm sure you don't want to spend time watching me type in all the tasks again, so I'll stop the video here.
In the next video, we've got a bit of tidying up to do.
We saw from the diagrams that AddEditFragment needs to be changed.
It should be delegating the saving to the ViewModel.
There's something else wrong with our app too. You may have already spotted it,
because we're doing something that the documentation says we shouldn't do.
I hinted at this a few videos ago.
See if you can spot what it is and we'll fix it in the next video.
I'll see you then.