(uplifting music)
(keyboard typing)
In this video, we're going to
create an app that does more than just displaying
widgets on the screen.
We'll start by producing some code,
so that we can get the button to actually do something.
Then we'll extend the app to see how to include a menu.
Now, in future sections,
I'm gonna show you the finished app running first,
so you know what it is we're creating.
But I'm not gonna do that here,
partly because the app is very simple,
and partly because we're gonna change
what it does half-way through.
To start with though,
I'm gonna set you a challenge to build the lay out
for the user interface that the app will use.
So, to help with that, here are some rules governing
how you can you use constraints.
So, as you can see, the rules are pretty simple.
Each view must have at least two constraints;
one horizontal and one vertical.
You can create constraints only between a constraint handle
and an anchor point, that share the same plane.
So in other words, a vertical plane,
the left and right sides of a view,
can be constrained only to another vertical plane,
and baselines can constrain only to other baselines.
For example, you can't constrain
the top of one widget to the left of another.
Now each constraint handle
can be used with just one constraint,
but you can create multiple constraints
from different widgets to the same anchor point.
Now if you don't constrain a widget,
both vertically and horizontally,
Android won't know where to place it on the screen.
Widgets that aren't constrained horizontally
will move to the left of the screen,
and widgets that aren't constrained vertically
will move to the top.
Now a constraint on a vertical edge
can only be connected to another vertical edge.
So in other words, you can't constrain
the top of one widget to the left side of another,
and that's not really difficult to remember
as it's a bit obvious.
Now each constraint handle can only be connected
to one anchor point.
An anchor point, by the way,
is a constraint handle that's the destination
of a constraint, or an edge of the screen.
Now anchor points can have more than one constraint
going to them though.
Again, that's easy to remember.
You can constrain multiple widgets
to the edges of the screen, for example.
Alright, so let's go ahead and create
the project we're gonna be using here.
We're gonna click on Start a new Android project.
We're gonna call this one Button Click App.
Company name is going to be learnprogamming.academy.
And we're gonna make sure that we've included
Kotlin support by ensuring that the check box
is checked to the left of that.
That's if you're using this,
building this app in the Kotlin course,
but if you're building this in the Java course,
you wanna make sure that Include Kotlin support
is actually unchecked.
Alright, so click on Next.
Now on this screen, we're gonna make sure
that the minimum SDK is API 17,
and everything else is unchecked.
So you can see here that I've got API 17 selected,
which is Android 4.2, and everything else is unchecked,
and click on Next.
Now you wanna start off with an empty activity.
So, choose that, or the closest one to it
if things have changed, and click on Next.
Now the suggested names here,
for the activity and layout are fine,
so make sure that the two options here,
the two boxes for Generate Layout File
and Backwards Compatibility, AppCompat,
make sure that they're both checked as well
and click on Finish.
Now once the Gradle build is finished
and the indexing is complete,
we can actually continue.
You can see the Gradle build
is running down the bottom there,
so I'll just give that a moment to complete.
Okay, then it's all done.
So, once the Gradle build is finished as it has now,
we can open up the res layout folder.
So I'm gonna come over here.
If your project pane's not showing for some reason,
or perhaps you've got a screen that looks like this,
click on the Project pane to the left there,
and make sure that you're in Android view
by selecting Android if it's not selected.
Then you wanna expand app,
and expand res, and expand layout.
Then we wanna double click this activity
_main.xml
to make sure that that's on the screen.
And if it was already existing up here,
just double click it,
and then I'm gonna click on this Project pane here
to close that off, to give us a bit more space.
Alright, now time for the challenge.
So the challenge is to create a layout
containing a Plain Text widget, a Button, and a TextView,
and arrange them so that they look like
the image you can see on the screen now.
Now if the screen size or the orientation changes,
the Plain Text and Button widgets
must remain at the top of the screen,
with the button over to the right,
and the Plain Text filling the space
from the left edge up to the Button.
Now the TextView should start just below the Plain Text,
and should expand to use as much as the screen as it needs
when the text in it grows.
It should also be scrollable vertically, as it gets bigger
than the available space on the screen.
Now all margins, set those to 16dp.
And as this is the first real challenge in the course,
I've included images of the Design and Blueprint,
as you can see on the screen there now.
So take a good look at those
and then pause this video,
and see if you can go ahead and create that interface,
and start the video
when you're ready to come back and see me,
go through the solutions.
So pause the video now.
Alright, so, hopefully you've managed to get that working,
or to get a large component of it working anyway.
So the first thing we wanna do now to build this interface,
is we're gonna delete the Hello World widget
that was created for us.
So let's start by doing that,
so I'm gonna click on Hello World,
and click that in the design or the blueprint.
Delete that. I'm gonna press the DEL key.
Alright, so I've deleted the Hello World widget
that was created for us.
Then we're gonna drag the three widgets we want
onto the design, and place them roughly where we want them,
using the guidelines that appear as, well, as a guide.
Now the guidelines appear, when you've dragged a widget
to a recognised position such as
16dp away from the edge of a layout.
So, by moving the button around a bit before dropping it,
you can actually get both horizontal
and vertical guidelines to appear,
and you'll see that shortly.
Now, if they don't appear, it doesn't matter.
It really only takes seconds
to fix up the margins up manually anyway.
So I'm gonna start by making sure that
autoconnect is enabled, and you can see here that
we haven't got a slash through the autoconnect,
so that's enabled, and the other thing I'm gonna do
is make sure the default margins is set to 16dp.
So I'm gonna come over here because it said to wait.
I'm gonna click on 16 or I could've typed that,
and we're now good to go.
So next I'm gonna drop a button over to the right.
Now we could've dropped the Plain Text widget first.
The order that you place the widgets on the layout
isn't really important here.
But we want the button to be constrained
to the top and right edges of the layout.
So I'm gonna make sure that it's correct, and then create
any constraints that aren't done automatically,
and then we'll also check the top and right margins.
So I've got all under here, under the palette.
I'm gonna come over here and just drag it over
to the right-hand side,
making sure that both guidelines appear.
We've got the horizontal and vertical guides, release.
And because we've got Autoconnect turned on,
you can see it's automatically added
a constraint at the top and right edge,
which is what we want here.
And also we can see that our margins,
16dp for the top, and 16dp for the right are both there.
If they're not correct for some reason for you,
you can just click on the drop down
and change the number, as appropriate,
and of course you can add a constraint manually,
if for some reason it wasn't added for you.
Alright, so that's the Button.
Next we want the Plain Text widget,
and that's over here in the text category.
Now the Plain Text widget
is gonna be placed on the left-hand side,
and again if I start this, and drag it around,
you can see that if I'm moving it slowly,
we can get those guidelines to appear for us automatically.
So once I release, we should find that the left
and the top constraints get added automatically,
and we can see that that's the case over here,
and I'm just checking to see that 16dp for the top margin,
and 16dp for the right margin.
Now we also want this constrained to the
left of the button, and more than likely
that hasn't been added automatically,
and it wasn't added for me.
So we're gonna add the right-hand constraint
to the left of the Button manually.
So I'm just gonna click on over here,
and drag that over to the Button,
so that our Plain Text widget is now
constrained to the Button.
Now Autoconnect may also have added a bottom constraint
to the bottom of the button.
That's not a problem in our app, but it could be in others.
So if you are seeing a constraint
from the bottom of the button
down to the bottom of the screen,
remove that, if one was created.
Alright, now at the moment, the Plain Text widget
isn't set up to fill all the available space left to right,
so we wanna change the layout_width in inspector
to match_constraint. So I'm gonna click on that
to make sure it was selected,
and we're gonna change the layout_width to match_constraint.
And you can see that's now growing
to fit all the available space.
So in other words, we're allowing it to fill the space
from the left of the screen, up to the button.
Now, to allow it to fill the screen vertically,
you might also change the layout_height to match_constraint.
But if I try and do that,
something weird happens, as you can see there,
and the widget shrinks vertically to just a line.
The reason that happens is because
there's no bottom constraint,
so there's nothing to define its bounds, vertically.
Now if you're going to use match constraint,
then the widget has to be constrained on both edges,
top and bottom in this case.
So a better option here,
would be to leave the height set to wrap_content,
and that's because it allows the widget
to expand vertically to display all the text it contains.
So I'm gonna go ahead and do that,
change that to wrap_content, and that fixes that up.
And the other thing to check here,
is to make sure that the margins are set correctly.
(mouse clicking)
And sometimes you'll find
there's a little bit of a weird bug there.
(mouse clicking)
And you can see that that's showing as 16.
If I change that to 8, you can see it briefly moves over
and briefly moves back again -
this is the left margin I'm talking about,
for the Plain Text.
Now, we want the text to start from the left-hand side,
but the widget is automatically set to centred.
Now as more text is entered, it'll expand right,
but it should start from the left edge of the layout.
So to do that we wanna change the horizontal slider to zero,
so that it's hard fast and to the left.
So I'm gonna change that slider to zero.
Now you may or may not get a problem when you do that.
If your editText widget,
has a left margin showing in the design or blueprint,
then everything's fine. But there's a bug
in Android Studio - there has been for a while,
even back in version 2.3 stable release.
So it attempts to cater for right to left languages,
and uses the layout_margin start,
and layout_margin and attributes.
Now, that might be instead of or in addition to,
the layout_margin left and layout_margin right attributes.
So the exact effect of the bug changes
with different versions,
so it's not really easy to demonstrate
exactly why it happened on your screen,
but hopefully everything works fine,
and the bug's been fixed by the time you watch this video.
But to show you one way the problem messes with the preview,
I'm gonna make a change to the margins
for the editText widget.
So I'm going to, over here,
for the editText widget, Plain Text, I'm going to
click over here to get to the extended attributes,
and I'm going to expand the layout_margin, here.
And what I'm gonna do is delete the settings,
if there's anything in there for the right,
and I'm gonna set end to 16dp,
which is currently set at the moment.
Now it may already be using end as it was in this case here.
In which case there's nothing obviously
that you need to change.
But you can see that the net effect of that is that
the editText is showing hard over
against the left-hand edge, with no margins showing,
and that's been the case all along,
since I first dragged this
Plain Text or editText widget onto the screen.
Now I'm not exactly sure why
it's the left margin that's vanished,
when it was the setting for the right margin
that was changed, or in this case has been set,
but it's a bug, and that's the nature of bugs.
Seems worse if you have different pairs
specifying the left and right margins, for example,
using left, and you can see here we've got
left and right specified, or start and right.
So, you will get strange results with margins, or if you do,
check the margins
in the attributes section, as you can see here.
Now, the layout_margin start and end attributes,
well they were both introduced in API 17 Jellybean,
and will actually be ignored on earlier Android versions.
Now what that means is,
that the margin won't be set on earlier versions,
unless you've got layout_margin left
and layout_margin right attributes.
Now you can use them as well as the start end versions.
The new attributes are ignored on older versions.
So once you've actually got your margins correct,
check the layout margin attributes, and make sure you've got
both sets of attributes for each margin.
So if you set left, then you also wanna set
start to the same value, and if you set right,
then set end to the same value.
Now we're targeting API 17 and above,
so you might think you could just
use the start and end attributes.
That's correct, you can. But, if you later change your mind,
and target API 16 or above,
you'll have to go through every layout in the app,
setting the left and right margin attributes
for every widget.
Now, Android Studio may hopefully start
doing that for us, in a future release.
But right now, it's much more reliable
to just set both pairs of attributes
when you're creating the layouts.
So just click on the Button to select it,
and set the end margin
if it's not already set, to 16dp as well,
and I'm gonna set, in my case,
because right wasn't specified,
I'm gonna specify right to be 16dp as well.
I'm gonna click on start and change that to 16dp as well,
so they both match, and you can see now that I've done that,
we've got left 16dp, start 16dp, end 16dp and right 16dp.
You can see that when I set that,
we've now got the margin correctly showing,
in the design and blueprint.
So that's good, and that makes everything work out okay,
but watch out if you change the margins in the inspector,
and check the margins again like I've just shown you,
if you do.
Alright, so, the Text View, well that's gonna go
directly below the Plain Text widget,
but what we'll do is we'll finish the video here,
and we'll start up in the next video,
where we'll go ahead and add that Text View.
So I'll see you in the next video.