So I ended the last video by asking the
question, does it work?
So let's actually try running this
program to make sure that it does work.
So we're going to run it on our emulator.
Now we're going to go over here and click
on this little green arrow on the
toolbar, to run the app, then I'm going to
choose the emulator. Now I've probably
got a lot more emulators than you've
actually got in your system, and you can
actually see that some of these are
missing a system image, but the one that I've
got connected and currently using is
this nexus 4 API 26, which of course is
Android 8. So you want to select your
Android 8 device, your emulator, and I'm
doing that now, I'm going to click on
OK.
And I've already got it started so I'm
going to come over here, and we'll have a
look at what the app looks like on that
device. You can see down the bottom of
the screen there, that Gradle build is
running, and we've got a progress bar
that hasn't updated, but it is actually
processing away for the first time and
generating the build, the Android
application, and then sending it to the
emulator so that we can actually see
what it looks like. And keep in mind that
if you've got a slower computer and you're
short of memory, it's definitely worth
starting the emulator before you start
coding, so it's up and running and ready
for when you want to test your app. And
you can see that, in my case, I had the
emulator already running.
Okay, so you can see the app is now
on screen, and there's a couple of things
I should explain about it in case you
think that you messed up creating the
layout in the challenge. Firstly though,
let's test it, and when I click the
button the message is added, or should be
added, to the textView down here. So I've got
the name there, if I just put in my
name,
and then click on button, you can see the
button got tapped one time. And if we
click it again, the button got tapped two
time, and then one more time, you can see
that the text this time is the button
got tapped three time. So the actual
concept is working well. The text is
being added to the textView successfully.
What we should have done is cleared the
original text first, so we're going to do
that when we go back to the code. I'm
going to click just a few more times, to
see what happens once we get to the
stage of filling things up, and I'm
tapping, and you can see now, or rather you
can't see what's happening and that's
because the text is now
disappearing behind the on-screen
keyboard. Now that's the first thing you
might think you've got wrong, but it's
okay and that's actually normal behavior
on Android. Now the Plain Text widget
that we used when working in the
designer is an editText, and what an
editText is, is basically a TextView
that's been extended to allow editing.
Now obviously, on an Android device you'd
normally need the keyboard when typing,
so the editText widget has been
designed to cope when the keyboard's on
the screen. Now because you can't type
into a TextView, it doesn't havee that
behavior. So there's nothing wrong with
the layout as such - it's working as it
should. Now if you did want the TextView
to shrink to accommodate the keyboard,
you could do that in your code, although,
it may well be easier to use an edit
Text, then disable it so that text can't be
typed. That way you get the benefit of
the added functionality an editText
has, for dealing with the keyboard, while
still having something that
behaves more like a TextView. Now we'll
be doing that in a later section just so
you can see how it's done, but the second
thing I want to show you, is, if I now
dismiss the keyboard by clicking on this
down arrow and I'll tap a few more times,
or rather, because I'm running an
emulator I'm using my mouse.
Right til we get to the bottom of the
screen on my emulator, and I'm still
tapping now but you notice that
the TextView doesn't scroll. So once
again you haven't done anything wrong in
your layout. The multi-line editText
widget Scrolls when you set the
scrollbar, but to make a TextView scroll,
there's an extra step we need to do in
the code. Now the final thing that needs
to be fixed is that the message itself
isn't very good. The button got tapped two
time, got tapped three time, etc. well
that isn't very good English. So overall,
though, the program seems to be working
fine so far, and we've successfully
linked code to a button so that it
responds to clicks and that it actually
does something.
But let's fix those three issues, though,
that we've talked about and we'll do
that by going back to the code. Now
firstly, clearing the existing text from
the TextView when the program starts is
really easy, but before you switch to the
layout to delete the text property, I'm
going to show you another way. So
clearing it in the layout is a perfectly
good way to do it, by the way, but
essentially, when you're starting out it
can be very useful to leave text in the
TextView widgets, as otherwise it can be
really hard to tell that they're there
without looking at the blueprint or
selecting them. I'm going to show you a
way around that later, but another way to
clear it is to set its text property in
code and provide an empty string. So what
I'm going to do is add a few lines of
code now. We're going to just scroll up
here to the original definitions of the,
well actually, we've got our original
declarations up here, but then when we've
added our findViewById calls for each
below that TextView, we were going to
initialize it. So we're going to put text
View?.text =
and two double quotes. Now unlike append,
which adds text to any already
there, setting the text property
replaces all the texts in the TextView
with the new text. By providing a blank
string, which we've done here on line 23,
that's two sets of speech marks with
nothing between them, two double quotes
in other words, we replace any existing
text with nothing and that effectively
clears what's already there on screen.
Alright, the next thing to do is to add
an s after the word time if the button's
been clicked
more than once, so that the English is
correct. And what we can do is add the
code for that. I'm going to start by
adding some code to line 29. So what I'm
going to do is put an if clause in there,
so if parentheses numTimesClicked,
if that is not equal to, so exclamation
mark equal one and curly braces. Then
we're going to put textView?
dot append and parentheses, then in double
quotes yes.
So rather than checking for a number of
clicks being greater than one, I've
checked it for not equal to one. That way,
if we ever change it to record the zero
before the button's clicked, it would
still read correctly, and that's because in
English you'd say zero times and not
zero time. Now that's not true in all
languages though. In fact, Android has
full support for dealing with
translations into other languages,
including the different way of phrasing
things when there are zero, one or more , 185
than one of them. So it's a good idea to
design programs with international users
in mind. Now I'm not going to do that
right now, though, because we've already
got enough to think about at the moment.
But we will be coming back to this
because it's one of the reasons for some
of the warnings we didn't resolve in the
layout designer. Alright, so at this
point that's two of our problems sorted.
There's just the scrolling to handle now.
Now I mentioned that the TextView
doesn't automatically enable scrolling,
just because we turned on the scroll bar,
but the editText widget does. In fact,
the editText just does what we're
about to do, automatically when scroll
bars are enabled, and that's one of the
ways that it extends the TextView. So
what we're going to do, though, is we're
going to add some code back up here, onto
line that 24, and this is just going to
make the TextView scroll. So we're going
to type textView?. and
select movementMethod, as you can see
there, equals and then we're going to
type scroll, or Scrolling, I should say,
MovementMethod and parentheses on the
end. Now assigning a new
ScrollingMovementMethod to the text
Views movementMethod property, is all
that's needed to make the TextView
scroll. Now this only works because we
added a vertical scrollbar in the layout,
so that step was still needed. Al
right, so at this point now, it's time to
test the program again, just to make sure
that we've hopefully ironed out all these
problems. Now the emulator was running
before but this time, now that we've got
a deployed version of the program, the
instant run should automatically update
the app for us on the virtual device and
restart the app for us fairly quickly. So
I'm going to run that and then tab over
to our emulator.
We should find it's a lot faster to
start this time. Alright, so there's our
app again. Now firstly, notice that we're
starting with a clear area now, so
clearly the dot text setting that to
an empty string worked. I'm going to click the
button a few times - the button got tapped
one time - and notice we've now
got the correct s being added on the end,
two times, and tap it a few more times,
and now if I dismiss the keyboard, and
let's see what happens if we get down to
the bottom, will that actually scroll for
us. And you can see that's still not
scrolling at this point for us. However,
we can scroll it, as you can see here, and
see the rest of the text by scrolling it
up and down. It disappears if we haven't
selected it, in other words, if you didn't
have a finger and moving it up and down.
If you're using a real device, or in my case,
I'm using the mouse, we can see that it
does now scroll for us. Keep in mind,
though, that emulators are just that -
emulators. They're not real devices and
it's rare to control a real Android
device with a mouse. It is possible, but
of course, most people won't do that,
so the mouse here is behaving like a
finger on the phone's screen. And again,
I'm mentioning that because the scroll
indicator, as you can see, clearly doesn't
appear until I click and hold down the
mouse button on the TextView. When I did
that we were able to then scroll up or
down, depending on where we are on the
screen. And the other thing I want to point
out here is that what we can see on the
right hand side, that's a scroll
indicator, not a scroll bar. On your
operating system, Windows, Mac or Linux, you
scroll by dragging the scroll bars. but
on Android you scroll by dragging the
screen. So keeping the mouse button down
and moving up and down as I'm doing now,
the contents of the TextView are
scrolling, so that's how you'll do it. Al
right, so I think overall that's looking
a bit
better. There's still a slight problem,
though, and if we go back up to the top,
you may have noticed it. We've still got
this blank line up here. So it's putting a
blank line before the first message, and
actually i think that would make for a
good challenge. Alright, so the challenge
is to change the code so that a blank
line isn't printed before the messages,
but is printed after them. So that's your
our challenge. I'm going to pause the
video now. See how you go about making
that change, and come back and you can
actually see our solution. See you when
you get back. Alright, so there's always
more than one way to code things - even a
simple change like this one. So the real
test with all the challenges in the
course is, does it work? So if your
messages print out fine, with each one on
a new line and no blank line at the
start, then you've completed the
challenge. So my solution, wwll let's have a
look at that. What I'm going to do is
actually change the output. I'm going to
get rid of the \n at the start of the
string. What I'm going to do is make a
change to add it at the end. I'm going to
come down here to our if test. I'm
going to add a \n there. Then
what I'm going to do is change the code
for an else, else textView?
dot append double quotes and in
parentheses, \n, and obviously, I
removed the \n at the start as
well. So we're consequently making sure
there's the backslash n will appear on
any text that, or at the end of the line of
any text that is showing, or is being
outputted onto the screen. Alright, so
let's go ahead and run the program now,
and check that the challenge
does actually work. Alright, so we're
going to just press the button,
press the button a few more times, and you can
see it seems to be working a lot better
now. We've still got a bit of a gap there
but that's just a normal gap spacing now,
between controls, as opposed to the
problem before. We had a much larger gap
and that was caused by the initial
backslash n that was at the start of the
line, before we actually started
outputting.
So that's the challenge sorted out. There
is still a problem, though, and I'm going
to show you how to fix that in a later
video. So what I'll do first is just make
sure that we can still scroll these.
You can still scroll it so that's still
working as well. Alright, but again, I've
mentioned that there's still a problem,
though, and this problem I'm about to
show you, I'm going to show you how to fix in
a later video. Now remember that I said
you should always test your code in both
portrait and landscape. Now when I go
ahead and rotate this, so rotate the
emulator into landscape, you can see
over here, I'm going to do that. You can
see as soon as I did that, all the messages
disappeared. And just to confirm that, if
I add a few more now in landscape
mode, again, I can still scroll as you can
see there. But if I then just move this
over so we can see it a bit better, and
if I rotate back to portrait, you can see we've
got the same problem - the messages are
disappearing again. I'm going to show you
how to deal with that in the next video.
For now though, I'm going to tell you
that the reason it happens is that
Android destroys your activity when the
device orientation changes, then creates
it again in the new orientation. Now that
might take a moment to sink in because
it sounds like a very strange way to do
things.
Destroying the activity just because the
user rotates a phone seems a bit drastic,
but in fact, it's a very elegant solution
to a problem that's more complex than it
may appear to be. Now it's true that
that is what Android does, and you
know it works because you've rotated
your phone loads of times and your apps
have carried on with the new screen size
with no problems. Now in the next video,
we're going to start extending the app
so it does something a bit more useful,
and then we're going to look at how to cope
with changes in orientation when your
app is running. So I'll see you in the
next video.