Welcome back, everyone.
Our report's coming along.
In this video, we'll implement sorting.
When the user taps one of the column headings,
the data will be sorted by that column.
Examine the DurationsViewModel code carefully
to decide how you're going to achieve that.
Yes, it's challenge time.
Remember that the durations report activity
will respond to the user tapping the headings,
and the ViewModel will take care of loading the data.
Add an onClick listener to the headings in the DurationsReport
class to allow the data to be sorted by the various columns.
Test your solution to make sure it works.
Pause the video now and come back when you're ready to see my solution.
So how did you get on?
The only changes we need to make are in the DurationsReport class.
And DurationsViewModel already deals with re-querying the data
when its sort order property changes.
For my solution,
I'm going to get the DurationsReport class
to implement the view.OnClickListener interface,
that's probably the easiest way
to use the same onClick listener for all the headings.
Although, you could have declared an onClick listener object instead.
I'll get android studio to generate the function after oncreate,
and then we'll add the code.
We've got an error on line 38 because we should be using
the safe call operator.
Using safe call is one solution,
but this is an implementation of the views
on ClickListener interface.
What are the chances of this function being called by something that's null.
Remember that google haven't finished annotating
all the java methods and parameters with non-null.
The view parameter can't be null.
And another solution is to remove the nullable type marker
from the declaration.
All right. When one of the column headings is tapped,
this function will receive the corresponding text view as an argument.
We can use the ID of the text view to decide which one was tapped.
A simple when statement says the view model sort order property.
We've already got the ViewModel to reload the data
when sort order changes,
so that's all we need to do.
In oncreate, we set the OnClick listener
for each of the heading widgets.
Remember, the description column won't exist in portrait.
Using the save call operator will make sure we don't get a null pointer exception
when attempting to set its OnClick listener,
I'll run the app to test it.
I'll start by tapping the date column.
That sorts the data by date, which is good.
The duration column also works fine.
That scrambled the task names
letting us test the task name column.
That also seems to be working.
If you get strange results when sorting by date, don't worry,
there's a bug in this program
but you won't notice it unless you're testing on a different time zone
to GMT.
The more hours away from GMT you are,
the more chance there is you'll experience a bug.
I'll be talking about this later.
First, we're going to implement all the functionality
then we'll look at spotting and fixing this bug.
All right. We should also test sorting in landscape
because we've got an extra column when displaying the report in landscape.
This highlights a problem with our data
as far as testing the reports goes.
Our descriptions are a bit artificial,
that was useful to validate the data in the database earlier,
but it doesn't let us test sorting very easily.
Tapping the description column doesn't do a lot
because the task names and the task description sort
in almost the same order.
For a thorough test,
you should change all the task descriptions to something more realistic.
I'm not going to do that on the video, it does work though.
A quick test is to sort on duration,
and then tap on description
to sort the column that way.
That seems to be working as well.
Part of the reason this was so simple
was because of the clear separation between the
DurationReports class and the DurationsViewModel.
One question we often get asked by students is,
how can i learn to design my code well?
That comes with experience.
Be prepared to create classes that are far from perfect.
The more times you get it wrong, the sooner you'll get it right.
It's not always easy to spot good design until you come to make a change.
If the change is fairly easy and involves a few classes,
then the design is probably good.
If you really struggle and have to make changes all over the place,
that's an indication that the design could be improved.
All right. I'll stop this video here.
In the next video, we'll make a start on creating the menu
for the reports activity. See you then.