Let's Build a Homemade Xylophone Flutter App
Hey All,
I am back with yet another app I have built while following the Angela Yu course on Udemy so I can share with you guys what I have learnt from it. So without further ado let's get started.
Things To Learn And Implement
These are the list of thing we are going to learn by the end of the creation of this app.
- FlatButton widget
- Expanded widget (Once again)
- Importing package and Using it
- Playing the local sound on Audio in-app
- Different type of function call
Let's Create our Xylophone App
By the End our App is going to look something like this:
where each button is associated with a sound note (Can't show it you guys how it works π for that you have to build on your ownπ ).
Setting Up the Base Setup
So by now you already know that the base setup for our app can be done with a single flutter command.
flutter create xylophone
Now let's update the App icons for both Android and iOS by changing them In there respective folders.
Also, let's add the required note sounds after creating the asset
folder and store it in this folder. Also, let's update the pubsec.yaml
so that flutter recognises the added note sound files.
name: xylophone
description: A new Flutter project.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
version: 1.0.0+1
environment:
sdk: ">=2.7.0 <3.0.0"
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^1.0.0
dev_dependencies:
flutter_test:
sdk: flutter
# The following section is specific to Flutter.
flutter:
uses-material-design: true
assets:
- assets/
and run the flutter pub get
to update the flutter dependencies.
You can clone this repo which contains the complete code with required assets for our app.
Let's create FlatButtons for each Sound Note
So now let's create a flat button and make it play a sound note when it's clicked.
So now let's start with our app coding
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
home: Scaffold(
backgroundColor: Colors.black,
body: Xylophone(),
),
),
);
}
class Xylophone extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container();
}
}
This provides us with a pitch Black background app without any app bar.
Now let's create a FlatButton
widget which provides us with a button without any elevation. Also, the FlatButton
is Now replaced By TextButton
Widget
A Material Design "Text Button".
Use text buttons on toolbars, in dialogues, or inline with other content but offset from that content with padding so that the button's presence is obvious. Text buttons do not have visible borders and must therefore rely on their position relative to other content for context. In dialogues and cards, they should be grouped in one of the bottom corners. Avoid using text buttons where they would blend in with other content, for example in the middle of lists.
A text button is a labelled child displayed on a (zero elevation) Material widget. The label's Text and Icon widgets are displayed in the style's ButtonStyle.foregroundColor. The button reacts to touches by filling with the style's ButtonStyle.backgroundColor.
So Now let's 7 buttons with a different colour so we can distinguish each of them. ( I will display the code after I explain about the Importing packages)
Importing the Audioplayer package
Now as I told we need to play a tone which each of the buttons is clicked. So to make that audio play we are going to use the package which is already created by other developers so can we don't have to create our own custom code to make the audio player for our App.
To import package first we need to find the package which suits our need. So let's go to the flutter package which holds all the list of the packages which we can use in our project.
Once we are on the website now let's search for the audio player package which we want to play the sound when we click on the button. In result, we might get many packages with almost similar implementation out of which we have to pick the package which is best suited for the project still if you find multiple packages fulfilling your requirement then check the package pub points and popularity so that you will be using the package which has the best solution and which are frequently used by the other developersπ.
Once you pick your package now let's open that package and read the documentation which explains us about the package like how to install, Examples of use cases, etc.
By following the Installation steps mentioned in the documentation. So let's use the audioplayer
package in our project. So the Updated Yaml looks like this:
name: xylophone
description: A new Flutter project.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
version: 1.0.0+1
environment:
sdk: ">=2.7.0 <3.0.0"
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^1.0.0
audioplayers: 0.17.0 // This the package we have got from the flutter packages.
dev_dependencies:
flutter_test:
sdk: flutter
# The following section is specific to Flutter.
flutter:
uses-material-design: true
assets:
- assets/
Now to Use this in our app just run the flutter pub get
command so the package gets add as an external library in our project.
Now let's import the package and create an object for the player so we can use the functionalities offered by the package.
import 'package:audioplayers/audio_cache.dart';
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
home: Scaffold(
body: Xylophone(),
),
),
);
}
class Xylophone extends StatelessWidget {
@override
Widget build(BuildContext context) {
return SafeArea(
child: Column(
children: [
FlatButton(
onPressed: () {
final player = new AudioCache();
player.play('note1.wav');
},
child: null,
color: Colors.red,
),
FlatButton(
onPressed: () {
final player = new AudioCache();
player.play('note2.wav');
},
child: null,
color: Colors.orange,
),
FlatButton(
onPressed: () {
final player = new AudioCache();
player.play('note3.wav');
},
child: null,
color: Colors.yellow,
),
FlatButton(
onPressed: () {
final player = new AudioCache();
player.play('note4.wav');
},
child: null,
color: Colors.green,
),
FlatButton(
onPressed: () {
final player = new AudioCache();
player.play('note5.wav');
},
child: null,
color: Colors.green.shade900,
),
FlatButton(
onPressed: () {
final player = new AudioCache();
player.play('note6.wav');
},
child: null,
color: Colors.blue,
),
FlatButton(
onPressed: () {
final player = new AudioCache();
player.play('note7.wav');
},
child: null,
color: Colors.purple,
),
],
),
);
}
}
As you can see in the Code we have Seven FlatButton which each is set to play a tone when clicked. Also, we have used the Column
widget to display the all button in a column and By using the SafeArea
widget that inserts its child by sufficient padding to avoid intrusions by the operating system.
And the
final player = new AudioCache();
player.play('note1.wav');
Creates an object for AudioCache class which has the code for the locally stored audio files and then through the object we are accessing the method which helps us in playing the audio. (So simple right π think of the time we saved from writing all those codes which we had to write make the audio player if didn't have this package.). Also we not going to change the variable player so we are making it as final which prevents the variable modification.
Also, one more thing that as you can see that we are directly mentioning the audio file name without folder name that is due to audioplayer
package consider that audio files are stored inside the asset
folder.
As of now, our app looks like this:
As you can see that buttons are not covering the whole screen which can be taken care By adding the single line inside the Column
widget we can make those buttons to stretch to the end of the screen that is
crossAxisAlignment: CrossAxisAlignment.stretch
by adding this line the buttons are made stretch horizontally to cover the whole screen
Now as you can see that we have many repeated lines of code so we can reduce it make our code look better and cleaner by creating a function which can be used instead of repeating the same line of code again and again.
Creation of Function for the Sound Play
So let's create the function named playSound
which got the code for creating the object of the AudioCache
class and from that object we are accessing the play
function offered by that class.
Function is a set of statements that take inputs, do some specific computation and produces output. Functions are created when certain statements are repeatedly occurring in the program and a function is created to replace them. Functions make it easy to divide the complex program into smaller sub-groups and increase the code reusability of the program.
Basically, there are four types of functions in Dart. These are as follows:
- No arguments and no return type
- With arguments and no return type
- No arguments and return type
- With arguments and with return type
So as we don't have to return anything but we need to change the sound note depending on the button so we are gonna need the With arguments and no return type
type of function.
class Xylophone extends StatelessWidget {
void playSound(int noteNumber) {
final player = new AudioCache();
player.play('note$noteNumber.wav');
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
FlatButton(
onPressed: () {
playSound(1);
},
child: null,
color: Colors.red,
),
FlatButton(
onPressed: () {
playSound(2);
},
child: null,
color: Colors.orange,
),
FlatButton(
onPressed: () {
playSound(3);
},
child: null,
color: Colors.yellow,
),
FlatButton(
onPressed: () {
playSound(4);
},
child: null,
color: Colors.green,
),
FlatButton(
onPressed: () {
playSound(5);
},
child: null,
color: Colors.green.shade900,
),
FlatButton(
onPressed: () {
playSound(6);
},
child: null,
color: Colors.blue,
),
FlatButton(
onPressed: () {
playSound(7);
},
child: null,
color: Colors.purple,
),
],
),
);
}
}
Create one more Function for Button build
Still, we can see the repeated code for building the Expanded FlatButtons so let's create a function for that as well but
as you can see this since we are going to call the function from inside of the Column
widget it expects a widget in return from the function so the function return type should be a widget and next we also need to provide the colour of the button and number of the sound note be played for that button so we are going to use the named parameter in the function so that there will be confusion with the parameters to be passed with function.
class Xylophone extends StatelessWidget {
void playSound(int noteNumber) {
final player = new AudioCache();
player.play('note$noteNumber.wav');
}
Expanded buildKey({Color color, int noteNumber}) {
return Expanded(
child: FlatButton(
onPressed: () {
playSound(noteNumber);
},
child: null,
color: color,
),
);
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
buildKey(color: Colors.red, noteNumber: 1),
buildKey(color: Colors.orange, noteNumber: 2),
buildKey(color: Colors.yellow, noteNumber: 3),
buildKey(color: Colors.green, noteNumber: 4),
buildKey(color: Colors.teal, noteNumber: 5),
buildKey(color: Colors.blue, noteNumber: 6),
buildKey(color: Colors.purple, noteNumber: 7),
],
),
);
}
}
Viola, now you see that by how many lines code we have reduced from our code using the single function.
Here is our final product which creates the sound note on clicking on the button.
Challenges Faced
Challenges to be faced with this project was to play the audio depending on each button and making the code clean and can be reused and finally use of the import with the dart language.
- The Button creation issue we overcame through the use of the
FlatButton
widget. - Audio play, we imported the
audioplayer
package which had the functionality to play the audio and we made those function to play the audio on clicking the button - We removed the repeated lines of code by the use of Functions
Summary
To summarise the whole thing by creating this app we learnt the use of the import and how to use it. Using the audio player to play the audio. use of the flat button with column and stretch it across the screen and different types of the functions.
Thank you
Thank for reading the Blog till now (If you have read it till now π ). Leave a like and comment if you liked the blog and definitely leave a comment if you found any mistakes so that I can correct myself. In next the blog, I will be back with the Quiz with the scoring system (I have just seen the preview of the app in the course and I will share with the guys what I have learnt from creating that app π)
Till then εθ§ π