---
layout: presentation
title: Introduction to Doodle Assignment
description: Introduction to Doodle Assignment
class: middle, center, inverse
---
# CSE 340 Lab 1: Doodle (Winter 2020)

## Introduction to Doodle

.title-slide-logo[
![:img Android Logo](img/android-logo.png)
]
---

.left-column[
## **Library** (and Inheritance Hierarchy)

<div class="mermaid">
    graph TD
    Activity[Activity]
    Activity -->|...| Doodler[Doodler]
    Doodler --> Part1[Part1]
    Part1 --> Part1Activity[Part1Activity]
    Part1 --> Part2Activity[Part2Activity]

    class Part1,Part1Activity,Part2Activity yellow
    class Activity,Doodler green
</div>
]

.right-column[
## Android Classes we are using in Doodle and how they relate

- Doodler (which you don't edit) *extends* [Activity](https://developer.android.com/reference/android/app/Activity)
- Part1 *extends* Doodler. It implements *helper methods* for Part1Activity and
Part2Activity.
- Part1Activity and Part2Activity both extend Part1
]
---
layout:none

.title[Running Sample Code]
.body[
When you accept the assignment on GitGrade, a repository containing the starter code is generated for you on CSE
GitLab. You **MUST** work within this assignment, as it will be turned in via GitGrade when it is due.

Please clone and use the repository and commit and push your work regularly.
Not only will doing so protect your code, but it will also allow course staff
to look at your code and it will allow you to easily pull any changes we make
to the assignment source.You can find instructions on setting up and maintaining
a forked repository [here](https://help.github.com/en/articles/working-with-forks).
]
---
## Cloning Doodle

.left-column[
You can find your unique repo by the notification email or by going to [GitLab](https://gitlab.cs.washington.edu) or via
the [GitGrade](https://gitgrade.cs.washington.edu) interface.
]

.right-column[
![:img Android Studio splash screen, 30%](img/doodle-clone-1.png)
![:img Android Studio clone dialog, 30%](img/doodle-clone-2.png)
]

---
.title[Open project in Android Studio]
.body[
- Run configurations should be automatically imported from Gradle
- If not, `build` should trigger an import
- Run with ►
- Connect an android device by USB or create a new virtual device
- If by USB, debugging must be enabled on the device
]
---
.title[Implementing `addImage`]
.body[
```java
private ImageView addImage(FrameLayout mainCanvas, String imageName, Float x, Float y, int size);
```

### Params:
- `mainCanvas`: Canvas in which to render the image.
- `imageName`: Filename of image to draw in `res/drawable`.
]
--
.body[
- `x`: Horizontal distance from top-left corner of canvas to top-left of image.
- `y`: Veritcal distance from top-left corner of canvas to top-left of image.
- `size`: Width and height of rendered image, in pixels.
]

---
.title[Implementing `addImage`]
.body[
### Returns:
- An `ImageView` which has been added to the canvas.
]

---
.title[Implementing `addImage`]
.body[
Break down into component steps, look up documentation, and implement

1. Create `ImageView`
]
--
.body[
2. Add new view to canvas
]
--
.body[
3. Position and set view size
]
--
.body[
4. Set view contents
]
---
.title[Implementing `addImage`]
.body[
```java
private ImageView addImage(FrameLayout mainCanvas, String imageName, Float x, Float y, int size) {
// Create ImageView and add it to mainCanvas.
ImageView imageView = new ImageView(this);
// Add imageView to mainCanvas
// Set imageView size and position
// Set imageView contents using filename
return imageView;
}
```
]
---
.title[Implementing `addImage`]
.body[
```java
private ImageView addImage(FrameLayout mainCanvas, String imageName, Float x, Float y, int size) {
// Create ImageView and add it to mainCanvas.
ImageView imageView = new ImageView(this);
mainCanvas.addView(imageView);
// Set imageView size and position
// Set imageView contents using filename
return imageView;
}
```
]
---
.title[Implementing `addImage`]
.body[
```java
private ImageView addImage(FrameLayout mainCanvas, String imageName, Float x, Float y, int size) {
// Create ImageView and add it to mainCanvas.
ImageView imageView = new ImageView(this);
mainCanvas.addView(imageView);

imageView.getLayoutParams().height = size;
imageView.getLayoutParams().width = size;

// Set imageView contents using filename
return imageView;
}
```
]
---
.title[Implementing `addImage`]
.body[
```java
private ImageView addImage(FrameLayout mainCanvas, String imageName, Float x, Float y, int size) {
// Create ImageView and add it to mainCanvas.
ImageView imageView = new ImageView(this);
mainCanvas.addView(imageView);

imageView.getLayoutParams().height = size;
imageView.getLayoutParams().width = size;
imageView.setX(x);
imageView.setY(y);

// Set imageView contents using filename
return imageView;
}
```
]
---
.title[Implementing `addImage`]
.body[
```java
private ImageView addImage(FrameLayout mainCanvas, String imageName, Float x, Float y, int size) {
// Create ImageView and add it to mainCanvas.
ImageView imageView = new ImageView(this);
mainCanvas.addView(imageView);

imageView.getLayoutParams().height = size;
imageView.getLayoutParams().width = size;
imageView.setX(x);
imageView.setY(y);

int resID = getResources().getIdentifier(imageName, "drawable", getPackage());
imageView.setImageResource(resID);
return imageView;
}
```
]


---
## `ValueAnimator`

- Keeps track of the animation's timing (how long its been running and current value of property)

- Contains a `TimeInterpolator` that defines the type of interpolation for the value over time

- Contains a `TypeEvaluator` that figures out how to calculate values for the property being animated

```java
ValueAnimator animation = ValueAnimator.ofFloat(0f, 1f);
animation.setDuration(1000);
// Starts the animation
animation.start();
// TODO: need to listen for updates to get the returned value
```
---
.title[How do we use pacing functions for this?]
.body[
![:img Picture of a curve transforming motion over time to create a pacing
effect, 40%](img/drawing/pacing.png)

- Time normalized with respect to animation interval (0...1)
- Normalized time is transformed by pacing function (0…1)
- Paced value is then fed to curve function to get final value

]
---
.title[XML shown in class]
.body[
```xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <objectAnimator android:propertyName="x" android:valueTo="100" />
</set>
```
]
---
```java
package com.example.myapplication;
//imports...

public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ImageView view = new ImageView(this);
setContentView(view);

Bitmap bitmap = Bitmap.createBitmap(100,100, Bitmap.Config.ARGB_8888);
view.setImageBitmap(bitmap);
Canvas c = new Canvas(bitmap);
Paint p = new Paint();
c.drawCircle(10,10,5,p);

ObjectAnimator anim = ObjectAnimator.ofFloat(view, "alpha", 1f, 0f);
anim.setDuration(2000);
anim.start();

Animator anim2 = (Animator) AnimatorInflater.loadAnimator(this,
R.animator.sample);
anim2.setTarget(view);
anim2.setDuration(2000);
anim2.start();
}
}
```