Wireframe to Wire-fame

Codecademy Team
Apply your new Android development skills to bring a wireframe to life.

In this project, you will fire up Android Studio, create a brand new project, and design the layout needed to make Unquote a reality. You will use Android Studio and the Layout Editor to create a layout that will serve as the main game screen for Unquote, the trivia game that punishes players for spending too much time on the Internet… or not enough time… We’re not exactly sure!

This is the wireframe you need to build:

Demo of Project
It looks intimidating, but you've got this. Let's begin.

Create a Brand New Android Studio project

We’re going to start Unquote with a clean slate. Begin by launching Android Studio.

1. Choose File > New > New Project…


Hint

If you see the "Welcome to Android Studio" window, click "Start a new Android Studio project."

2. Select the Empty Activity template


Hint

Android Studio prints the label for each template below the thumbnail.

3. Name your project, “Unquote”


Hint

Don't worry about the package name, only modify the Name of your project directly.

4. Set the minimum API level to 15


Hint

This is found in a dropdown selector, and 15 may already be set for you.

5. Click “Finish”

6. You’re ready to design!

Android Studio created all the files you’ll need for the remainder of this project.


Study the Wireframe

Given the final Unquote wireframe (pictured above) and everything you know of Android’s Views and ViewGroups, you can begin to deconstruct the drawing into its component parts.

1. Including the parent ViewGroup, how many components are required by the wireframe?


Hint

Typically each box, text element, image, etc. require a minimum of 1 component to represent them in the final layout file. If you arrived at 10, you're on the right track.

2. How many ImageView components does the wireframe require?


Hint

ImageView objects represent images on-screen, how many images does the wireframe demand?

3. How many TextView components does the wireframe require?


Hint

In total, 3. One for the question text. One for the number of questions remaining. And another to present the phrase, "questions remaining", immediately to the right of the previous.

4. How many Button components does the wireframe require?


Hint

A total of 5. One Button for every possible answer, and another to submit the answer after the player has made their selection.

5. What’s special about the Button components?

If you drew a box around each element to represent the width and height each requires, what stands out about the answer button?


Hint

Every element except the answer button grows as wide as its parent ViewGroup or takes up only as much space as needed (wrap_content).

The answer Button, however, take up approximately half (~50%) of the width of the parent ViewGroup. Also, the top two Button components look identical to the bottom two Button components.

6. How will you place the Button components side-by-side?

Begin to think about the layout implementation required to place elements side-by-side, horizontally in a single-file line.

Hint

The LinearLayout ViewGroup might help you here.

7. Take your best guess!

Redraw the game screen wireframe on a sheet of paper, and add comments in the margins.

Label each element by its component name (Button, TextView, etc.). Label each ViewGroup by its component name (ConstraintLayout, LinearLayout).

Finally, for all components within your ConstraintLayout, draw constraints using little arrows.

You will recreate this diagram in Android Studio soon!

Hint

ViewGroups may be children of other ViewGroups. Meaning, a LinearLayout may be a child View of a ConstraintLayout (and vice-versa).


Analog to Digital

Now you will take your wireframe and begin recreating it in Android Studio’s layout editor.

1. Open activity_main.xml


Hint

You can find this file under the resources/layout folder in your Project Navigation panel, or under Layout within the Resource Manager panel.

2. Switch to Design Mode

In Design Mode, you will freely modify the design without writing the XML document by hand. If you prefer to build your layout in text, feel free to switch to Text Mode.


Hint

Switch to Design Mode by clicking the Design icon above the tab at the bottom of the editor window.

3. Remove the default TextView

We will start this layout with a clean slate, remove the “Hello World!” TextView in the middle of the layout.


Hint

You can delete components by clicking them in the editor window and pressing the Backspace or DEL key.

4. Add an ImageView

Drag an ImageView from the Component Palette into the center of the layout, and choose backgrounds/scenic found under Sample Data as the default image content.


Hint

You may find the ImageView component in the Common and Widgets categories within the Component Palette.

5. Apply constraints to the ImageView

Based on the wireframe and design thinking you performed, which layout constraints should you place on the ImageView for it to remain centered at the top of the game screen?

Click and drag the bubbles at the edges of the ImageView to apply constraints to the component.


Hint

You can center a child within a ConstraintLayout by constraining the left and right side to parent.

6. Modify the ImageView attributes

Modify the ImageView attributes so that the component is only as tall as its content requires, as wide as its constraints demand, and grows (or shrinks) in height to maintain the original aspect ratio of the image.

This may require some poking around the Attributes Panel with your ImageView selected. Remember, you can hover over the name of any attribute to reveal its purpose.

To undo (or delete) an attribute, highlight the attribute under the Declared Attributes Panel, and press the Backspace or DEL key.


Hint

Children of ConstraintLayout with a layout_width set to 0dp will grow as wide as their left & right constraints allow.

Assigning wrap_content to layout_height allows components to request as much space as their content requires.

Under the Common Attributes Panel, ImageView provides an attribute named adjustViewBounds. Setting adjustViewBounds to true will cause the ImageView to maintain the original aspect ratio of its content.


Bottom’s Up

With your ImageView prepared, you are ready to create the game controls. The controls exist at the bottom of the screen and should remain there regardless of the length of the question text or height of the image.

You will construct the remainder of the layout using a bottom-up approach, meaning, you establish the bottom-most components first, then anchor the remaining components above them one horizontal layer at a time.

Let’s begin!

1. Add a TextView

Drag a TextView from the Component Palette into your layout. This TextView will represent the number of questions remaining and will be the tallest component you anchor to the bottom of your ConstraintLayout.


Hint

You may find the TextView under the Common and Text categories within the Component Palette.

2. Constrain the component

Bind this TextView to the left and bottom of the screen with constraints.

Use a margin to give 8dp of space between the TextView and the left edge of the screen.


Hint

Use the parent as the constraint for both left and bottom constraints, and apply an 8dp margin to the left of the TextView using the controls found in the Layout Attributes Panel.

3. Tweak the text

Use attributes to grow the text size to 48sp, make the text bold, and present 99 as the default number of questions remaining.


Hint

The textSize, textStyle, and tools:text attributes found under the Common Attributes Panel can help you out here.

4. One good text deserves another

Drag a second TextView onto your layout. This TextView should read, "questions remaining".

Use constraints to place this new TextView immediately to the right of the first one. Center it vertically between the top and bottom of the first TextView.


Hint

You can drag the left constraint bubble of the new TextView to the right constraint bubble of the first one.

And to center one View vertically with respect to another, constrain the top and bottom of the Viewto the top and bottom (respectively) of the other View.

5. Clean up

Use attributes to place 8dp of space between this new TextView and the first.


Hint

Highlight the second TextView and use the Layout Attributes Panel to place an 8dp margin on its left side.

6. Button up

Drag a Button component onto your layout, change the text to read "Submit".

Use constraints to bind this Button to the bottom-right of the screen and then put 8dp of margin between the Button and the right edge of the screen.


Hint

Use the text attribute found under the Common Attributes Panel to change the text displayed by the Button.

Constrain the Button to the right edge of the screen (from the right-bubble) and the bottom edge of the screen (from the bottom-bubble).

To add a margin, use the drop-down selectors in the Layout Attributes Panel.

7. Center yourself

Use constraints to align this Button vertically with the first TextView (the one which currently reads 99).


Hint

To do this, constrain the top of the Button to the top of the TextView.

8. And style it up

To give this Button a nicer look, change its style attribute to style/Widget.AppCompat.Button.Colored.


Hint

Find the style attribute under the Common Attributes Panel. Use the drop-down to find the Widget.AppCompat.Button.Colored style.


An Answer For Everything

In an earlier task, you thought about creating two side-by-side Button components that fill approximately half the width of the screen.

You may have considered constraints. By constraining the bottom of each Button to the same component and the left of one Button to the left edge of the parent and the right of the other Button to the right edge of the parent, you can level the Button components vertically.

Unfortunately, that approach forces you to hardcode the width of each Button to a fixed size. Without knowing the width of every device ahead of time, you cannot account for all possible screen sizes without incurring a series of crippling migraines.

Instead, you will use a LinearLayout feature to achieve this painlessly.

1. Drag a LinearLayout (horizontal) component onto your layout

This LinearLayout will contain the bottom row of answer Button components (answers 2 and 3).


Hint

Find this component under the Layouts Category within the Component Palette.

2. Align your LinearLayout

Use constraints to make your LinearLayout fill the width of the parent container, then constrain the bottom of your LinearLayout to the top of your “Submit” Button.

Add 8dp of margin to the left, right, and bottom edge of your LinearLayout.


Hint

As you've done before, drag the left-bubble of your LinearLayout to the left edge of the parent container and its right-bubble to the right edge of the parent container.

To allow the LinearLayout to fill the width of its constraints, change its layout_width attribute to 0dp.

To add margin, select your LinearLayout and use the drop-downs found in the Layout Attributes Panel.

3. Add two answer Button components

Drag a Button component into your LinearLayout. Then, drag another Button component right on top of the first one. Change each Button’s style attribute to match the ‘Submit’ button created earlier (style/Widget.AppCompat.Button.Colored).

Verify that both Button components dropped directly into the LinearLayout by examining the Component Tree.

If you accidentally place the Button into the wrong ViewGroup (ConstraintLayout), undo your last action with Ctrl/CMD + Z and try again.

What happens after placing two Button components inside of your LinearLayout?


Hint

If everything goes right, you'll have two Button components side-by-side, each consuming approximately 50% of the width of their LinearLayout parent!

This is due to the layout_weight attribute automatically applied to a child of LinearLayout.

By default, Android Studio sets the weight of each child to 1. And when all children have equal weight, they consume an equal amount of space within LinearLayout.

4. Wrap the Buttons

Change the layout_height attribute of your LinearLayout such that it grows only as tall as its content requires.


Hint

Use wrap_content to ensure that your View or ViewGroup only grows as tall or as wide as its content requires.

5. Repeat steps 1 through 4

Create another row of answer buttons that will represent answer0 and answer1. Constrain this row immediately above the previous row.


Hint

Here's how to get it done:
  1. Drag another LinearLayout (horizontal) onto your layout.
  2. Constrain the LinearLayout to the left and right edges of the screen
  3. Set its layout_width to 0dp
  4. Apply 8dp margins to its left and right edges
  5. Constrain the bottom of the LinearLayout to the top of the previous LinearLayout
  6. Add two Button components inside this LinearLayout
  7. Change the height of the LinearLayout to wrap_content

You can always undo something with Ctrl/CMD + Z, and retry steps 1 through 4 again to build your confidence.


6. One more component

Add a third and final TextView to your layout (ConstraintLayout)—one to present the question text to the player.


Hint

TextView is found in the Common and Text categories within your Component Palette.

7. Align the text

Use constraints to align the TextView to the left and right of its parent container, and constrain the bottom of the TextView to the top of the LinearLayout you created in step 5.

Surround the TextView with 8dp margins.


Hint

Use the constraint bubbles to assign the left-constraint to the left edge of the screen, right-constraint to the right edge, and bottom constraint to the top of the top-most LinearLayout (containing the answer0 and answer1 buttons).

8. Style it up

Use attributes found in the Common Attributes Panel to change the size of the text to 18sp, the typeface to sans-serif-thin and the tools:text to a default question, something like, "Famous advice from an iconic mentor. Which fictional character really imparted this bit of sage wisdom?".


Hint

Help yourself focus by collapsing the Declared, Layout, and All Attributes panels.


Minor Touch-Ups

With all of your elements in place, it’s time to make some small design tweaks to please the eye.

1. Change your theme colors

Open up the Resource Manager, and choose the tab labeled, Color. Double click either colorAccent, colorPrimary, or colorPrimaryDark.


Hint

You can find the Resource Manager in the menu by selecting View, then Tool Windows, then clicking Resource Manager.

2. Inside of colors.xml

colors.xml is a value XML file. Within a <resources> element, this file can store strings, colors, dimensions, and so much more.

  • Change the value of colorPrimary to #EFD9CA
  • Change the value of colorPrimaryDark to #C4B2A6
  • Change the value of colorAccent to #FD4D3F

Hint

These color values are hexadecimal numbers that define red, green, and blue color levels using two "digits" (0-9 and A-F are valid).

3. Return to activity_main.xml

Back in your main layout file, highlight the main ViewGroup, your ConstraintLayout.

In the Attributes Panel, click the search icon (magnifying glass symbol), and type “background” into the search bar.

4. Change the background color

If a value is present for the background attribute, white for example (#FFFFFF), click the color square to reveal a color-picker window. Switch to the Resources tab within the color-picker, then choose colorPrimary, this will change the background color of your ConstraintLayout.

Neat, huh?

5. Identify yourself

Lastly, you will need to fix the resource identifier for each component you plan to use in your code.

Namely, you need to customize the ID for the ImageView, the TextView which displays the question, the four answer buttons, the TextView that displays the number of questions remaining, and the “Submit” button.

Follow Android’s naming convention to modify the ID of each of these components.


Hint

Modify the id attribute directly from the Declared Attributes Panel.

Each ID should resemble this naming structure, iv_main_quote_image, e.g. {abbreviated component type}\_{layout name}\_{purpose}.

In this example, iv is short for ImageView, main refers to MainActivity, and quote_image is the purpose this ImageView serves.

6. It’s ready

Your layout is set for success. Once your Activity displays this layout, you’re ready to populate the components with the data necessary for your player to enjoy Unquote!

Great job! 👍