G'day everyone, welcome back. At the moment, our About dialogue can only be dismissed
by tapping away from it on the device screen. But it's also usual to dismiss
this type of dialogue by allowing the user to tap the dialogue itself, or by
providing an OK button. We'll look at both ways to implement that, in this video.
I'm going to do both, one after the other, because there's a reason why
tapping the dialogue to dismiss it isn't really appropriate in this case. In fact,
there are two reasons. So we're not going to dismiss the dialogue by tapping on it
in this app, but we'll have a quick look at how to implement that behavior.
We just have to set an onClick listener to the dialogue's view. We've set on click
listeners on buttons and ListView items, but you can add them to any View in
Android. Anything you can display on the screen can be made clickable.
In MainActivity, I'll delete that commented out code that didn't work, because you've got
the source in the last two videos if you need it.
We'll take this line out too,
and then we'll add our listener.
We've seen code like this lots of times now. The difference is that we're setting
a listener on a View this time, rather than a button. That's one way of allowing
the user another way to dismiss the dialogue, but in our particular case, it's
got a couple of problems. I'll run the app to make sure it works and then we'll
look at what those problems are.
With the about dialogue showing, I can click somewhere near the copyright
message and the dialogue's dismissed. We also get the message in logcat;
entering message view dot onClick.
So that's working fine and shows you can
attach onClick listeners to any type of View. The first problem is, that our icon
and title aren't part of our View. They were added by the dialog builder. If we
launch the About dialogue again, and tap near the icon or title,
nothing happens.
The version number's part of our layout, so tapping that will dismiss the dialogue,
but from our user's point of view, it's a bit hit or miss. If you include the title
and icon in the layout, everything would work fine. In that case, this would be a
suitable approach, except for the second problem. We've made the links in the text
clickable. The way that works, is that Android intercepts taps on the entire
line of text, not just on the link itself. If I tap level with the URL, but away to
the right, it's still part of the TextView and we've enabled autoLink on the TextView.
So, I'd suggest that dismissing the dialogue by tapping it, when you're
also showing autoLink text, isn't an ideal way to handle things.
If you're not showing autoLink text and your layout covers the entire dialogue, then the code
you've got will work fine.
OK, let's see how to add a button to the dialogue instead.
I want to leave the current code in, so it's available in the code you can download.
I'll copy the entire function and comment one copy out so it's still available.
Android Studio has a neat feature to make that a lot easier.
Select the entire function, including the annotation at the top, and use ctrl D,
command D on a Mac.
That works better if you also include the blank line after the function.
The copy remains highlighted, so we can use control / (command / on the Mac)
to comment the copy out. We can get the Builder to add a new button to the dialogue.
Just like we had to do with the title and the icon. Though we have to add
the button call before the call to builder.create, otherwise the button won't
appear in the dialogue.
We've seen the setPositive button function before, in our AppDialog class,
and this is doing the same thing. Run the app, and our users can now dismiss the dialogue,
by tapping away from it or tapping the OK button.
So, that's dialogues in a nutshell. They've turned into a large nut, though.
I'm going to finish this video with a comment about that last bit of code.
Looking at the code in the setPositiveButton function that we just
created, we perform a null check and also check that the dialogue is showing,
before calling it's dismiss function. Because Kotlin can't be sure that aboutDialogue
hasn't been changed on another thread, we need to use a safe call operator.
You may be wondering why it's necessary to check that the dialogue's showing before
dismissing it. If the dialogue's not showing, it's going to
be very hard for the user to tap the button. That may be true, but in an
event-driven system like Android, you can never be completely sure about the order
that events happen. If the device is rotated, and the user accidentally taps
the button at just the wrong time, it may be possible for our code to be called,
very slightly after the system's removed the dialogue. We can't be sure that an
event such as garbage collection, or an incoming phone call, won't slow things
down just enough, to give a delay before our function's called.
Trying to duplicate a series of events like that, so you can test it and be completely sure that it
will never happen, is not going to be easy. If an event happens, though, you can
be sure that you've handled it correctly. If something doesn't happen, you can't be
sure that it never will. Just because you can't get it to happen,
doesn't guarantee that it won't. So, I prefer to program very defensively in
these situations. The safe call operator makes sure we don't try to call a
function on a null object. At the moment, the check for isShowing isn't strictly necessary.
If you look at the code for the dismiss function, and follow it back
to the dialogue class dismiss dialogue function, you'll see that there's a check
that the dialogue is showing in there. We're not writing a time critical bit of
code here, and I prefer to be safe, rather than find that Google has
changed something and my code crashes. Alright, I'll accept Android Studio's
suggestion that we can replace the dialogue and the which arguments with an
underscore. In fact, I'll get the light bulb to do that.
You have to get the light bulb to appear twice, once for each argument.
The compiler can optimize the code, if it knows that the arguments aren't used,
and using underscore for the name is how you tell it that. In the next video, we'll see
how to make the links clickable on older Android versions.
See you in the next one.