(light music)
All right, so before we continue with the app
there's a few small typos that I've made,
I wanna actually correct those.
Firstly, in the app provider class,
in the delete function right down the end,
I've got that on the screen here,
I accidentally left in the word update
as the logging tag, so I'm gonna change that to delete.
And also the other thing that I want to fix
is in fragment main, fragment_main.xml,
you've might've seen this at the time
and I think I actually put an annotation on the video
about it, but we'll click in and have a look.
I actually left in the text for Hello World
and I actually pasted, I created a string resource
not for the main text, but for the second attribute
which is actually used just to show something
where there isn't anything on the screen for develop,
for development use in other words.
So I'm gonna copy that, I'm gonna paste that,
sorry, cut that out of there, I should say, not copy.
I'm gonna delete the Hello World and we're gonna paste that
there into our regular text property.
And now that's actually set up correctly
and we won't have Hello World showing on the screen.
All right, so I can close that down for now,
we've done that, and closing that provider as well.
Now there's also been another update of the content plugin,
so I wanna show you that there is a way of actually checking
whether a new plugin has been updated in IntelliJ
and you can come up here to tools when you're in the project
and the project is opened.
Come down to Kotlin and you can actually select
Configure Kotlin Plugin Updates,
and when you do that it'll usually tell you
whether there's a new version, and you can just click on
recheck now if you need it too,
but it actually says here that a new version, 1.2.51,
is available so I'm gonna instal that
noting that this will often come up
and actually prompt you to be updated anyway,
but I'm just showing you how you can come there
and check it yourself, so I'm going to download that plugin
remembering that there's a two-step process here.
At the moment the updated version of the plugin
won't be updated in our built Gradle files,
we'll need to actually go through and do that,
and you can see there that it's saying that
the plugin will be activated after the restart.
So I'm just going to do that,
I'm gonna restart Android Studio.
And eventually that'll fix this, so I suspect so
that the Gradle files will be updated automatically
or you'll be prompted in some way if you get it updated,
but at the moment if we go in there now
to our Project: TastTimer,
you can see that there's no indication that on here,
in here where at the moment that there's been an update,
but here it's now telling us it's an outdated Kotlin Runtime
so in other words, it hasn't prompted us to update
the plugin automatically, but it is now smart enough
to know that there's a new version.
So here it's actually saying it,
we can just expand it and have a look.
No surprises there because I've only
just installed it, 1.2.51,
if I click, care to click up that Runtime
that's the part I'm talking about that's not updated
automatically, so in this case we're just gonna go in there,
change the 50 to a 51, do a resync,
and that will then update it
to the latest version of Kotlin.
And sometimes it might be necessary to do a complete rebuild
and you can come up to build and select rebuild project
if you need to do that, that'll be if you get an error
or something weird happens, and on rare occasions also
you're making errors in a project that worked
before the update and you may have to go
up into the file menu up here
and select Invalidate Caches/Restart.
And you click on Validate and Restart which I won't do now
unless I get errors, and that's another way
of actually fixing things if you get
some weird errors after.
So I'm gonna click on Cancel to get out of that.
So you can see, in my case,
there hasn't been any errors added.
There's no more notes there about being outdated,
we can close that, close down the output
down the bottom there,
and let's continue on with the project now.
All right, so we've created our fragment,
we wanna write the code now to swap it in and out
when the user edits a task or adds a new one.
Now the code for that will go in main activity
which I've got open on the screen here.
Now at the moment, if we can scroll up to the top,
we've got a load of information,
a load of test code up here in on create.
So what I'm going to do first is delete that.
Basically gonna copy everything on what I've been working on
below the set support action byline
right through to the end of the function
including the closing log.
Delete that.
And let's also delete the various functions
that we created for testing our content provider,
that's the test delete, one on two, test update one on two,
and also our test inserts, so I'm gonna delete all of those,
'cause we're not gonna need those.
And we're left with now a much cleaner file
than what we've had before.
All right, so now at this point we're going to add
a new task when the menu item's tapped,
so we need to check that in the onOptionsItemSelected
which is where the menu processing occurs.
You could see that the code that Android Studio
generated returns the result of the one expression,
but that's not really suitable for how we'll be using it
so I'm gonna make some changes there to that.
So instead of having the return there,
I'm actually gonna delete that
and have a regular when loop there.
And on the next line I'm gonna start doing
and test firstly for R.id.menu_main_addTask.
And if that's selected then we want to call that,
call a function test, task rather, EditRequest,
passing null to that, and that's because it's a new task,
I'm gonna comment at the next line, the menu settings,
for now, I'm also again gonna change the else,
I'm gonna delete the else in fact.
I'm gonna copy the super.onOptionsItemSelected line,
I'm gonna cut that out, I said copy,
but I'm gonna cut that out.
And I gotta return, and the line that I cut out
and paste it back in there,
so it turns super onOptions ItemSelected.
So as you can see now we've got an option there
so if the user has clicked on the add option
that we've added, which is the plus icon for our menu,
we're going to call this function
that we haven't yet created, Task Edit Request.
So let's go ahead and create that now,
I'll put that immediately below
the onOptions ItemSelected function,
so it's gonna be a private fun, taskEditRequest,
and the argument will be task: Task?
And we'll start with the log, the Log.d(TAG,
and taskEditRequest: starts,
so some indication of the function starting.
And what I might wanna do next, I'm putting a comment here
is create a new fragment to edit the task.
Remembering that this function will be used for both adding
and editing tasks, so we're gonna go val_newFragment
is equal to AddEditFragment.newInstance,
and we're gonna pass the task to that function.
Then the next line we're gonna go with support
FragmentManager.beginTransaction()
and then the next line, and put a dot, replace,
then in parenthesis R.id.fragment, newFragment.
It's the one we just created on the previous line.
Then on the next line .commit().
And that'll be it, then we'll just put a Log.d
on the last line, (TAG, Exiting taskEditRequest)
All right, so that's just about all we need
to test the adding of a new task,
except though the code will crash at the moment.
And now if you remember in addEditFragments
on attach function we check to see if the activity
implemented the required interface.
Now any activity that wants to use addEditFragment
must implement its own saved click interface.
So let's do that for this class now for that reason.
So I'm gonna add it to the class declaration line
after the AppCompactActivity, parenthesis,
we're gonna put a comma, AddEditFragment.OnSaveClicked.
All right, and we now need to implement,
in this case just the one function,
so I'm gonna do that immediately below the,
actually I'll put it below the OnCreate function
and the onSavedClicked function
to be implemented to make it valid.
We've now got it to do in there as you can see.
All right, so at this point now we can run the programme
in the emulator, so let's go ahead and do that.
All right, just fast forward this bit until it starts.
All right, so the app's still running, as you can see,
so I wanna come over here and tap on the plus button,
you can see the AddEditFragment
is now appearing on the screen.
Now it's obviously not finished yet,
it's appearing on top of the main activity fragment,
as you can see, but we can see how easy it is
to add a new fragment to an app.
And just to confirm that I can actually come over here.
Woops.
I can type in the edit text boxes, Tim Was,
and just a number, you can see that's all working nicely,
so the edit's definitely working in our fragment,
but, again, obviously it's overwriting
the main activity fragment.
Now don't be tempted to rotate the device at this stage,
we've still got some work to do,
so the app will crash if you change orientation.
So I'm just gonna close it for now
and we'll go back to our code.
And before we finish the video I want to just have
a look at what we've done in the task edit request function,
so let's go and have a look at that again,
and work out why it hasn't worked as well as what we wanted,
so in other words, why it's overlaying,
and we can still see that fragment behind it.
So we've created a new AddEditFragment
using the new instance function on line 46.
We then get the support fragment manager for our app
and then begin a transaction.
Now the transaction, as you can see,
attempts to replace the contents of R.id.fragment
with our newly created fragment.
Now it's sort of worked, as you saw,
but it also sort of didn't,
because we ended up with the original content showing,
as well as our new fragment.
So let's check out this replace function.
Now don't be put off when you get something
that doesn't seem very informative.
This version of Replace is an overwritten version of Replace
with three parameters.
When you get something that just mentions
calling another method, follow the link
to get the information you need.
Again, you can see here that Calls, there's a link there,
and replace with three arguments there.
So I'm just going to click on that one
and this is ultimately the one that's actually called
with the three arguments.
And I'll just bring that up so we can see that,
so we can see the documentation for that,
and you can see that it says that it replaces
an existing fragment that was added to a container,
and if you read the description it talks about
removing all the currently added fragments,
then adding the new one.
But obviously that didn't work because the existing fragment
wasn't removed and if you just get back and check this out
we'll have a look at our content, .xml,
in our resources section, and layout, content_main.
And if you click on the fragment here,
the componentry under the name,
we've got learnprogramming.academy,
then we've got MainActivityFragment
that we specified for the main attribute.
So that was correct.
It has got a fragment widget, as you can see,
but what's not obvious is that this one can't be removed.
Now we're gonna have a look at the Google Guide in a moment,
it talks about adding, removing, and replacing fragments
in a fragment container, but what it doesn't say
is that it means any container except a fragment widget
which of course we're actually using.
So let's just check out the guide.
Quickly open a browser.
All right, so we'll just scroll down a little bit,
a short way down, there's a note about adding a fragment
to an activity.
Here we go, adding a fragment to the activity.
It's talking about two ways of including a fragment
in the view hierarchy.
The first way uses these fragment widgets,
as we've done so far, but below that,
just scroll down a little bit more,
it talks down here about pragmatically adding a fragment
to an existing ViewGroup.
So it's worth having a read through this page,
but just remember that when you include a fragment widget
in a layout it can have its original fragment removed.
What we can do and what we'll do in the next video
is use something like a frame instead.
So I will see you in the next video.