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

  1. Open App Inventor 2.

  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

  1. Drag and drop a Button component from the Palette's User Interface category to the Viewer. It will be named Button2.

  2. Select Button2 by clicking on it in the Viewer or the Components panel.

  3. 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".

  4. 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

  1. 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.

  2. 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

  1. Drag and drop an Image component from the Palette's User Interface category to the Viewer. It will be named Image1.

  2. Select Image1 by clicking on it in the Viewer or the Components panel.

  3. 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

  1. Click on the Palette's Media category to open it.

  2. 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.

  3. Select Player2 by clicking on it in the Viewer or the Components panel.

  4. 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:

  1. Select Button1 in the Viewer or the Components panel

  2. Click on Rename

  3. 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

  1. 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

  2. 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

  1. Name your components nicely.

  2. Use Snap to Grid to keep blocks lined up neatly. (see below)

  3. Do NOT put blocks on top of other blocks. No hidden blocks.

  4. 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.

  1. Click on the ButtonMalcolm component in the Toolbox.

  2. 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.

  1. Click on PlayerMalcolm component in the toolbox

  2. 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.

  1. Open Controls in the toolbox

  2. Drag and drop the block that reads if/then into the workspace.

  3. Click on the blue box in the corner of your if block (called a Mutator)

  4. 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

  1. Click on the PlayerMLK component from the toolbox

  2. 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:

  1. Drag and drop the PlayerMLK.Start from ButtonMLK.Click to the else slot in our new if block.

  2. Open the PlayerMLK component from the toolbox

  3. Drag the PlayerMLk.Pause from the toolbox and drop it in the then slot of our if block

  4. Drag and drop the if block into the ButtonMLK.Click event block

  5. Open the PlayerMalcolm component from the toolbox

  6. 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.

  1. 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.

  2. Right click on the if block that is in the workspace and select "Duplicate"

  3. Drag and drop the copy of our if block into the ButtonMalcolm.Click event block

  4. Right click on the PlayerMalcolm.Pause and select "Duplicate"

  5. 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.

  1. Click the small down arrow located in each block to open the drop down list

  2. Where the blocks read "PlayerMLk" change to "PlayerMalcolm"

  3. 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.