Skip to the content.
This is the Spring 2022 final website.

as2: Layout

Last revised: 5-April, 2022
Assigned:
  • Part 1-5 Wed 6-Apr
Due:
  • Part 1-2 Checkpoint 10:00 pm, Thur 14-Apr
  • Part 3-4 (Code) & Part 5 (Reflection) 10:00pm, Thur 21-Apr

HCI Goals:

  • Make use of interactor hierarchy
  • Use constraints to create responsive layouts
  • Make use of complex built-in layouts
  • Implement reusable layouts
  • Understand how scrolling works
  • Understand how sizes influence layout

Android Goals:

  • Create a generalizable, reusable layout for any number of images
  • Understand Android layout GUI and XML
  • Familiarize with Android programmatic layout API
  • Understand Android constraints implementation
  • Handle portrait and landscape orientation correctly
  • Handle fixed and variable sized container views
  • Learn about Inflators

Turn-in links

Assignment Description

This is the assignment spec for our Layout module of the class. Scroll down to the development strategies sections for some tips curated from past students!

An important note: Part 1-2 and Part 3-5 are NOT equivalent in difficulty. Part 1-2 will take significantly less time than Parts 3-5. Once you have completed part 1-2, turn it in and continue to work on the rest of the assignment. The checkpoint will help you discover early any misconceptions. Clearing up those misconceptions early will help with the balance of development cycle to ensure your code is working correctly.

Finally, note that all dimensions in all parts of this assignment should be specified in density independent pixels (i.e. dp instead of px).

Inheritance Hierarchy

Like Doodle, our MainActivity inherits from a TabActivity which we have created to switch between each of the parts of this assignment. However instead of switching between Activity objects, we’re switching between View objects. Part2View and Part3View inherit from a ScrollView, and Part4View inherits from a ConstraintLayout to allow for the most flexibility in your creative portion of this assignment.

classDiagram TabActivity <|-- MainActivity ScrollView <|-- Part2View ScrollView <|-- Part3View ConstraintLayout <|-- Part4View

Introduction to Parts 1 and 2

For parts 1 and 2, you will be building the same layout twice. It must show at least five images, be scrollable, and look equally nice horizontally and vertically. Additionally, you must use constraints to achieve this, using the ConstraintLayout we provide in part1.xml. part1.xml can be found in the res/layout directory in Android Studio once the layout project has been opened.

The results should look like this:

Portrait screenshot for parts 1 and 2 Landscape screenshot for parts 1 and 2

For part 1, you will use Android Studio’s built-in layout editor to create the desired layout, using a combination of XML and the GUI.

For part 2, you will create the same layout programatically, using Java code to construct view objects and add them to our activity. In this way you will demonstrate how to make a generalizable layout class that can be reused for an arbitrary number of images.

This video shows parts 1 and 2 in action:


A (slightly simplified) view of the interactor hierarchy for parts 1 and 2 is shown below. Two notes about the interactor diagrams in this specification:

graph LR W(LinearLayout) --> Status[StatusBar] W --> R[RelativeLayout] R --> S[ScrollView] S --> C[ConstraintLayout] C --> I1[ImageView: borders: vMargin] C --> I2[ImageView: borders: vMargin] C --> I3[ImageView: borders: vMargin] C --> I4[ImageView: borders: vMargin] C --> I5[ImageView: borders: vMargin] R --> B[BottomNav] classDef greenlarge fill:#dbf0db,stroke:#333,stroke-width:2px,font-size:16px,padding:0px,height:50px,top:1px; classDef bluelarge fill:#99ccff,stroke:#333,stroke-width:4px,font-size:16px,padding:0px,height:50px,top:1px; class Status,W,S,R,B greenlarge class C,I1,I2,I3,I4,I5 bluelarge

We can represent this same interactor hierarchy visually in a Layout Wireframe. An example of a Layout Wireframe for Part 1 is shown below which details the visual nesting of the interactors, margin spacing between the interactors. Layout Wireframe diagrams are a design tool to help you visualize how your app will function programatically. For instance, in this sample, we can see that you will only be adding images inside the ConstraintLayout. (Note: this layout diagram should be more detailed and also include labels for the ImageView and other objects).

This Layout Wireframe highlights that you will only be configuring the ImageViews as they relate to the ConstraintLayout(shown in blue). Note that this Layout Wireframe is simplified representation of what you would see in the Layout Inspector.

Reference image for parts 1 and 2 showing how each image is staked vertically with vMargin space on every side; below; above; and between images

You will be drawing Layout Wireframes for Part 4 of assginment as well in other parts of this course. The Layout Wireframes you produced must be more complex than what you see here. You will be expected to explicitly label each View, layout container, spacing, etc, and as well as specify any relevant information about orientation (such as Vertical vs Horizontal LinearLayout).

You may find the following link helpful when working with constraint layouts: “Building a Responsive UI with Constraint Layout” (pay particular attention to the Set size as a ratio section).

Further details on Part 1

Tasks:

When it comes to layout, working directly with XML can be a pain, especially when there are several attributes to keep track of on each element. Luckily, Android Studio provides a visual editor that you can use to build your app layout.

For part1.xml, you will accomplish the following:

Further details on Part 2

The Part2View starter code can be found in the cse340.layout directory in Android Studio.

In Part2View we have set up the basic scaffolding necessary to complete the given layout. For this section you will be instantiating the view objects from Part 1 programmatically.

Tasks:

It may be useful to view the interactor hierarchy using Layout Inspector when Part 1 is running to understand how to structure the views you are creating programatically in Part 2.

Reminder: Turn in your completed Part 1 and 2 to the appropriate Ed lesson for your check point. The course staff will give quick feedback about the correctness of part 1-2 while you are completing the balance of your assignment.

Part 3

The Part3View starter code can be found in the cse340.layout directory in Android Studio. We will create a custom Layout in Part3 that can organize an arbitrary series of Views into a Pinterest-like layout. Pinterest is a great example of a high-profile app that can be built with relatively simple layout instructions. For instance, one could imagine breaking the layout into two large vertical columns, then assigning various elements to each one. You will also need to ensure the columns never differ by more than the height (in dp) of one image.

Screenshot of pinterest layout

To determine which column a photo should go in, we will use “pinterest” ordering. You must track the height of the images in each column and add the next image to the shorter column (or the left column if equal).

Note that the aspect ratio of images may vary (they may have an arbitrary width and height. For this reason, you will need to figure out the image’s height once it is scaled to fit within the width of its column.

To do this, you will need to find out the displayed (or measured) height of the image. This requires that you get the measured width of a column (with the image added), then use that to measure the height of each image. It will help to take a look at How Android Draws Views and View#Measure(int, int) for this.

Screenshot of part 3    Screenshot of part 3 scrolled

It is important to understand that two photos with different resolutions but the same aspect ratio (width to height ratio) will both affect the column height identically because they will be scaled to have the same size on-screen.

Keep in mind that similar to Part 1 and Part 2, your Part 3 layout should be responsive to device orientation. When rotated your layout should maintain the proper positioning (vMargins, spacing, and aspect ratios should remain the same while images scale to fill the extra space.)

Our Pinterest style layout will be achieved both by using Layout Inflation (using a LayoutInflater with a valid XML file). A LayoutInflater allows us to accept a valid XML file specifying part of an interactor hierarchy and convert it into a View object that can be added to the interactor hierarchy you are constructing. This can be seen in practice in the R.id.action_part_1 case in MainActivity#onCreate(Bundle), which uses one of the four overloaded LayoutInflater#inflate methods.

Note that there is a difference between Part1 and Part3 in how we get the LayoutInflater. We inflate Part1 in MainActivity#onCreate(Bundle), and because we’re in a subclass of Activity we can call Activity#getLayoutInflater(). This is not the case in Part3View, a subclass of View which does not have that method available. Instead we need to get the LayoutInflator from the class “factory” LayoutInflator#from(Context). See the documentation for more details.

The XML for your layout can be built by hand writing the code or by using the XML/visual editor which is often easier when building static app layouts. Once the XML has been written, we can use an inflater in our .java code convert the XML into an object before programmatically appending it to our current app layout.

The interactor hierarchy for Part 3 is shown below. The elements marked in light green must be created using inflation (and the part3_grid.xml file must do this). The elements shown in blue must be created programmatically. Note that we are using LinearLayout to hold the images (not ConstraintLayout as in Part 1 and 2).

graph LR C[ViewGroup:ConstraintLayout] C --> Column1[ViewGroup:LinearLayout] C --> Column2[ViewGroup:LinearLayout] Column1 --> V1[ImageView:Gumball] Column1 --> V2[ImageView:Fox] Column1 --> V3[...] Column2 --> V4[ImageView:Duckling] Column2 --> V5[...] classDef greenlarge fill:#dbf0db,stroke:#333,stroke-width:2px,font-size:12px,padding:0px,height:50px,top:1px; classDef bluelarge fill:#99ccff,stroke:#333,stroke-width:4px,font-size:12px,padding:0px,height:50px,top:1px; class C,Column1,Column2 greenlarge class V1,V2,V3,V4,V5 bluelarge

Tasks:

Your starter code for Part 3 has detailed comments to guide you in how to implement onMeasure. One tricky bit: you may find that the ImageView objects do not initially have a measurement. It will help to recall that with the implementation of Android’s Measure-Layout-Draw algorithm, you can force a parent view to measure itself, which will in turn force the children of that view to measure themselves.

Part 4

For Part 4 you are to re-create an interface from another popular app such as Twitter, Facebook, Instagram, etc. Most commercial products, however, are very complicated, so this is your chance to be creative in the design and implement your own version of the app. The goal is for you to synthesize what you have learned in class as well as explore other features (such as other types of Common Layouts) that we have not covered in class.

Your layout must meet the following requirements:

Note: Unfortunately, you will not be able to implement a “sticky” top or bottom bar for your custom layout. This is due to a limitation with the implementation of the scrolling behavior. We will not penalize you for leaving the “sticky” aspect of these bars out.

The Part4View.java starter code can be found in the cse340.layout directory. It extends from ConstraintLayout to give you maximum flexibility to allow you to add anything you need to achieve your desired design.

You may also note, that while the constructor has vMargin as a parameter, you are not required to use our vMargin value.

You may use the same images that are used in Part 3. If you wish to do so, you should simply call the appropriate method in MainActivity.java. There is a note on how to do this in the Part4View constuctor.

To keep your code organized you may wish to group some views together into a new View. If you choose to do this, we will accept an additional java file MyViewHolder.java and an extra layout, myviewholder.xml.

And finally, recall that there are four methods for inflating an XML file - research which one is appropriate for your creative layout implementation.

Tasks:

Past students have found the following links helpful in designing and implementing Part 4:

Part 5 (Reflection)

For this part, you will submit your reflection on this assignment to Gradescope. Create a MS Word, Google or other type of document and copy the following questions (in italics below) into that document. Add your responses below each question. You can have more than one answer per page, but if you can, please try to avoid page breaks in the middle of a question. Insert page breaks between questions as needed.

  1. Diagrams and images
    • The Layout Wireframe you drew for Part 4.
    • The interactor hierarchy you drew for Part 4. (Do not turn in a screen shot of the layout inspector for this).
    • A screenshot of the interface you are emulating, in both portrait and landscape mode. You must explicitly specify if the app you are emulating does not have a landscape mode.
    • A screen shot of your final interface in both portrait and landscape mode.
  2. For every interface there are generally multiple ways of laying it out, particularly if the interface is a complicated one. Reflect on your design and implementation of Part 4. What other ways you could emulate the same interface using different ViewGroups/Layouts. What would be the benefits or drawbacks to using these other Layouts?
  3. The image below is a simplified screen capture from a music playing app.
    • Draw a Layout Wireframe for the portion of the app shown. Your Wireframe should contain a minimum of four layouts. It may help to check out the Common Layouts.
    • Briefly justify the reason why you chose the layouts you did in part a).
    • Draw the interactor hierarchy for the portion of the screen shown below.
  4. Responsive design is when you create an application that “responds” to dynamic changes in the screen size or orientation of the device. Why are responsive designs important in user interfaces, software development and software engineering, as well as real life applications? Think beyond just an app on a screen…
  5. This class is part theory, part implementation. As such, lecture and section may not have provided you all of the information necessary to complete the layout program. How did you approach the independent learning required to complete this assignment? List at least one resource you used in your learning that would recommend to a friend taking this class in the future.
  6. Acknowledgements: Cite anything (website or other resource) or anyone that assisted you in creating your solution to this assignment. Remember to include all online resources (other than information learned in lecture or section and android documentation) such as Stack Overflow, other blogs, students in this class, or TAs and instructors who helped you during OH.

A screenshot of the Tidal app with a February Playlist playing My Power A screenshot of a music playing app.

Development Strategies

Rotation buttons on emulated android device

These buttons will allow you to rotate the emulated device clockwise/counter-clockwise.

Code quality and commenting your code

We expect that you will maintain the same Code Quality and Commenting standards as you did with our Doodle assignment. For details please see those sections.

Debugging tips and tricks

private static final String TAG = "Layout";

Log.i(TAG, "Hello world!");

To make full use of Logcat, make sure to configure the priority level (in this case, “Info”) and use the correct tag (in this case, “Layout”). It’s also good to check that you have the correct device/emulator selected.

Note: Remember to take your Log.i debugging calls out of your code before turning it in.

Android Log.* | Using Logcat

Turn in

Code Submission Instructions

We will test layout on emulators with different screen sizes. Please use constraints correctly. Don’t just try to match pixels in our sample screenshots.

You will turn in your source code files to the appropriate Ed Lessons for Part 1-2 and then for Part 3-4.

We are allowing you to turn in Part 1-2 early for a checkpoint to see how closely you match our tests. You will get 1 point for turning in code that compiles and passes up to half of the tests. If you pass more than half the tests, we will award you 2 points.

Make sure you only edited the following files for submission:

- Part2View.java
─ Part3View.java
─ Part4View.java
- res/drawable
- res/layout/part1.xml
- res/layout/part3_grid.xml
- res/values/strings.xml
- res/values/dimens.xml

Note: While you can edit the above files, please do not remove any of the existing drawables, Strings, or dimensions from them.

If you wish, you may also include the following extra files:

─ MyViewHolder.java
- res/layout/myviewholder.xml
- res/layout/part4.xml
- assets/part4.csv

Do not edit any of the other files that we have given you, do not delete any of the images in the res/drawable folder, and do not delete any existing strings in res/values/strings.xml (you may add bitmaps and strings of course.)

If you add your own images or other files for Part 4, please make sure to add, commit, and push them to your repository in the appropriate directories before turning in your assignment. If your images are not there, your custom layout will not work for others and you will NOT get credit for the work you did.

Note: Large images can be problematic both for running your app and for committing to your gitlab repository (there are size limit imposed on both Ed and Allen School resources). If you choose to add your own images, add at most 10MB of data (you will not be able to turn in your assignment in if it is larger than that). One solution is to resize your high resolution images before using them in your creative application.

Reflection submission

The reflection will be turned in to Gradescope.

Grading (50pts)

The Layout assignment will be out of 50 points and will roughly (subject to small adjustments) be distributed as:

Part 1-2 checkpoint (2pts) Note: this MUST be turned in on time to receive points. No late assignment for part 1-2 will be accepted.

Final checkpoint (48 pts)

IDE Errors/Warnings you can ignore

Note: DO NOT assume that because an error/warning can be ignored for this assignment, it can be ignored for all assignments. ALWAYS check the spec for each assignment before deciding what is OK to ignore.