(electronic jingle)
(typing)
A few videos ago, we looked at different ways
to get references to our widgets from Kotlin code.
So let's review the code again
and quickly go over what we did.
Now, for the first two widgets, the edit text widgets
for the result and the user's input, we used the approach
that would be familiar to Java programmers.
So we declared the properties first on lines 15 and 16,
as you can see here, then called find view by ID
in the on create method to get the references
to the widgets in the layout.
And we had to declare the two properties
as late init, but otherwise that's pretty standard code.
Now, for the display operation text view,
we used a lazy delegate.
This is the code on line 17.
Now, the find view by ID function isn't called
until we first access the display operation property
and it's in cached so that find view by ID
doesn't get called repeatedly.
Now, we had to give Kotlin a hint
so that it knows what type to cast the view to
and we did that by using the diamond operator
to specify text view when calling find view by ID over here,
again on line 17.
Now, Kotlin has a number of extensions for Android
that can simplify this even further,
and one of these lets us effectively import the resources
and then refer to them as normal properties in our code.
First, we have to import
what are called synthetic properties,
and for our activity_main layout,
that's gonna look like the following.
So it's basically below the other imports up here,
we type import
kotlinx.android.synthetic.main.activity_main.*
So after adding that import, all the widgets in our layout
can be accessed just like any other properties
that we imported into our code.
Now, it's easier to fully appreciate that by seeing
it in action, so I'm gonna modify our existing code
to make use of these extension properties.
As I do it, notice that the only thing I'm doing
is deleting code.
And in fact, what I'm gonna do is I'm gonna start
by commenting it out just so you can see how much code
we can remove.
So I'm gonna start by commenting out the three lines
up here, our definitions on line 17 through 19.
And next I'm gonna come down here to the definitions
in the on create function
and I'm effectively going to comment all those out
right down to the button plus definitions,
right down here to the button plus.
I'm going to come up here, including result
and comment all of those out
right down to button plus.
So, we've removed all the properties and local variables
and all the boilerplate code
that just calls find view by ID.
As you can see, in this particular programme,
that's a fair bit of code.
Now, we do have two errors.
That's because we called the text view property
display operation but the ID of the text view is operation.
So we just have to change the old property name
to the correct ID on the two lines that we've got an error.
So first, if I click on the first one,
you can see we've got this display operation,
again I mentioned that the text view name is operation,
so let's change that.
Operation.
And then look at the second error,
display operation again, make that operation.
Now there's two other lines we can remove as well
because if you go back up to the top and have a look,
we've actually got two unused imports,
although Android Studio may have deleted them for you
if you told it to remove unused imports in the settings,
and in my case I have done that, and the two imports
that had been removed are android.widget.textview
and android.widget.edittext.
In my case, you can see they have both been removed
because I've got that setting
to basically remove unused imports automatically.
What I'll do is start my emulator
because we're going to test the app again
just to make sure that it still works.
And it's obviously a good idea in this scenario,
given the changes we've made,
to do a test run just to make that things still work
as they were working before.
So we'll just fast-forward this.
Alright, and we'll just run our app
to make sure it still works.
Alright, so let's try our calculations.
So 25 multiplied by four equals,
and multiplied by three equals, that's 300, that's correct.
Let's now divide it by nine, multiplied by three equals 100.
So that's working fine without all the code
that we've now removed.
Let's just go back to the code
and have a look at how this all works.
So when we added that line, which was on line 10
which is now on line seven, this import,
this kotlinx.android.synthetic.main.activty_main.*
the Kotlin extension plugin creates properties
corresponding to each of the views in the layout.
Now in this case it would import them
from activity_main, because that's the name
that we provided to the import, again on line seven.
Now behind the scenes, Kotlin adds a caching function
to our class.
Now the first time we access one of the properties
by the using the views ID, the caching function calls
find view by ID to get a reference to the view.
It then stores that so subsequent accesses
don't result in further calls to find view by ID.
I think you'd agree that's pretty neat,
'cause we can refer to the views in our layout
without all that boilerplate code that we had before,
all that code that I've now commented out in this class.
Now I'm gonna leave the comments for now
so that they'll appear in the source code for this video
in the resources section.
What I will do is delete the comments
at the start of a future video
before we make any more changes to the code.
Now one thing that we couldn't see
is that Android Studio will add the import for us.
We couldn't see it because we'd already added code
that used the properties, but you'll see the import
being added to our next app.
I'm gonna be using this approach in most places
from now on.
There's at least one bit of code where I won't,
but I'll explain why at the time.
So there are several ways of getting references
to the views or widgets in our layout
from our Kotlin code.
You'll find all ways being used in code
that you'll come across and there's nothing right or wrong
about any of the approaches.
I think this last way results in the simplest code
which is why I'm gonna be using it going forward.
Now if this method wasn't available,
I'd prefer the lazy delicate method wherever possible.
If the widget reference has to be read write,
then late init is the next choice.
And you can only use lazy with val properties,
not with vars.
In the next few videos, we're gonna go back to layouts.
Our calculator doesn't look too good in landscape
and that's because the buttons aren't centred
and we're a bit pushed for space vertically,
so we're gonna look at ways to tidy that up.
So let's work on that in the next video.