as2: Layout
Last revised: Jan 27, 2021- Jan 13, 2021
- Part1-2 Jan 21, 10:00pm
- Part3-4 Jan 28, 10:00pm
- Part3-4 Lock Jan 30, 10:00pm
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-size container views
- Learn about Inflators
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
- GitGrade links
- Assignment Description
- Introduction to Parts 1 and 2
- Part 3
- Part 4
- Part 5 (Reflection)
- Development Strategies
- Debugging tips and tricks
- Turn in
- Grading (40pts)
GitGrade links
Note: this is a 2 part assignment. You will work in the same repo for both, but you must accept part 1-2, turn in part 1-2, then accept part 3-4, then turn in part 3-4
Part 1-2: Accept the Assignment / Turn in the Assignment
Part 3-4: Accept the Assignment / Turn in the Assignment
Assignment Description
This is the assignment spec for Layout. Scroll down below Part 5 for some development strategies and tips curated from past students!
On average, students spent about 10 - 12 hours on average on this assignment. It has been modified somewhat since then, but make sure you get started early, as this can quickly become one of the more time-consuming assignments of the quarter.
Also an important note : Part 1-2 and Part 3-5 are NOT equivalent in difficulty. Part 1-2 should 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 at the end of your 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.
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:
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.
The important part of the interactor hierarchy for parts 1 and 2 is shown below:
We can represent this same interactor hierarchy visually in an Layout Wireframe shown below. Note that you will only be adding things inside the ConstraintLayout.
You will only be configuring the ImageViews as they relate to ConstraintLayout (shown in blue). Also this is simplified from what you would see in the Layout Inspector
And this video shows parts 1 and 2 in action:
Related Info
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:
- Use the tools provided by Android Studio to build a layout that vertically stacks images.
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:
- Familiarize yourself with how to reference images in res/drawable.
- Use the Visual and XML editor to construct a single, scrollable column of images.
- You must place a
vMargin
gap between images and their container, as well as between consecutive images. You do not have to ensure that the bottom image hasvMargin
space between it and its parent’s bottom.vMargin
is defined inres/values/dimens.xml
- Your layout must have enough images that you need to scroll (use
animal_0
throughanimal_4
) - Each image must be scaled so it fits horizontally and is centered while maintaining its aspect ratio. This requires you to set some attributes specific to ImageViews (not inherited) which are mentioned in the ImageView Documentation
- You must use constraints to ensure that an image is adjacent to the previous image (
Top_toBottomOf
) and that its left and right side are constrained to the parent container.
Related Info
- ConstraintLayout
- Linear Layouts
- ImageView
- ViewGroup.LayoutParams#MATCH_PARENT
- ViewGroup.LayoutParams#WRAP_CONTENT
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:
- You must accomplish the layout requirements from Part 1 programmatically, by setting layout parameters on Views in Java to accomplish your desired layout. In addition, Part2 to should be able to support an arbitrary number of images, not just the ones specified in an XML file.
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.
Part 3
Note: Remember to accept the as-layout-part-3-4 assignment and turn in the assignment when you are done.
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.
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. To do this you need 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 for this.
Note 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).
The XML/visual editor makes it much easier to build our app layouts, so we can use that to create new
layouts, then use an inflater to 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 the switch to LinearLayout
to hold the images.
Tasks:
- Before getting started on this section, try constructing a LayoutInflater and passing in your
part1.xml
file. - Once you are comfortable with inflation, use inflation to make use of the ConstraintLayout we have provided for you (
cse340.layout.R.layout.part3_grid
) - Use inflation to make use of the ConstraintLayout we have provided for you (
cse340.layout.R.layout.part3_grid
) - Try modifying it by hand to inflate with images in a Pinterest style layout to make sure you know what layout parameters you should be using
- Then remove those and programmatically create ImageViews based on the information passed in:
- Add each image to the bottom of one of the two columns.
- Which column an image is added to will depend on the current length of both columns (the image will be added to the bottom of the currently shorter column).
- Each image must be
vMargin
from the previous image vertically (or from the top of the column if it is the first image in that column). - There must be a
vMargin
gap between the left image and the left side of the screen, between the right image and the right side of the screen, and between the two columns. The center of thevMargin
gap between the two columns must be in the exact center of the screen. All images must be horizontally scaled to to be wide enough to meet these margins exactly. - The heights of the images must be scaled proportionally based on the constrained width.
- The bottom of the last image in the longer column must be flush with the bottom of that column. If the other column is shorter, then of course it will show more margin.
- Write code that evenly distributes ImageViews between a given set of columns based on the scaled height they will be on screen, not the dimensions from the drawable resource.
*
Note that all of this code must be in the contructor of the `Part3View` (or in a private method called by the constructor.)Note that most of this code will be inonMeasure()
Related Info
Part 4
The Part4View
starter code can be found in the cse340.layout
directory in Android Studio. It uses ConstraintLayout
to give you maximum flexibility, but you can add anything appropriate inside that as you wish.
For part 4, feel free to explore anything pertaining to layout that we have discussed over the last few weeks. You are not limited to only using the types of layout covered in class. Your task is to sketch (wireframe) and re-create an interface from another popular app. For instance: Twitter, Facebook, Instagram, etc. (not Pinterest!)
Your layout must meet the following requirements:
- Your layout must handle scrolling
- Your layout must be responsive to device orientation. If the user rotates their device, then your application must adjust to fit the new orientation.
- Your interface should be sufficiently similar to the one you’re emulating. Don’t leave out things like icons & text.
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 Tasks:
- Before you start, sketch the interface you’ve chosen to mock up as a Layout Wireframe on a piece of paper or using a tablet pen. This sketch will be turned in as part of your reflection in Part 5.
- Also draw out the Interactor Hierarchy for the interface. Your Interactor Hierarchy may be done with a computer program.
- Using XML and programatic means, create your version of this interface.
- Make sure that you create a Part4.xml file and add/commit/push it to your GitLab repository (a similar process to using your own pictures.)
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.
-
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 screen shot of your final interface and the the interface you are emulating, both in portrait and landscape mode.
- For every interface there may be multiple ways of laying it out, particularly if they are complicated. As you reflect on your design and implementation of part 4, think of another way you could wireframe the same interface using different ViewGroups/Layouts.
- 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.
- Why are responsive designs important, in user interfaces, software development and software engineering, and real life applications?
Development Strategies
- You may run into issues when rotating the device. Note, when rotating the emulated device or your personal Android device, that the layout must adjust accordingly. You do not need to readjust the layout of your images when rotating the device, as this must remain the same.
These buttons will allow you to rotate the emulated device clockwise/counter-clockwise.
- When dealing with the Android documentation: ask as many questions as necessary! The android documentation can be painful to read through, as there are many potential options to choose from. If you need any help parsing it, feel free to ask anyone on the course staff for advice. Additionally, we suggest that you read through the following resources as you develop your apps, to better understand the tools you are utilizing (these are referenced in their respective parts as well):
- An explanation of the ImageView ScaleType attribute (Part 1)
- Building a Responsive UI with Constraint Layout (Part 3) Note the “Set Size as a ratio” section here
- What’s new in Constraint Layout 1.1.0 (Part 4)
- Adjusting the view size
Debugging tips and tricks
- Recall that you can use the Layout Inspector to see where your views are placed in the parent. The Layout Inspector is can be found under the Tools menu.
- If your application stops running (the device displays an alert that says
“
has stopped"), you likely have a serious runtime error. Make sure to look at the _Run_ tab at the bottom of the screen. More information on runtime crashes is available through [developer.android.com](https://developer.android.com/topic/performance/vitals/crash) . - Your application may crash while inflating if there is a problem with your
.xml
file. - Logging output is especially useful for testing the functionality of sections of code such as
Layout#MainActivity#OnCreate
and other methods. Much likeSystem.out.print
in Java, Andriod provides its own class for producing output:Log
. We suggest that you useLog.i
and create your own custom tag so that you can filter the output for the information you want. Below is an example of how to use theLog.i
function.
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 MainActivity”). 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.
Related Info
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 the following files on GitGrade
- Part 1-2.
- Make sure you have accepted Part3-4 before turning that part in.
- Continue to work in your same repo
- Part 3-4.
We are allowing you to turn in Part 1-2 early for a checkpoint to see how closely you match our pixel 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:
─ Part1.java
- Part2View.java
─ Part3View.java
─ Part4View.java
- res/drawable
- res/layout/part1.xml
- res/layout/part3_grid.xml
- res/values/strings.xml
If you wish, you may also include three additional classes:
─ MyViewHolder.java
- res/layout/myviewholder.xml
- res/layout/part4.xml
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 in Part 4, please make sure to add and commit them to
your repository in the res/drawable
directory 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 school resources). Please make sure to resize your high resolution images before using them in your creative application.
Reflection submission
The reflection will be turned in to Gradescope.
Grading (40pts)
The Layout assignment will be out of 40 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.
- Turned in and compiles: 1 pt
- Passed >1/2 of tests: 1 pt
Final checkpoint (38 pts)
- Part 3-4 code (26 pts)
- Part 1 (6 pts) has correct layout (checking parameters margins and so on); and works in landscape mode; doesn’t overuse constraints (i.e. not too many)
- Part 2 (7 pts) has correct layout (as above); works in landscape mode; and can handle multiple images
- Part 3 (9 pts) has correct layout (checking parameters margins and so on); has correct Pinterest ordering; properly uses inflation
- Part 4 (4 pts) uses both XML and code (primarily evaluated in reflection)
- Reflection (12 pts)
- Layout Wireframe, Interactor Hierarchy, and screenshots of part 4 (3 pts total)
- Each of the 3 reflection questions is worth 3 points (9 pts total)
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.
-
Button
- Hardcoded Strings
-
TextView
- Hardcoded Strings
-
ImageView
- Missing
contentDescription
- Missing