So now that we've created our simple task class,
we can create the activity to handle adding tasks.
Now I said activity here,
but instead of creating a new activity,
we're going to create a new fragment.
So what is a fragment?
Well, a good description of a fragment
is that it's a sub activity.
A fragment can have it's own layout
and can be embedded inside an activities layout
to provide some functionality in a modular fashion.
So, we quickly skip over to Google
and do a search for Android Fragment.
You get this link that usually comes up first
from Android, under a guide for components and fragments.
So I'm gonna click on that.
And this is well worth a read.
So the basic idea of a fragment
is that you can reuse it in different activities
and if we scroll down a little bit, there's a diagram here
that actually shows that.
This is an example of how that would work.
So on the left is a tablet display showing two fragments,
that is displayed in the same activity,
in fact that's very similar to what we're going to produce.
When you edit a task from the recycler due list,
the task details will appear on the right hand side
of the screen.
So the diagram on the right shows the same two fragments
being used on a phone in portrait mode.
So this uses the same two fragments,
that's the tabulate example
but because the screen isn't wide enough
to show them both side by side,
each fragment is displayed in a separate activity.
In fact we're going to do things slightly differently.
So launching a new activity is fine,
if all you're doing is displaying data.
When you allow the right hand fragment to edit the data,
things get difficult.
The Google's example only show displaying data
and using two separate activities in portrait mode.
We're gonna swap out the fragments instead.
So let's see how that works.
What we're gonna do now is take it slow.
We're gonna start by getting a single fragment working
in portrait mode on a phone.
Once we've seen how to use a fragment,
we'll build on that to handle the side by side display
on devices that have enough screen space.
So switching back to Android studio,
we're gonna start off by creating a new fragment.
So I'm gonna right click on the package name,
new, just now we're gonna come down to fragment,
select that from the menu,
then choose Fragment (Blank) from the menu.
We're gonna call this one AddEditFragment.
And now because we've already got a layout
called fragment_add_edit,
Android Studios wants to call this layout
fragment_add_edit2.
So we could just untick the create layout XML box
but that just doesn't create the layout,
it also adds a bit of code to use.
So we're gonna create this second layout file
so it adds that code
then we'll delete this extra layout later.
We do want both of these other boxes to be checked though.
They generate a lot of code for us which saves us time.
And obviously remember in the case
of the case of the course language drop down,
make sure that's set to Kotlin
and I'm gonna click on finish.
Okay, so you can see Android Studios generated
quite a lot of code for us.
So let's work through it and make some changes.
So the generic bits of the code are all marked
with TODO comments, as you can see here on line 12
and another one on line 27
and that makes them easy to spot
because they're the parts of the code we need to change.
So the first change is to the arguments that we're gonna
pass to the fragment in a bundle.
Now we'll only be passing a single argument
which will be the task to edit.
So what we're gonna do is
refactor the ARG_PARAM1 constant
to ARG_TASK and then delete ARG_PARAM2.
Just go ahead and do that.
I'm gonna refactor that.
Rename it.
And we're gonna call it ARG_TASK.
And we're gonna change the param1 to task
and for the ARG_PARAM2, I mentioned we don't need that
so I'm gonna delete it.
Once that's done, we can delete the TODO line as well,
'cause we've actually made those changes.
Alright so the class itself contains
fields for the arguments,
so once again, we need to actually go ahead
and make some changes to that.
So I'm gonna refactor the first one to be called task,
this param1, let's do that.
This param1, we'll change that to be task.
And we'll also change the definition,
which is a string, to a task,
leaving the question mark there.
And we're also then going to delete the second one,
the second parameter, because again we're not using that.
Now we are gonna come back to this line.
For now though, we're seeing the basic edits
that we need to make to the code that
Android Studios generated for us.
So I'm gonna delete the TODO for this as well
because we have made the changes to that.
So scrolling down a little bit now.
We've got a few errors.
Basically we have a param2 is referencing the code,
So I'm just gonna delete those lines as we come to them.
So on the onCreate, I go ahead delete that now.
Now this code looks a bit strange now,
the code that's starting on line 30.
It makes sense to use LET when dealing
with more than one parameter
but now there's only one,
we can just use a safe call operator instead.
So that will still work,
it's just unnecessary.
So let's go ahead and make that change.
So I'm going to leave the super.onCreate
and just type in task equals arguments
question mark because this is a safe call operator,
dot, and we're gonna leave getString in there
for a moment,
as ARG_TASK.
That'd be the replacement code.
And I'll delete the other code out.
Now, we've still got an error here.
That's because we changed the top of task to be a task,
but the generator code and the code that I retyped in,
is still using getString to try and retrieve it
from the bundle.
So we need to change this getString to getParcelable instead
and that's obviously because we've implemented
the task class to basically implement
the passable interface.
So I'm gonna do arguments question mark dot,
and it's gonna be getPARCELABLE
and in parentheses, ARG_TASK, but before that
we need to use a diamond operator there
and put Task within that,
to specify the top of object that we're expecting
to get from the bundle.
And when I do that, the error disappears.
And if I just go ahead and delete the task,
there you can see there remove explicit type arguments.
I can actually remove that
because it's now optional.
Basically, conversion 1.2.50 of Kotlin,
There's no log other requirement for the top to be specified
so if you get a message like I did,
to remove explicit top arguments,
then you can delete the diamond operator and task
after getParcelable.
So I get up out and do that.
And if I click in there again, you can see
I've got this warning, remove explicit type arguments,
so for that reason I'm going to remove it.
But obviously, if you haven't got that,
you can leave it in.
Alright, so now moving on down to the onCreate view function
that we've got here starting on line 33,
that's inflating the fragment_add_edit2 layout
that Android Studios generated for us.
Now, we've already got a layout
which we created in previous videos.
So for that reason, we can go now ahead and
make a change to that and inflate
that one but changing the 2,
we'll now be inflating the layout that we created earlier.
And we can now also delete the generated layout,
the fragment_add_edit2 in the res layout folder.
Just gonna go ahead and do that.
And that of course was the one that we created in this video
so make sure you delete the right one.
I'm gonna select delete there, click on OK.
And that's now been removed.
And again, the reason we told Android Studios to generate
a layout even though we already had one,
was so that it would put the line
to inflate the layout code in there for us,
to allow us to make a simple change.
So we could've told it not to create a new layout,
but then we'd have to remember to type that line in,
changing it and deleting the other layout is just easier.
Right, so next we have the function
that the fragments button will call.
This is at the moment called onButtonPressed
and it's got a TODO there.
So Android Studios is giving this generic code here.
It's quite likely that we'll want the fragment
to notify its activity when something happens.
And that's why Android Studios generated
this onButtonPressed function,
and it's also created a general purpose parameter at uri.
Now, we will have a button on this fragment,
the save button that we created in the layout.
But what we're gonna do is attach
an onSaveClickedListeners to it later
and for that reason we don't need this function.
So I'm gonna delete this onPressed function altogether
including the TODO comment.
Now, the onAttach function here,
that's checking that our activity does implement
the necessary interface,
in this case the interface that allows
our fragment to call it back.
Now that name that it's using here,
this OnFragmentInteractionListener is a general purpose name
and frankly is a bit of a mouthful.
So I'm gonna refactor and rename it
and change it to OnSaveClicked
And I'm gonna do that by renaming the interface down here.
Refactor, rename, and then I'm gonna
go with the name there of OnSaveClicked.
And I'm just gonna click OK there.
And then I'm gonna click on Do Refactor.
And you can see it's made the necessary change to the call
on line 41 as well as the interface itself on line 64.
So Android Studios helpfully changes references
in the comments in the code itself,
when you click on that Do Refactor which is pretty handy.
Alright, moving on again now though,
after the touch function, we have the onDetach function,
and that just sets the list the to know,
and I'm gonna be explaining all this fragment lifecycle
functions in the next few videos
so don't worry about what it's doing there,
just at the moment.
Next time we got another TODO here within our interface
and we have already named the interface.
But I'm also gonna take the opportunity
to refactor the actual function name
which is currently set to onFragmentInteraction.
Let's go ahead and do that.
Now, our activity's gonna be responding
when the save button is clicked,
so it makes sense to call this function onSaveClicked.
And obviously the function has a lowercase O,
and the interface has a capital O
as you can see there.
Now that's a common way of naming things,
and we've seen it with the OnClickedListeners
that we've written previously.
Now we also have to remove the parameter
because we won't be passing back to the activity.
Gonna do that.
And I'm also gonna take the opportunity to delete
the TODO comment since we've now made the required changes.
Right, so the final part of generic code here
is the companion object.
So this provides a static method in Java terms
that we can use to create new instances
of the fragment.
So it uses the same two parameters
and obviously we need to change it to use our
single task parameter.
Let's go ahead and make some changes to that.
So firstly on the newInstance function declaration,
gonna change that now so it's just got the one.
It's gonna be task colon task question mark.
So what I'll do is just delete those two lines there,
the two puts because we're gonna be
putParcelable instead.
So it's gonna be putParcelable
and it's gonna be ARG_TASK, task
and you can see that I've deleted the second layer
second entry for ARG_PARAM2
because we're only using a single parameter here now.
So this newInstance function provides a convenient way
to pass a task to the fragment
without having to include all that bundle code
in our calling code.
Now, if we didn't use the newInstance function,
our calling code would look something like
the code that I'm about to paste in.
I'll paste this in right at the end of the file down here
so we don't get any errors.
We are going to comment this out.
So that would be our calling code
what it would normally look like.
And we could simplify that a little bit
by using the apply function from the AddEditFragment
in the bundle.
So we can make it a little bit simpler,
something along the lines of this,
and I'll paste this code as well.
So that's making it a little bit simpler.
But I think in reality it's a lot simpler
to use what we've got with this newInstance function.
This is effectively what we're going to be using.
So I think you'd agree that's a lot simpler.
We don't have to remember all about bundles and arguments,
but we wanna create a new AddEditFragment.
Now, you might be wondering there why
we didn't just pass the task argument in the constructor.
That would be the easiest of all,
but unfortunately it's not possible.
Fragments must have a parameter less constructor,
in order for Android to create them when it needs to.
Now remember that Android does all sorts of things
behind the scenes.
If our fragment gets destroyed,
Android will recreate it.
So it takes care of saving the fragment state for us,
but it has no idea what arguments we may have passed
when we created it.
If we go passing arguments to the fragment constructor,
they would be available when Android recreates the fragment.
So that's why arguments are passed in the arguments bundle,
and why we can't pass them in the constructor.
Alright, so what I'm gonna do is comment out
these three functions so that they are available
in the resources if you wanna check out little tune edits.
Alright, so let's finish off the changes
before reviewing what we've done.
Now I haven't deleted the TODO item
in the companion object yet.
That's because there is still a minor change to make.
Android Studios is actually giving us a few warnings here.
Now, the first one if you hover over here
it's saying that function onsaveClicked is never used,
so we can ignore that one.
But the next two are interesting, we'll hover down here.
So you can see that they're complaining about
the names that we've got in the companion objects comments.
And you can see we've got param1 and param2.
When you format comments like this, like we've done
or like what was created automatically for us
from Android Studios, starting on line 68,
they're not treated as ordinary comments.
They're actually Java dot comments and they're used to
automatically generate documentation
for our classes and functions.
Now Android Studios tries to help us
make sure they're accurate and in this case,
to check the names param1 and param2 against our code,
we no longer have a param2, and we've renamed
param1 to task, so therefore we need to update the comment.
So go ahead and do that.
Delete the second entry first, param2.
And for param1, I'm gonna change that
to make it task and I'm gonna call it a description.
I can put task to be edited or null to add new task.
Or null to add a new task.
And you can see those warnings are now disappeared.
We've only got the other warning there
about the fact that onSaveClicked has never been used.
Now that I've done that, I can delete the TODO there.
Alright, so I'm gonna finish this video
just by reviewing what we've just done.
So Android Studios has generated a lot of
generic code for us when the created the new fragment.
Not all of it's needed in all situations.
And things like the parameter names
and the namings of the interface are just placeholders.
We were expected to rename them to something more meaningful
for our application, which is, of course,
what we've done here.
Now we had to delete all references to param2,
'cause we're only passing a single argument
to the fragment, the task to be edited.
Now, we could've left it with the name param1,
but that's not very readable.
And we also had to change the parameter type,
and that's because we're passing a task and not a string.
So we've taken a generic fragment class
that Android Studios created and tailored it slightly.
So looking at the files in the project pane,
we've got MainActivity.kt,
that uses the layout activity that is called main,
which includes content_main.
Now that's just a convenience to keep the action bar
and floating action button separate from our widgets.
The widgets we want to display go in content_main.
Now content_main in this app doesn't contain any widgets.
We've just used a fragment instead.
So if we open up content_main now,
close the project pane briefly.
And you see that we have here there's a fragment
that's set to MainActivityFragment
And you can see they have it at set to MainActivityFragment.
We're going to the text code or I could just go
to the name down there, MainActivityFragment
under the fragment name.
So when we ran the app earlier,
MainActivityFragment used the Fragment_Main layout
to display our recycler view.
What we're gonna do next is add the code
to swap MainActivityFragment for AddEditFragment.
We'll do that when the edit button's tapped,
so that the display will show the edit screen,
instead of the recycler view list.
When the user finishes editing,
we'll swap the fragments back.
So AddEditFragment will be removed,
and then MainActivityFragment will appear in its place.
But I wanna make one more quick change,
which is to add logging to our four fragment functions.
Let's go back to our file,
in this case the AddEditFragment.
So we need to first add our usual logging tag
at the top of the file.
And I'll add that to above the ARG_TASK setting.
So it's gonna be, or definition, I should say,
private const val_TAG is equal to AddEditFragment.
The actual logging itself,
we'll start by adding one in the onCreate method,
onCreate function.
We'll have that as the first line before the call to super.
So Log.d parentheses TAG comma,
double quote onCreate colon starts.
Just gonna take a copy of that to be easier
to change the other definitions that we add.
OnCreateView, I'm gonna paste that in as the first line.
And we'll change this to onCreateView.
Next onAttach, let's add one for that.
OnAttach starts,
and finally we're gonna add one to our onDetach.
OnDetach starts.
So now that we've created our fragment,
we're gonna write the code to swap it in and out,
in the next video.
And once you've seen that working,
we'll then have a look at the fragment lifecycle.
So, I'll see you in the next video.