So currently, this is what our app looks like.
We've got seven keys, one in each color, and they all manage to play different sounds. But at the moment,
the layout isn't great, right?
It's only taking up a small proportion of the screen. And it doesn't really look like a Xylophone app
yet.
So how can we get it to look like this instead? Where we have a black background so that any part that's
not a key is blank.
And we also have a full width keys that take up all of the available space in the horizontal axis and
all the vertical space is evenly divided by these seven keys.
Now there shouldn't be anything new here because we've covered all of this when we explored layouts
in the Mi card app.
So I want to set this to you as a challenge to see if you can make the user interface look like this.
Pause the video and try to complete the challenge.
All right.
So here's the solution.
First let's change the background color of our scaffold to black.
So we're going to go into our scaffold widget.
We're gonna add a property that's changing the background color to colors.black.
There we go.
And let's just confirmd to make sure that it worked.
All right.
So here's what we've got so far. The white background has turned into a black background, and it's blended
seamlessly with the edges.
So now let's go ahead and try to expand our buttons.
So the keys will distribute themselves along the main axis of our column.
And to do that, if you remember, we had to use the expanded widget. So we would wrap whatever we want to
expand inside an expanded widget, and we're going to use the OPTION + ENTER to bring up that light bulb
menu, and we're going to wrap with a new widget that's going to be an expanded widget.
Now at this point if you only have a single expanded widget that will try to take up all of the space
that's available to it.
So it looks something like this, which is not what we want.
We want all of these keys to divide the amount of height that's available by themselves so that they each
take up the same amount of space.
So to do that, we have to add all of these other buttons inside the expanded widget.
Now this is a good point to mention that when you notice any of these widgets enclosed in a red box,
at this point, if you go to another widget say the next flat button that you want to embed in a expanded
widget and you use that same trick of doing ALT + ENTER or OPTION + ENTER, then it doesn't really work because
it's still held on to this widget.
So this is a quirk of Android Studio and you can simply get rid of the red box by just hitting the TAB
key anywhere where there's some empty space.
And that gets rid of the selection and we can now again use our OPTION + ENTER or ALT + ENTER.
So let's go through our file and let's add expanded to all of our flat buttons.
So now that we've wrapped all of our flat buttons inside an expanded widget,
now all of our buttons should now expand to the amount of height they can possibly have.
So now all our buttons should have the same height and it should be evenly distributed in our column.
And you can see, our flat buttons are now evenly distributed in terms of height, at least, in our column.
But the only thing is the width that each button is taking up is still the default amount that they're
told to take up.
So in order for it to go all the way to the edge, we have to change the cross axis alignment of our column.
So we find our column widget and we're going to add a cross axis alignment and we're going to make it
stretch so that it takes up the entire width of the screen, or as much width as possible basically.
So this is the solution to our mini challenge, and I hope that was a good review of some of the concepts
that you learnt in the Mi card module
where we did mostly things such as layouts and axis alignments et cetera.
So now we've basically completed our user interface. It looks pretty much the way that we want it to.
But if we take a look at our code, you can see that it's incredibly repetitive.
There's so many lines of repeated code.
And if you look at these little sections of expanded widgets, they're extremely similar to each other.
They're all expanded widgets.
They each have a child of a flat button. The flat buttons each have a color.
And when they get pressed, they all call the play sound method up here.
So, it's not great to have all of this code
that's the same, because let's say that we wanted to, I don't know, change something about our buttons,
for example if we wanted to give it, you know, some piece of text that says 'This is a button',
then we would have to do this to every single one of our buttons for this to be carried out everywhere.
And as you saw even previously when we were just adding the expanded widget around all the flat buttons,
it was painful enough.
So how can we reduce all of this code redundancy and try to get our code just a bit tighter?
Well we can probably extract a single one of our widgets,
right?
What if instead of creating this thing many many times over,
what if we tried to use a function to create this instead?
And we call that function seven times, instead of creating it from scratch every single time.
Isn't that what functions are for, right?
So in order to do that we're going to remove a single expanded widget, and I'm going to use COMMAND + X
or CONTROL + X to cut it out of my column. And up here just below playSound,
I'm going to create a new function called buildKey.
And this function is meant to help me build this expanded widget. And I want to be able to, instead of
having to have all of this repeated code, I'm going to delete everything right up until the final expanded.
So just before it says widgets, and I'm gonna delete all of that.
Instead I want to be able to call my method buildKey seven times, and this should build my widget each
time.
So let's just check to make sure I've got enough
1, 2, 3, 4, 5, 6 & 7 so perfect.
So once this starts working, every single widget will be built using our new function called buildKey.
And it will build an expanded widget with a flat button inside with a color and also a sound that gets
played.
Now there's just a couple of fixes that we have to make here.
Firstly, at the end of each line of code in a function, we know it has to end with a semicolon. And that's
just the grammar of functions. As in English language
we have the full stop, in programming when we have a function and we get it to do something or execute
something, we have to tell it where it's the end of that line of instruction.
But our code still have some errors. And all the errors are down here, and they all say the same thing.
The expression here has a type of void, and therefore cannot be used.
What is this void that they're referring to?
Well it's because each of our build key functions have that void keyword here that we've so far tried
to avoid talking about.
And the reason is because this will involve learning about the third type of functions, which is function
that not only have a body, as in some instructions that it needs to carry out when it gets triggered, but
also it can have a input, as we've seen, by putting in a argument inside the parentheses.
And finally the third type of functions that we want to talk about are the type where it can actually have
an output. So something can come out of this function once it is called.
And right now, this function, our buildKey function, doesn't actually have an output.
It's basically a type 1 function right?
It doesn't even take any input.
So if you are somebody who already have experience programming in other languages, you can solve this
problem and you can get rid of this error and get it to produce seven buttons on screen that all play
the same sound that all have the color red, then you can skip the next lesson. But if you can't, then I
recommend heading over to the next lesson where we're going to talk about the third type of functions
in Dart, functions that can have an output. Whichever path you choose,
I will see you on the next lesson.