I Have a Dream - B
02
The I Have a Dream app only had one picture and speech, and it didn't allow you to pause the speeches. In part B, you'll add a speech of Malcolm X to show the contrast of these two great leaders, and you'll code it so each speech can be paused.
This tutorial introduces the concept of an if-else condition, which enables an app to ask questions and make decisions: its one of the fundamentals of "artificial intelligence".
Objectives
Follow an instructor-led walk-through to create the I Have a Dream app on a mobile device
Utilize a conditional if-else selection blocks to improve the app's behavior
Reuse code efficiently by using the copy and paste blocks feature in App Inventor Blocks Editor
Utilize a horizontal arrangement to layout buttons side-by-side
Name components in a standard format (description and component type, e.g. MalcolmButton or ButtonMalcolm)
Getting Ready & Video Tutorial
Open App Inventor 2.
Go to My Projects.
Select the I Have a Dream app you created in part A
User Interface: I Have a Dream B
We are going to update our user interface to include some extra components to improve our app. Our new user interface (UI) for our I Have a Dream app will consist of eight Components: two Buttons, two Players, two Labels, an Image, and a HorizontalArrangement component. Remember that this is done in the Designer View.
Your Viewer panel should now look like the image to the right when your app is complete.
Adding a Button Component
Drag and drop a Button component from the Palette's User Interface category to the Viewer. It will be named Button2.
Select Button2 by clicking on it in the Viewer or the Components panel.
Click on its Image property and select the "malcolm152x129.jpg" image from the drop-down list.
Click on its Text property and change it to an empty string by deleting "Text for Button2".
You should also update the button for Martin Luther King. Do this in the same way as before. Select Button1 in the Components panel and change its Image property to "mlk152x129.jpg"
Organizing the User Interface
Drag and drop a HorizontalArrangement component from the Palette's Layout category to the Viewer
TClark Hint: Make the Width property 100 percent or Fill parent, so it is easier to put components in it.
Drag and drop the Martin Luther King button and Malcolm X button into the HorizontalArrangement component so they are side-by-side.
Adding an Image Component
Drag and drop an Image component from the Palette's User Interface category to the Viewer. It will be named Image1.
Select Image1 by clicking on it in the Viewer or the Components panel.
Click on its Picture property and select the "228px-MLK_and_Malcolm_X_USNWR_cropped.jpg" image from the drop-down list.
TClark Hint: Select Screen1 and change the AlignHorizontal property to the center for everything to be centered nicely.
You can also change the BackgroundColor here, don't forget to change the TextColor of the Label to white, and update the Text as well.
Adding a Player Component
Click on the Palette's Media category to open it.
Drag and drop a Player component from the Media category to the Viewer. It will be named Player2 and it will appear at the bottom of the Viewer under Screen1 as a non-visible component.
Select Player2 by clicking on it in the Viewer or the Components panel.
Click on its Source property and select the "malcolmx.mp3" sound file from the drop-down list.
Renaming the Components
We want to rename our components to make coding our app easier. Component names should include the component type and some sort of identifier. To rename a component:
Select Button1 in the Viewer or the Components panel
Click on Rename
In the New Name text box, type the desired name, and click OK
Rename the Button1 component to ButtonMLK
Rename the Button2 component to ButtonMalcolm
Rename the Player1 component to PlayerMLK
Rename the Player2 component to PlayerMalcolm
We also want to change the Label's Text property to reflect the new changes we are making to the app
Select Label1
Change the Text property from "Martin Luther King" to "Martin Luther King and Malcolm X"
Put a check in the box under the FontBold property
Change the FontSize property to 18
Select Label2
Change the Text property from "Tap to hear the speech" to "Tap to hear each speech"
Organizing Code
A good coding practice is to keep all your code organized. TClark's Rules/Hints for these
Name your components nicely.
Use Snap to Grid to keep blocks lined up neatly. (see below)
Do NOT put blocks on top of other blocks. No hidden blocks.
Do NOT collapse blocks.
Coding the App's Behavior
It's time to get the app to play the speech when we touch its screen. For this we will be using the Blocks editor. So switch now to the Blocks Editor View.
Event Driven Programming
Mobile apps use a style of programming known as event driven programming. An app's behavior depends on how the user programs the app to respond to various events. An example of an event would be when the user clicks on a button or when the phone's location changes or when a text message is received. We'll write apps that respond to all of these events.
For the I Have a Dream app, there is only one event that we care about, the Button click event. This event will be called when Martin Luther King or Malcolm X is clicked.
Click on the ButtonMalcolm component in the Toolbox.
Drag and drop the When ButtonMalcolm.Click block into the Workspace.
This is an example of a when event block, which is also called an event handler block.
Notice that it has a empty do slot. When ButtonMalcolm is clicked, the app will do whatever code we put into this slot.
Click on PlayerMalcolm component in the toolbox
Drag and drop the PlayerMalcolm.Start block into the do slot of the ButtonMalcolm.Click event
For the I Have a Dream app, we want it to play only one speech at a time and pause each speech when the pictures are clicked. To do this, we will need to use Logic
Adding an If block
If blocks allow the app to make decisions. In our app, we want to determine whether the sound should be played or paused based on whether something is already playing. To do this, we need to use an if block.
Open Controls in the toolbox
Drag and drop the block that reads if/then into the workspace.
Click on the blue box in the corner of your if block (called a Mutator)
Drag and drop the else block from the left into the if block on the right
Now that we have our if block, we will add the question we want it to ask
Click on the PlayerMLK component from the toolbox
Drag the PlayerMLK.IsPlaying block and drop it into its slot on the if block
When the ButtonMLK is clicked, the app now asks if the player is playing. If it is, the code under then will be executed. If not, it will execute the else code instead. Next we will tell the app what to do in each case.
When ButtonMLK is clicked, we want the program to play PlayerMLK if it is not playing, pause PlayerMLK if it is playing, and always pause PlayerMalcolm. To do this:
Drag and drop the PlayerMLK.Start from ButtonMLK.Click to the else slot in our new if block.
Open the PlayerMLK component from the toolbox
Drag the PlayerMLk.Pause from the toolbox and drop it in the then slot of our if block
Drag and drop the if block into the ButtonMLK.Click event block
Open the PlayerMalcolm component from the toolbox
Drag the PlayerMalcolm.Pause block and insert it on the outside the if block
Duplicating a block of code
The next step is to code the behavior for ButtonMalcolm. Because it is similar to the behavior of ButtonMLK, we are able to make a shortcut by duplicating the code.
Drag the PlayerMalcolm.Start block from the ButtonMalcolm.Click event and drop it in the trash icon in the bottom right corner of the workspace. Because we are duplicating the other code, we will not need this extra block.
Right click on the if block that is in the workspace and select "Duplicate"
Drag and drop the copy of our if block into the ButtonMalcolm.Click event block
Right click on the PlayerMalcolm.Pause and select "Duplicate"
Drag and drop the copy of PlayerMalcolm.Pause into the ButtonMalcolm.Click event, inserting it above the if block
We have now copied all the code needed for ButtonMalcom, but it does not yet apply to the correct player. We want ButtonMalcolm.Click to pause PlayerMLK, then either player or pause PlayerMalcolm. We can change this easily by using the drop-down lists.
Click the small down arrow located in each block to open the drop down list
Where the blocks read "PlayerMLk" change to "PlayerMalcolm"
Where the blocks read "PlayerMalcolm" change to "PlayerMLk"
Testing Your App
If everything is configured properly, you should see the IHaveADream app on the phone and when you click a button, you should hear the appropriate speech.
Test your app with the following inputs. See if your outputs match the expected outputs.
To summarize the behavior, whenever the user clicks on ButtonMLK, the app will pause PlayerMalcolm, then either pause or play PlayerMLK , and vice versa for ButtonMalcolm.