https://developer.android.com/training/animation/overview

Animate bitmaps

When you want to animate a bitmap graphic such as an icon or illustration, you should use the drawable animation APIs. Usually, these animations are defined statically with a drawable resource, but you can also define the animation behavior at runtime.

Animate UI visibility and motion

When you need to change the visibility or position of views in your layout, you should include subtle animations to help the user understand how the UI is changing.

To move, reveal, or hide views within the current layout, you can use the property animation system provided by the android.animation package,

To create these animations with the least amount of effort, you can enable animations on your layout so that when you simply change the visibility of a view, an animation applies automatically.

Physics-based motion

Two common physics-based animations are the following:

  • Spring Animation
  • Fling Animation

Animations not based on physics—such as those built with ObjectAnimator APIs—are fairly static and have a fixed duration. If the target value changes, you need to cancel the animation at the time of target value change, re-configure the animation with a new value as the new start value, and add the new target value. Visually, this process creates an abrupt stop in the animation, and a disjointed movement afterwards, as shown in figure 3.

Whereas, animations built by with physics-based animation APIs such as DynamicAnimation are driven by force. The change in the target value results in a change in force. The new force applies on the existing velocity, which makes a continuous transition to the new target. This process results in a more natural-looking animation, as shown in figure 4.

Animate layout changes

On Android 4.4 (API level 19) and higher, you can use the transition framework to create animations when you swap the layout within the current activity or fragment. All you need to do is specify the starting and ending layout, and what type of animation you want to use. Then the system figures out and executes an animation between the two layouts. You can use this to swap out the entire UI or to move/replace just some views.

The starting and ending layout are each stored in a Scene, though the starting scene is usually determined automatically from the current layout. You then create a Transition to tell the system what type of animation you want, and then call TransitionManager.go() and the system runs the animation to swap the layouts.

Animate between activities

On Android 5.0 (API level 21) and higher, you can also create animations that transition between your activities. This is based on the same transition framework described above to animate layout changes, but it allows you to create animations between layouts in separate activities.

You can apply simple animations such as sliding the new activity in from the side or fading it in, but you can also create animations that transition between shared views in each activity.

As usual, you call startActivity(), but pass it a bundle of options provided by ActivityOptions.makeSceneTransitionAnimation(). This bundle of options may include which views are shared between the activities so the transition framework can connect them during the animation.

https://developer.android.com/guide/topics/graphics/prop-animation

Property Animation Overview

You can define an animation to change any object property over time, regardless of whether it draws to the screen or not. A property animation changes a property’s (a field in an object) value over a specified length of time.

The property animation system lets you define the following characteristics of an animation:

  • Duration: The default length is 300 ms.
  • Time interpolation
  • Repeat count and behavior: You can specify whether or not to have an animation repeat and how many times to repeat the animation. You can also specify whether you want the animation to play back in reverse. Setting it to reverse plays the animation forwards then backwards repeatedly, until the number of repeats is reached.
  • Animator sets: You can group animations into logical sets that play together or sequentially or after specified delays.
  • Frame refresh delay: You can specify how often to refresh frames of your animation.

Property Animation Overview

The property animation system is a robust framework that allows you to animate almost anything. You can define an animation to change any object property over time, regardless of whether it draws to the screen or not. A property animation changes a property’s (a field in an object) value over a specified length of time. To animate something, you specify the object property that you want to animate, such as an object’s position on the screen, how long you want to animate it for, and what values you want to animate between.

The property animation system lets you define the following characteristics of an animation:

  • Duration: You can specify the duration of an animation. The default length is 300 ms.
  • Time interpolation: You can specify how the values for the property are calculated as a function of the animation’s current elapsed time.
  • Repeat count and behavior: You can specify whether or not to have an animation repeat when it reaches the end of a duration and how many times to repeat the animation. You can also specify whether you want the animation to play back in reverse. Setting it to reverse plays the animation forwards then backwards repeatedly, until the number of repeats is reached.
  • Animator sets: You can group animations into logical sets that play together or sequentially or after specified delays.
  • Frame refresh delay: You can specify how often to refresh frames of your animation. The default is set to refresh every 10 ms, but the speed in which your application can refresh frames is ultimately dependent on how busy the system is overall and how fast the system can service the underlying timer.

To see a full example of property animation, see the ChangeColor class in the android-CustomTransition sample on GitHub.

How property animation differs from view animation

The view animation system provides the capability to only animate View objects, so if you wanted to animate non-View objects, you have to implement your own code to do so. The view animation system is also constrained in the fact that it only exposes a few aspects of a View object to animate, such as the scaling and rotation of a View but not the background color, for instance.

Another disadvantage of the view animation system is that it only modified where the View was drawn, and not the actual View itself. For instance, if you animated a button to move across the screen, the button draws correctly, but the actual location where you can click the button does not change, so you have to implement your own logic to handle this.

  • Depending on what property or object you are animating, you might need to call the invalidate() method on a View to force the screen to redraw itself with the updated animated values. You do this in the onAnimationUpdate() callback. For example, animating the color property of a Drawable object only causes updates to the screen when that object redraws itself. All of the property setters on View, such as setAlpha() and setTranslationX() invalidate the View properly, so you do not need to invalidate the View when calling these methods with new values. For more information on listeners, see the section about Animation listeners.

Choreograph multiple animations using an AnimatorSet

The Android system lets you bundle animations together into an AnimatorSet, so that you can specify whether to start animations simultaneously, sequentially, or after a specified delay. You can also nest AnimatorSet objects within each other.

Animation listeners

You can listen for important events during an animation

  • Animator.AnimatorListener
  • ValueAnimator.AnimatorUpdateListener
  • onAnimationStart() – Called when the animation starts.
  • onAnimationEnd() – Called when the animation ends.
  • onAnimationRepeat() – Called when the animation repeats itself.
  • onAnimationCancel() – Called when the animation is canceled. A cancelled animation also calls onAnimationEnd(), regardless of how they were ended.
  • onAnimationUpdate() – called on every frame of the animation. Depending on what property or object you are animating, you might need to call invalidate() on a View to force that area of the screen to redraw itself with the new animated values. setAlpha() and setTranslationX() need invalidate() 

You can extend the AnimatorListenerAdapter class instead of implementing the Animator.AnimatorListener interface.

Animate layout changes to ViewGroup objects

실제작동) https://youtu.be/55wLsaWpQ4g

customizing 하려면 아래 내용 참조

You can animate layout changes within a ViewGroup with the LayoutTransition class. Views inside a ViewGroup can go through an appearing and disappearing animation when you add them to or remove them from a ViewGroup or when you call a View’s setVisibility() method with VISIBLE, INVISIBLE, or GONE. The remaining Views in the ViewGroup can also animate into their new positions when you add or remove Views. You can define the following animations in a LayoutTransition object by calling setAnimator() and passing in an Animator object with one of the following LayoutTransition constants:

  • APPEARING – A flag indicating the animation that runs on items that are appearing in the container.
  • CHANGE_APPEARING – A flag indicating the animation that runs on items that are changing due to a new item appearing in the container.
  • DISAPPEARING – A flag indicating the animation that runs on items that are disappearing from the container.
  • CHANGE_DISAPPEARING – A flag indicating the animation that runs on items that are changing due to an item disappearing from the container.

You can define your own custom animations for these four types of events to customize the look of your layout transitions or just tell the animation system to use the default animations.

간단한 사용방법

<LinearLayout 
   android:orientation="vertical"
   android:layout_width="wrap_content"
   android:layout_height="match_parent"
   android:id="@+id/verticalContainer"
   android:animateLayoutChanges="true" />

Setting this attribute to true automatically animates Views that are added or removed from the ViewGroup as well as the remaining Views in the ViewGroup.

Animate view state changes using StateListAnimator

view의 상태 변화에 따른 animation. 이를 구현하는 방법으로는 두가지가 있다. 

  1. property animation – StateListAnimator class 이용하는 방법
  2. drawable animation 

property animation – StateListAnimator class 이용하는 방법

The StateListAnimator class lets you define animators that run when the state of a view changes. This object behaves as a wrapper for an Animator object, calling that animation whenever the specified view state (such as “pressed” or “focused”) changes.

The StateListAnimator can be defined in an XML resource with a root <selector> element and child <item> elements that each specify a different view state defined by the StateListAnimator class. Each <item> contains the definition for a property animation set ( 여러개의 animation 모음 ).

res/xml/animate_scale.xml

<?xml version="1.0" encoding="utf-8"?> 
<selector xmlns:android="http://schemas.android.com/apk/res/android">
   <!-- the pressed state; increase x and y size to 150% -->
   <item android:state_pressed="true">
       <set>
           <objectAnimator android:propertyName="scaleX"
               android:duration="@android:integer/config_shortAnimTime"
               android:valueTo="1.5"
               android:valueType="floatType"/>
           <objectAnimator android:propertyName="scaleY"
               android:duration="@android:integer/config_shortAnimTime"
               android:valueTo="1.5"
               android:valueType="floatType"/>
       </set>
   </item>
   <!-- the default, non-pressed state; set x and y size to 100% -->
   <item android:state_pressed="false">
       <set>
           <objectAnimator android:propertyName="scaleX"
               android:duration="@android:integer/config_shortAnimTime"
               android:valueTo="1"
               android:valueType="floatType"/>
           <objectAnimator android:propertyName="scaleY"
               android:duration="@android:integer/config_shortAnimTime"
               android:valueTo="1"
               android:valueType="floatType"/>
       </set>
   </item>
</selector>

위의 state list animator를 view에 덧붙이는 방법은 두가지 

  1. xml 방법
  2. code 방법

xml 방법

<Button android:stateListAnimator="@xml/animate_scale" 
       ... />

code 방법

AnimatorInflater.loadStateListAnimator() method, and assign the animator to your view with the View.setStateListAnimator() method.

drawable animation ( 뉴스완장 작업시 내가 사용한 적이 있음 )

<!-- res/drawable/myanimstatedrawable.xml --> 
<animated-selector
   xmlns:android="http://schemas.android.com/apk/res/android">

   <!-- provide a different drawable for each state-->
   <item android:id="@+id/pressed" android:drawable="@drawable/drawableP"
       android:state_pressed="true"/>
   <item android:id="@+id/focused" android:drawable="@drawable/drawableF"
       android:state_focused="true"/>
   <item android:id="@id/default"
       android:drawable="@drawable/drawableD"/>

   <!-- specify a transition -->
   <transition android:fromId="@+id/default" android:toId="@+id/pressed">
       <animation-list>
           <item android:duration="15" android:drawable="@drawable/dt1"/>
           <item android:duration="15" android:drawable="@drawable/dt2"/>
           ...
       </animation-list>
   </transition>
   ...
</animated-selector>

Use a TypeEvaluator

animation 진행되면서 변화하는 property value를 만들어주는 class. 

Android system are int, float, or a color, which are supported by the IntEvaluator, FloatEvaluator, and ArgbEvaluator type evaluators.

Use Interpolators

The Android system provides a set of common interpolators in the android.view.animation package

Specify keyframes

A Keyframe object consists of a time/value pair that lets you define a specific state at a specific time of an animation. 

Keyframe.ofFloat( 시간, 밸류 )

Keyframe kf0 = Keyframe.ofFloat(0f, 0f); 
Keyframe kf1 = Keyframe.ofFloat(.5f, 360f);
Keyframe kf2 = Keyframe.ofFloat(1f, 0f);
PropertyValuesHolder pvhRotation = PropertyValuesHolder.ofKeyframe("rotation", kf0, kf1, kf2);
ObjectAnimator rotationAnim = ObjectAnimator.ofPropertyValuesHolder(target, pvhRotation);
rotationAnim.setDuration(5000);

drawable image를 이용한 keyframe animation – 영화필름작업과 유사 ( 위의 keyframe과는 전혀 무관함 헷갈리지 않기를 ) https://youtu.be/V3ksidLf7vA

Animate views

view animation은 겉모양만 변경시킨다.

The property animation system can animate Views on the screen by changing the actual properties in the View objects. In addition, Views also automatically call the invalidate() method to refresh the screen

property 종류

  • translationX and translationY
  • rotation, rotationX, and rotationY
  • scaleX and scaleY
  • pivotX and pivotY
  • x and y: These are simple utility properties to describe the final location of the View in its container, as a sum of the left and top values and translationX and translationY values.
  • alpha

사용 예시

ObjectAnimator.ofFloat(myView, "rotation", 0f, 360f);

Animate using ViewPropertyAnimator

The ViewPropertyAnimator provides a simple way to animate several properties of a View in parallel. 

아래 세 코드들은 다 같은 결과를 가져온다. 각기 다른 방법으로 구현 가능

ViewPropertyAnimator

myView.animate().x(50f).y(100f);

Multiple ObjectAnimator objects와 AnimatorSet 를 이용한 방법

ObjectAnimator animX = ObjectAnimator.ofFloat(myView, "x", 50f); 
ObjectAnimator animY = ObjectAnimator.ofFloat(myView, "y", 100f);
AnimatorSet animSetXY = new AnimatorSet();
animSetXY.playTogether(animX, animY);
animSetXY.start();

one ObjectAnimator를 이용한 방법

PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("x", 50f); 
PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("y", 100f);
ObjectAnimator.ofPropertyValuesHolder(myView, pvhX, pvhY).start();

Declare animations in XML

xml을 이용 animation을 구현하는 방법

  • ValueAnimator<animator>
  • ObjectAnimator<objectAnimator>
  • AnimatorSet<set>
<set android:ordering="sequentially"> 
   <set>
       <objectAnimator
           android:propertyName="x"
           android:duration="500"
           android:valueTo="400"
           android:valueType="intType"/>
       <objectAnimator
           android:propertyName="y"
           android:duration="500"
           android:valueTo="300"
           android:valueType="intType"/>
   </set>
   <objectAnimator
       android:propertyName="alpha"
       android:duration="500"
       android:valueTo="1f"/>
</set>

위와 같이 xml화일을 만들고 아래 코드를 activity, fragment에 넣어줘야 한다.

AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(myContext, 
   R.animator.property_animator);
set.setTarget(myObject);
set.start();

ValueAnimator를 이용한 예시도 docs에 있다.   https://developer.android.com/guide/topics/graphics/prop-animation

Animate drawable graphics

The first option is to use an Animation Drawable. This allows you to specify several static drawable files that will be displayed one at a time to create an animation. The second option is to use an Animated Vector Drawable, which lets you animate the properties of a vector drawable.

Use AnimationDrawable

The AnimationDrawable class is the basis for Drawable animations.

While you can define the frames of an animation in your code, using the AnimationDrawable class API, it’s more simply accomplished with a single XML file that lists the frames that compose the animation. The XML file for this kind of animation belongs in the res/drawable/ directory.

<animation-list xmlns:android="http://schemas.android.com/apk/res/android" 
   android:oneshot="true">
   <item android:drawable="@drawable/rocket_thrust1" android:duration="200" />
   <item android:drawable="@drawable/rocket_thrust2" android:duration="200" />
   <item android:drawable="@drawable/rocket_thrust3" android:duration="200" />
</animation-list>

By setting the android:oneshot attribute of the list to true, it will cycle just once then stop and hold on the last frame. If it is set false then the animation will loop. 

AnimationDrawable rocketAnimation; 

public void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.main);

 ImageView rocketImage = (ImageView) findViewById(R.id.rocket_image);
 rocketImage.setBackgroundResource(R.drawable.rocket_thrust);
 rocketAnimation = (AnimationDrawable) rocketImage.getBackground();

 rocketImage.setOnClickListener(new View.OnClickListener() {
     @Override
     public void onClick(View view) {
       rocketAnimation.start();
     }
 });
}

start() method called on the AnimationDrawable cannot be called during the onCreate() method of your Activity, because the AnimationDrawable is not yet fully attached to the window. call it from the onStart() method in your Activity.

Use AnimatedVectorDrawable

svg image file을 shapeshifter를 이용해서 android에서 사용가능한 xml화일로 바꾸고 이를 ImageView에서 연다.

위에서 언급한 과정을 보여주는 예시 동영상 https://youtu.be/TfiZmzqAMgA

https://developer.android.com/training/animation/reveal-or-hide-view

Reveal or hide a view using animation

자주 사용하는 animation 3가지 설명

Create a crossfade animation

Create a card flip animation

Create a circular reveal animation

     – 참고자료)  https://youtu.be/X5hQv2uadjk

https://developer.android.com/training/animation/reposition-view

Move a View with Animation

Change the view position with ObjectAnimator

The ObjectAnimator API provides an easy way to change the properties of a view with a specified duration.

ObjectAnimator animation = ObjectAnimator.ofFloat(view, "translationX", 100f); 
animation.setDuration(2000);
animation.start();

Add curved motion

Use PathInterpolator

The PathInterpolator class is a new interpolator introduced in Android 5.0 (API 21). view가 이동하는 궤적을 휘어지게 한다.

// arcTo() and PathInterpolator only available on API 21+ 
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
 Path path = new Path();
 path.arcTo(0f, 0f, 1000f, 1000f, 270f, -180f, true);
 PathInterpolator pathInterpolator = new PathInterpolator(path);
}

You can also define a path interpolator as an XML resource:

<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android" 
   android:controlX1="0.4"
   android:controlY1="0"
   android:controlX2="1"
   android:controlY2="1"/>
ObjectAnimator animation = ObjectAnimator.ofFloat(view, "translationX", 100f); 
animation.setInterpolator(pathInterpolator);
animation.start();

Define your own path

The ObjectAnimator class has new constructors that enable you to animate coordinates along a path using two or more properties at once along with a path.

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 
 Path path = new Path();
 path.arcTo(0f, 0f, 1000f, 1000f, 270f, -180f, true);
 ObjectAnimator animator = ObjectAnimator.ofFloat(view, View.X, View.Y, path);
 animator.setDuration(2000);
 animator.start();
} else {
 // Create animator without using curved path
}

https://developer.android.com/guide/topics/graphics/fling-animation

Move views using a fling animation

image

Add the support library

dependencies { 
     implementation 'com.android.support:support-dynamic-animation:28.0.0'
 }
 

Create a fling animation

FlingAnimation fling = new FlingAnimation(view, DynamicAnimation.SCROLL_X);

Set velocity

You can use a fixed value as the starting velocity, or you can base it off of the velocity of a touch gesture. If you choose to provide a fixed value, you should define the value in dp per second, then convert it to pixels per second. Defining the value in dp per second allows the velocity to be independent of a device’s density and form factors.

Note: Use the GestureDetector.OnGestureListener and the VelocityTracker classes to retrieve and compute the velocity of touch gestures, respectively. ( 사용자의 스와이프 속도에 따른 속도설정 )

Set an animation value range

setMinValue() and setMaxValue() methods

Set friction

setFriction() method lets you change the animation’s friction. 

Sample code

FlingAnimation fling = new FlingAnimation(view, DynamicAnimation.SCROLL_X); 
fling.setStartVelocity(-velocityX)
       .setMinValue(0)
       .setMaxValue(maxScroll)
       .setFriction(1.1f)
       .start();

Set the minimum visible change

anim.setMinimumVisibleChange(DynamicAnimation.MIN_VISIBLE_CHANGE_SCALE);

https://developer.android.com/guide/topics/graphics/spring-animation

Animate movement using spring physics

the SpringForce class lets you customize spring’s stiffness, its damping ratio, and its final position.

간단한 사용방법

  • Add the support library You must add the support library to your project to use the spring animation classes.
  • Create a spring animation: create an instance of the SpringAnimation class and set the motion behavior parameters.
  • (Optional) Register listeners: Register listeners to watch for animation lifecycle changes and animation value updates.

Note: Update listener should be registered only if you need per-frame update on the animation value changes. An update listener prevents the animation from potentially running on a separate thread

  • (Optional) Remove listeners
  • (Optional) Set a start value
  • (Optional) Set a value range: Set the animation value range to restrain values within the minimum and the maximum range.
  • (Optional) Set start velocity: Set the start velocity for the animation.
  • (Optional) Set spring properties: Set the damping ratio and the stiffness on the spring.
  • (Optional) Create a custom spring
  • Start animation: Start the spring animation.
  • (Optional) Cancel animation

.

Add the support library

fling animation 에서도 같은 library를 이용한다. 

(참고로 circular reveal animation는 Android 5.0 (API level 21) and higher 에 기본내장)

(참고로 zoomin, crossfader, card filp은 원래 sdk에 내장되어있는 library이용)

  1. Open the build.gradle file for your app module.
  2. Add the support library to the dependencies section.
  dependencies { 
     implementation 'com.android.support:support-dynamic-animation:28.0.0'
 }

Create a spring animation

final View img = findViewById(R.id.imageView); 
// Setting up a spring animation to animate the view’s translationY property with the final
// spring position at 0.
final SpringAnimation springAnim = new SpringAnimation(img, DynamicAnimation.TRANSLATION_Y, 0);

The spring-based animation can animate views on the screen by changing the actual properties in the view objects. 아래 property 밸류가 스프링 운동으로 변하게 된다.

  • ALPHA
  • TRANSLATION_X, TRANSLATION_Y, and TRANSLATION_Z

         TRANSLATION_X describes the left coordinate.
         TRANSLATION_Y describes the top coordinate.
         TRANSLATION_Z describes the depth of the view relative to its elevation.

  • ROTATION, ROTATION_X, and ROTATION_Y: These properties control the rotation in 2D (rotation property) and 3D around the pivot point.
  • SCROLL_X and SCROLL_Y: These properties indicate the scroll offset of the source left and the top edge in pixels. It also indicates the position in terms how much the page is scrolled.
  • SCALE_X and SCALE_Y
  • X, Y, and Z: These are basic utility properties to describe the final location of the view in its container.

         X is a sum of the left value and TRANSLATION_X.
         Y is a sum of the top value and TRANSLATION_Y.
         Z is a sum of the elevation value and TRANSLATION_Z

Register listeners

DynamicAnimation class ( sprint animation 포함 ) provides two listeners: OnAnimationUpdateListener and OnAnimationEndListener.

OnAnimationUpdateListener

When you want to animate multiple views to create a chained animation, you can set up OnAnimationUpdateListener to receive a callback every time there is a change in the current view’s property. The callback notifies the other view to update its spring position based on the change incurred in the current view’s property.

// Creating two views to demonstrate the registration of the update listener. 
final View view1 = findViewById(R.id.view1);
final View view2 = findViewById(R.id.view2);

// Setting up a spring animation to animate the view1 and view2 translationX and translationY properties
final SpringAnimation anim1X = new SpringAnimation(view1,
       DynamicAnimation.TRANSLATION_X);
final SpringAnimation anim1Y = new SpringAnimation(view1,
   DynamicAnimation.TRANSLATION_Y);
final SpringAnimation anim2X = new SpringAnimation(view2,
       DynamicAnimation.TRANSLATION_X);
final SpringAnimation anim2Y = new SpringAnimation(view2,
       DynamicAnimation.TRANSLATION_Y);

// Registering the update listener
anim1X.addUpdateListener(new DynamicAnimation.OnAnimationUpdateListener() {

// Overriding the method to notify view2 about the change in the view1’s property.
   @Override
   public void onAnimationUpdate(DynamicAnimation dynamicAnimation, float value,
                                 float velocity) {
       anim2X.animateToFinalPosition(value);
   }
});

anim1Y.addUpdateListener(new DynamicAnimation.OnAnimationUpdateListener() {

 @Override
   public void onAnimationUpdate(DynamicAnimation dynamicAnimation, float value,
                                 float velocity) {
       anim2Y.animateToFinalPosition(value);
   }
});

OnAnimationEndListener

  1. Call the addEndListener() method and attach the listener to the animation.
  2. Override the onAnimationEnd() method to receive notification whenever an animation reaches equilibrium or is canceled.

Remove listeners

call removeUpdateListener() and removeEndListener() methods.

Set animation start value

call the setStartValue() method and pass the start value of the animation. If you do not set the start value, the animation uses the current value of the object’s property as the start value.

Set animation value range

when you want to restrain the property value to a certain range.

  • setMinValue()
  • setMaxValue()

아래 작업들은 SpringForce obj에 각 특성들을 설정하는 작업

Set start velocity ( fling animation과 같다. )

Start velocity defines the speed at which the animation property changes at the beginning of the animation. The default start velocity is set to zero pixels per second. You can set a fixed value as the start velocity. If you choose to provide a fixed value, we recommend to define the value in dp per second and then convert it to pixels per second. Defining the value in dp per second allows velocity to be independent of density and form factors. For more information about converting value to pixels per second, refer to the Converting dp per second to pixels per second section.

To set the velocity, call the setStartVelocity() method and pass the velocity in pixels per second. The method returns the spring force object on which the velocity is set.

Note: Use the GestureDetector.OnGestureListener or the VelocityTracker class methods to retrieve and compute the velocity of touch gestures.

final View img = findViewById(R.id.imageView); 
final SpringAnimation anim = new SpringAnimation(img, DynamicAnimation.TRANSLATION_Y);

// Compute velocity in the unit pixel/second
vt.computeCurrentVelocity(1000);
float velocity = vt.getYVelocity();
anim.setStartVelocity(velocity);

Converting dp per second to pixels per second

float pixelPerSecond = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpPerSecond, getResources().getDisplayMetrics());

Set spring properties

The SpringForce class defines the getter and the setter methods for each of the spring properties, such as damping ratio and stiffness.

setting method는 obj 자신을 return 하므로 chaining 이 가능하다. 

Damping ratio

  1. getSpring() to retrieve the SpringForce obj.
  2. setDampingRatio()  damping ratio must be a non-negative number. If you set the damping ratio to zero, the spring will never reach the rest position. In other words, it oscillates forever.

ratio constants are available in the system:

  • DAMPING_RATIO_HIGH_BOUNCY
  • DAMPING_RATIO_MEDIUM_BOUNCY
  • DAMPING_RATIO_LOW_BOUNCY
  • DAMPING_RATIO_NO_BOUNCY
final View img = findViewById(R.id.imageView); 
final SpringAnimation anim = new SpringAnimation(img, DynamicAnimation.TRANSLATION_Y);

//Setting the damping ratio to create a low bouncing effect.
anim.getSpring().setDampingRatio(SpringForce.DAMPING_RATIO_LOW_BOUNCY);

Stiffness

the strength of the spring. 

  1. getSpring() to retrieve SpringForce obj.
  2. setStiffness() Note: The stiffness must be a positive number.

stiffness constants are available in the system:

  • STIFFNESS_HIGH
  • STIFFNESS_MEDIUM
  • STIFFNESS_LOW
  • STIFFNESS_VERY_LOW
final View img = findViewById(R.id.imageView); 
final SpringAnimation anim = new SpringAnimation(img, DynamicAnimation.TRANSLATION_Y);

//Setting the spring with a low stiffness.
anim.getSpring().setStiffness(SpringForce.STIFFNESS_LOW);

    Create a custom spring force

    1. Create a SpringForce object.
    2. Assign the properties by calling the respective methods. You can also create a method chain.
    3. Call the setSpring() method to set the spring to the animation.

    SpringForce force = new SpringForce();

    force.setDampingRatio(DAMPING_RATIO_LOW_BOUNCY).setStiffness(STIFFNESS_LOW);

    setSpring(force);

    Start animation

    There are two ways you can start a spring animation: By calling the start() or by calling the animateToFinalPosition() method. Both the methods need to be called on the main thread.

    animateToFinalPosition() method performs two tasks:

    • Sets the final position of the spring – setFinalPosition()
    • Starts the animation, if it has not started.
    final View img = findViewById(R.id.imageView); 
    final SpringAnimation anim = new SpringAnimation(img, DynamicAnimation.TRANSLATION_Y);

    //Starting the animation
    anim.start();

    Cancel animation

    사용자 갑자가 exit 하는 경우 cancel 처리한다.

    There are two methods. The cancel() method terminates the animation at the value where it is. The skipToEnd() method skips the animation to the final value and then terminates it.

    Before you can terminate the animation, it is important to first check the state of the spring. If the state is undamped, the animation can never reach the rest position. To check the state of the spring, call the canSkipToEnd() method. If the spring is damped, the method returns true, otherwise false.

    The cancel() method must be called only on the main thread.

    Note: the skipToEnd() method causes a visual jump.

    https://developer.android.com/training/animation/layout

    Auto animate layout updates

    <LinearLayout android:id="@+id/container" 
       android:animateLayoutChanges="true"
       ...
    />

    android:animateLayoutChanges attribute를 설정함으로써 layout안에 element가 만들어지고 사라질때 시스템이 제공하는 애니메이션을 적용할수 있다. 

    Tip: If you want to supply custom layout animations, create a LayoutTransition object and supply it to the layout with the setLayoutTransition() method.

    https://developer.android.com/training/transitions/

    Animate layout changes using a transition

    참고) https://code.tutsplus.com/tutorials/an-introduction-to-android-transitions–cms-21640

    https://www.youtube.com/watch?v=00uf3cwC0I0

    변화전 layout scene 변화후 layout scene을 정하면 자동으로 animation이 적용된다. 적용되는 animation 종류도 여러가지가 있다. 

    scene간의 layout transition animation을 사용할때의 장점

    • Group-level animations: Apply one or more animation effects to all of the views in a view hierarchy.
    • Built-in animations: Use predefined animations for common effects such as fade out or movement.
    • Resource file support: Load view hierarchies and built-in animations from layout resource files.
    • Lifecycle callbacks: Receive callbacks that provide control over the animation and hierarchy change process.

    Note: between layouts within the same activity. If the user is moving between activities then you should instead read Start an activity using an animation.

    The basic process to animate between two layouts is as follows:

    1. Create a Scene object for both the starting layout and the ending layout. However, the starting layout’s scene is often determined automatically from the current layout.
    2. Create a Transition object to define what type of animation you want.
    3. Call TransitionManager.go() and the system runs the animation to swap the layouts.

    Create a scene

    Scenes store the state of a view hierarchy, including all its views and their property values. The transitions framework can run animations between a starting and an ending scene.

    You can create your scenes from a layout resource file or from a group of views in your code. However, the starting scene for your transition is often determined automatically from the current UI.

    A scene can also define its own actions that run when you make a scene change.

    Note: The framework can animate changes in a single view hierarchy without using scenes, as described in Apply a transition without scenes. 

    Create a scene from a layout resource

    You can create a Scene instance directly from a layout resource file. Use this technique when the view hierarchy in the file is mostly static. The resulting scene represents the state of the view hierarchy at the time you created the Scene instance. If you change the view hierarchy, you have to recreate the scene. The framework creates the scene from the entire view hierarchy in the file; you can not create a scene from part of a layout file.

    To create a Scene instance from a layout resource file, retrieve the scene root ( 이란 scene을 포함하게 될 container layout 아래 예에서는 framelayout id scene_root 이 해당된다 ) from your layout as a ViewGroup instance and then call the Scene.getSceneForLayout() function with the scene root and the resource ID of the layout file that contains the view hierarchy for the scene.

    예시코드) 

    res/layout/activity_main.xml

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
       android:id="@+id/master_layout">
       <TextView
           android:id="@+id/title"
           ...
           android:text="Title"/>
       <FrameLayout
           android:id="@+id/scene_root">
           <include layout="@layout/a_scene" />
       </FrameLayout>
    </LinearLayout>

    scene은 xml화일 부분을 가지고 만들수 없으므로 예시에서는 scene에 해당하는 layout file을 따로 만들고 include를 이용 포함 시켰다. 

    res/layout/a_scene.xml

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
       android:id="@+id/scene_container"
       android:layout_width="match_parent"
       android:layout_height="match_parent" >
       <TextView
           android:id="@+id/text_view1
           android:text="Text Line 1" />
       <TextView
           android:id="@+id/text_view2
           android:text="Text Line 2" />
    </RelativeLayout>

    res/layout/another_scene.xml

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
       android:id="@+id/scene_container"
       android:layout_width="match_parent"
       android:layout_height="match_parent" >
       <TextView
           android:id="@+id/text_view2
           android:text="Text Line 2" />
       <TextView
           android:id="@+id/text_view1
           android:text="Text Line 1" />
    </RelativeLayout>

    scenes 이 될 두 xml화일들은 같은 elements를 가지고 있으며 위치만 다르다.( 꼭 이렇게 같은 element로 구성되어야 하는지는 확인이 필요하다. )

    Generate scenes from layouts

    Scene mAScene; 
    Scene mAnotherScene;

    // Create the scene root for the scenes in this app
    mSceneRoot = (ViewGroup) findViewById(R.id.scene_root);

    // Create the scenes
    mAScene = Scene.getSceneForLayout(mSceneRoot, R.layout.a_scene, this);
    mAnotherScene =
       Scene.getSceneForLayout(mSceneRoot, R.layout.another_scene, this);

    Create a scene in your code

    You can also create a Scene instance in your code from a ViewGroup object. Use this technique when you modify the view hierarchies directly in your code or when you generate them dynamically.

    Scene mScene; 

    // Obtain the scene root element
    mSceneRoot = (ViewGroup) mSomeLayoutElement;

    // Obtain the view hierarchy to add as a child of
    // the scene root when this scene is entered
    mViewHierarchy = (ViewGroup) someOtherLayoutElement;

    // Create a scene
    mScene = new Scene(mSceneRoot, mViewHierarchy);

    Create scene actions

    ( layout이 바뀌어 transition되는 과정에 추가 작업을 할수 있는 hook functions에 대한 설명 )

    The framework enables you to define custom scene actions that the system runs when entering or exiting a scene. In many cases, defining custom scene actions is not necessary, since the framework animates the change between scenes automatically.

    Scene actions are useful for handling these cases:

    • Animate views that are not in the same hierarchy. You can animate views for both the starting and ending scenes using exit and entry scene actions.
    • Animate views that the transitions framework cannot animate automatically, such as ListView objects. For more information, see Limitations.

    To provide custom scene actions, define your actions as Runnable objects and pass them to the Scene.setExitAction() or Scene.setEnterAction() functions. The framework calls the setExitAction() function on the starting scene before running the transition animation and the setEnterAction() function on the ending scene after running the transition animation.

    Note: Do not use scene actions to pass data between views in the starting and ending scenes. For more information, see Define transition lifecycle callbacks.

    Apply a transition

    ( Transition은 activity간의 transition에도 사용된다  )

    The transition framework represents the style of animation between scenes with a object. You can instantiate a Transition using several built-in subclasses, such as AutoTransition and Fade, or define your own transition. Then, you can run the animation between scenes by passing your end Scene and the Transition to TransitionManager.go().

    ( Transition을 extend한 animation 역할을 하는 transition 으로는 Fade, AutoTransition, ChangeBounds 있다 )

    The transition lifecycle is similar to the activity lifecycle, and it represents the transition states that the framework monitors between the start and the completion of an animation. 

    Create a transition instance from a resource file

    This technique enables you to modify your transition definition without having to change the code of your activity. This technique is also useful to separate complex transition definitions from your application code, as shown in Specify multiple transitions.

    To specify a built-in transition in a resource file, follow these steps:

    1. Add the res/transition/ directory to your project.
    2. Create a new XML resource file inside this directory.
    3. Add an XML node for one of the built-in transitions.

    For example, the following resource file specifies the Fade transition:

    res/transition/fade_transition.xml

    <fade xmlns:android="http://schemas.android.com/apk/res/android" />

    The following code snippet shows how to inflate a Transition instance inside your activity from a resource file:

    Transition mFadeTransition = 
           TransitionInflater.from(this).
           inflateTransition(R.transition.fade_transition);

    Create a transition instance in your code

    This technique is useful for creating transition objects dynamically if you modify the user interface in your code, and to create simple built-in transition instances with few or no parameters.

    To create an instance of a built-in transition, invoke one of the public constructors in the subclasses of the Transition class. For example, the following code snippet creates an instance of the Fade transition:

    Transition mFadeTransition = new Fade();

    Apply a transition

    TransitionManager.go(mEndingScene, mFadeTransition);

    The starting scene is the ending scene from the last transition. If there was no previous transition, the starting scene is determined automatically from the current state of the user interface.

    If you do not specify a transition instance, the transition manager can apply an automatic transition .

    Choose specific target views

    The framework enables you to select specific views you want to animate.

    Each view that the transition animates is called a target. You can only select targets that are part of the view hierarchy associated with a scene.

    To remove one or more views from the list of targets, call the removeTarget() method before starting the transition. To add only the views you specify to the list of targets, call the addTarget()function.

    Specify multiple transitions

    You do not have to choose only one animation, since the transitions framework enables you to combine animation effects in a transition set that contains a group of individual built-in or custom transitions.

    To define a transition set from a collection of transitions in XML, create a resource file in the res/transitions/ directory and list the transitions under the transitionSet element.

    <transitionSet xmlns:android="http://schemas.android.com/apk/res/android" 
        android:transitionOrdering="sequential">
        <fade android:fadingMode="fade_out" />
        <changeBounds />
        <fade android:fadingMode="fade_in" />
    </transitionSet>

    To inflate the transition set into a TransitionSet object in your code, call the TransitionInflater.from() function in your activity. The TransitionSet class extends from theTransition class, so you can use it with a transition manager just like any other Transition instance.

    Apply a transition without scenes

    처음과 마지막 큰차이가 없는 경우 굳이 scenes를 만들필요없이 간단히 animaation을 만들수 있다. ViewGroup.removeView() function, and add the search results by calling ViewGroup.addView() function.

    참고) https://youtu.be/K3yMV5am-Xo?t=630

    예시코드) 

    res/layout/activity_main.xml

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
       android:id="@+id/mainLayout"
       android:layout_width="match_parent"
       android:layout_height="match_parent" >
       <EditText
           android:id="@+id/inputText"
           android:layout_alignParentLeft="true"
           android:layout_alignParentTop="true"
           android:layout_width="match_parent"
           android:layout_height="wrap_content" />
       ...
    </RelativeLayout>

    MainActivity

    private TextView mLabelText; 
    private Fade mFade;
    private ViewGroup mRootView;
    ...

    // Load the layout
    setContentView(R.layout.activity_main);
    ...

    // Create a new TextView and set some View properties
    mLabelText = new TextView(this);
    mLabelText.setText("Label");
    mLabelText.setId(R.id.text);

    // Get the root view and create a transition
    mRootView = (ViewGroup) findViewById(R.id.mainLayout);
    mFade = new Fade(Fade.IN);

    // Start recording changes to the view hierarchy
    TransitionManager.beginDelayedTransition(mRootView, mFade);

    // Add the new TextView to the view hierarchy
    mRootView.addView(mLabelText);

    // When the system redraws the screen to show this update,
    // the framework will animate the addition as a fade in

    Define transition lifecycle callbacks

     the TransitionListener 를 이용한다.

    Transition lifecycle callbacks are useful, for example, for copying a view property value from the starting view hierarchy to the ending view hierarchy during a scene change. You cannot simply copy the value from its starting view to the view in the ending view hierarchy, because the ending view hierarchy is not inflated until the transition is completed. Instead, you need to store the value in a variable and then copy it into the ending view hierarchy when the framework has finished the transition. To get notified when the transition is completed, you can implement the TransitionListener.onTransitionEnd() function in your activity.

    https://developer.android.com/training/transitions/custom-transitions

    Create a custom transition animation 

    ( customized된 transition은 layout 변화에도 사용되고 activity transition에도 사용된다 )

    Extend the Transition class

    public class CustomTransition extends Transition { 

       @Override
       public void captureStartValues(TransitionValues values) {}

       @Override
       public void captureEndValues(TransitionValues values) {}

       @Override
       public Animator createAnimator(ViewGroup sceneRoot,
                                      TransitionValues startValues,
                                      TransitionValues endValues) {}
    }

    Capture view property values

    Transition animations use the property animation system.

    Capture starting values

    To pass the starting view values to the framework, implement the captureStartValues(transitionValues) function. The framework calls this function for every view in the starting scene. The function argument is a TransitionValues object that contains a reference to the view and a Map instance in which you can store the view values you want. In your implementation, retrieve these property values and pass them back to the framework by storing them in the map.

    To ensure that the key for a property value does not conflict with other TransitionValues keys, use the following naming scheme:

    package_name:transition_name:property_name

    public class CustomTransition extends Transition { 

       // Define a key for storing a property value in
       // TransitionValues.values with the syntax
       // package_name:transition_class:property_name to avoid collisions
       private static final String PROPNAME_BACKGROUND =
               "com.example.android.customtransition:CustomTransition:background";

       @Override
       public void captureStartValues(TransitionValues transitionValues) {
           // Call the convenience method captureValues
           captureValues(transitionValues);
       }


       // For the view in transitionValues.view, get the values you
       // want and put them in transitionValues.values
       private void captureValues(TransitionValues transitionValues) {
           // Get a reference to the view
           View view = transitionValues.view;
           // Store its background property in the values map
           transitionValues.values.put(PROPNAME_BACKGROUND, view.getBackground());
       }
       ...
    }

    Capture ending values

    The framework calls the captureEndValues(TransitionValues) function once for every target view in the ending scene. In all other respects, captureEndValues() works the same as captureStartValues().

    @Override 
    public void captureEndValues(TransitionValues transitionValues) {
       captureValues(transitionValues);
    }

    In this example, both the captureStartValues() and captureEndValues() functions invoke captureValues() to retrieve and store values. The view property that captureValues() retrieves is the same, but it has different values in the starting and ending scenes. The framework maintains separate maps for the starting and ending states of a view.

    Create a custom animator

    To animate the changes to a view between its state in the starting scene and its state in the ending scene, you provide an animator by overriding the createAnimator() function. When the framework calls this function, it passes in the scene root view and the TransitionValues objects that contain the starting and ending values you captured.

    The number of times the framework calls the createAnimator() function depends on the changes that occur between the starting and ending scenes. For example, consider a fade out/fade in animation implemented as a custom transition. If the starting scene has five targets of which two are removed from the ending scene, and the ending scene has the three targets from the starting scene plus a new target, then the framework calls createAnimator() six times: three of the calls animate the fading out and fading in of the targets that stay in both scene objects; two more calls animate the fading out of the targets removed from the ending scene; and one call animates the fading in of the new target in the ending scene.

    For target views that exist on both the starting and ending scenes, the framework provides a TransitionValues object for both the startValues and endValues arguments. For target views that only exist in the starting or the ending scene, the framework provides a TransitionValues object for the corresponding argument and null for the other.

    To implement the createAnimator(ViewGroup, TransitionValues, TransitionValues)function when you create a custom transition, use the view property values you captured to create an Animator object and return it to the framework. For an example implementation, see the ChangeColor class in the CustomTransition sample. For more information about property animators, see Property animation.

    Apply a custom transition

    Custom transitions work the same as built-in transitions. You can apply a custom transition using a transition manager, as described in Apply a transition.

    https://developer.android.com/training/transitions/start-activity

    Start an activity using an animation

    ( activity간의 transition이나 layout 변경에 따른 transition이나 다 같은 Transition class를 기본으로 사용한다. customizing하려는 경우 조금 위에 있는 https://developer.android.com/training/transitions/custom-transitions
    Create a custom transition animation 를 이용한다 )

    기본 3가지 종류

    • An enter transition determines how views in an activity enter the scene. 
    • An exit transition determines how views in an activity exit the scene. 
    • A shared elements transition determines how views that are shared between two activities transition between these activities.

    기본적으로 제공되는 enter and exit transitions:

    • explode – Moves views in or out from the center of the scene.
    • slide 
    • fade

    the default cross-fading transition is activated between the entering and exiting activities.

    Any transition that extends the Visibility class is supported as an enter or exit transition. 

    기본적으로 제공되는 shared elements transitions:

    • changeBounds – Animates the changes in layout bounds of target views.
    • changeClipBounds – Animates the changes in clip bounds of target views.
    • changeTransform – Animates the changes in scale and rotation of target views.
    • changeImageTransform – Animates changes in size and scale of target images.

    Check the system version

    Activity transition APIs are available on Android 5.0 (API 21) and up. 

    // Check if we're running on Android 5.0 or higher 
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
       // Apply activity transition
    } else {
       // Swap without transition
    }

    activity 간 transition을 사용하려는 작업

    1. style xml 화일을 이용 activity 간 transition을 구현하는 방법 ( app의 style로서 적용하는 방법 )

    First, enable window content transitions with the android:windowActivityTransitions attribute when you define a style that inherits from the material theme. You can also specify enter, exit, and shared element transitions in your style definition:

    <style name="BaseAppTheme" parent="android:Theme.Material"> 
     <!-- enable window content transitions -->
     <item name="android:windowActivityTransitions">true</item>

     <!-- specify enter and exit transitions -->
     <item name="android:windowEnterTransition">@transition/explode</item>
     <item name="android:windowExitTransition">@transition/explode</item>

     <!-- specify shared element transitions -->
     <item name="android:windowSharedElementEnterTransition">
       @transition/change_image_transform</item>
     <item name="android:windowSharedElementExitTransition">
       @transition/change_image_transform</item>
    </style>

    The change_image_transform transition in this example is defined as follows ( 다양한 transition을 같이 적용가능하다. https://developer.android.com/training/transitions/Animate layout changes using a transition 참고 가능  )

    <!-- res/transition/change_image_transform.xml --> 
    <!-- (see also Shared Transitions below) -->
    <transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
     <changeImageTransform/>
    </transitionSet>

    The changeImageTransform element corresponds to the ChangeImageTransform class. For more information, see the API reference for Transition.

    2. code에서 activity 간 transition을 구현하는 방법

    To enable window content transitions in your code instead, call the Window.requestFeature()function:

    // inside your activity (if you did not enable transitions in your theme) 
    getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);

    // set an exit transition
    getWindow().setExitTransition(new Explode());

    To specify transitions in your code, call these functions with a Transition object:

    • Window.setEnterTransition()
    • Window.setExitTransition()
    • Window.setSharedElementEnterTransition()
    • Window.setSharedElementExitTransition()

    The setExitTransition() and setSharedElementExitTransition() functions define the exit transition for the calling activity. The setEnterTransition() and setSharedElementEnterTransition() functions define the enter transition for the called activity.

    To start an enter transition as soon as possible, use the Window.setAllowEnterTransitionOverlap() function on the called activity. This lets you have more dramatic enter transitions.

    Start an activity using transitions

    startActivity(intent, 
                 ActivityOptions.makeSceneTransitionAnimation(this).toBundle());

    If you have set an enter transition for the second activity, the transition is also activated when the activity starts. To disable transitions when you start another activity, provide a null options bundle

    참고 ) https://youtu.be/BF4yvhpMPcg?t=760

    Start an activity with a shared element

    To make a screen transition animation between two activities that have a shared element:

    1. Enable window content transitions in your theme.
    2. Specify a shared elements transition in your style.
    3. Define your transition as an XML resource.
    4. Assign a common name to the shared elements in both layouts with theandroid:transitionName attribute.
    5. Use the ActivityOptions.makeSceneTransitionAnimation() function.
    // get the element that receives the click event 
    final View imgContainerView = findViewById(R.id.img_container);

    // get the common element for the transition in this activity
    final View androidRobotView = findViewById(R.id.image_small);

    // define a click listener
    imgContainerView.setOnClickListener(new View.OnClickListener() {
       @Override
       public void onClick(View view) {
           Intent intent = new Intent(this, Activity2.class);
           // create the transition animation - the images in the layouts
           // of both activities are defined with android:transitionName="robot"
           ActivityOptions options = ActivityOptions
               .makeSceneTransitionAnimation(this, androidRobotView, "robot");
           // start the new activity
           startActivity(intent, options.toBundle());
       }
    });

    For shared dynamic views that you generate in your code, use the View.setTransitionName()function to specify a common element name in both activities.

    To reverse the scene transition animation when you finish the second activity, call theActivity.finishAfterTransition() function instead of Activity.finish().

    Start an activity with multiple shared elements

    To make a scene transition animation between two activities that have more than one shared element, define the shared elements in both layouts with the android:transitionName attribute (or use the View.setTransitionName() function in both activities), and create an ActivityOptions object as follows:

    ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(this, 
           Pair.create(view1, "agreedName1"),
           Pair.create(view2, "agreedName2"));

    https://developer.android.com/training/animation/overview

    Animate bitmaps

    When you want to animate a bitmap graphic such as an icon or illustration, you should use the drawable animation APIs. Usually, these animations are defined statically with a drawable resource, but you can also define the animation behavior at runtime.

    Animate UI visibility and motion

    When you need to change the visibility or position of views in your layout, you should include subtle animations to help the user understand how the UI is changing.

    To move, reveal, or hide views within the current layout, you can use the property animation system provided by the android.animation package,

    To create these animations with the least amount of effort, you can enable animations on your layout so that when you simply change the visibility of a view, an animation applies automatically.

    Physics-based motion

    Two common physics-based animations are the following:

    • Spring Animation
    • Fling Animation

    Animations not based on physics—such as those built with ObjectAnimator APIs—are fairly static and have a fixed duration. If the target value changes, you need to cancel the animation at the time of target value change, re-configure the animation with a new value as the new start value, and add the new target value. Visually, this process creates an abrupt stop in the animation, and a disjointed movement afterwards, as shown in figure 3.

    Whereas, animations built by with physics-based animation APIs such as DynamicAnimation are driven by force. The change in the target value results in a change in force. The new force applies on the existing velocity, which makes a continuous transition to the new target. This process results in a more natural-looking animation, as shown in figure 4.

    Animate layout changes

    On Android 4.4 (API level 19) and higher, you can use the transition framework to create animations when you swap the layout within the current activity or fragment. All you need to do is specify the starting and ending layout, and what type of animation you want to use. Then the system figures out and executes an animation between the two layouts. You can use this to swap out the entire UI or to move/replace just some views.

    The starting and ending layout are each stored in a Scene, though the starting scene is usually determined automatically from the current layout. You then create a Transition to tell the system what type of animation you want, and then call TransitionManager.go() and the system runs the animation to swap the layouts.

    Animate between activities

    On Android 5.0 (API level 21) and higher, you can also create animations that transition between your activities. This is based on the same transition framework described above to animate layout changes, but it allows you to create animations between layouts in separate activities.

    You can apply simple animations such as sliding the new activity in from the side or fading it in, but you can also create animations that transition between shared views in each activity.

    As usual, you call startActivity(), but pass it a bundle of options provided by ActivityOptions.makeSceneTransitionAnimation(). This bundle of options may include which views are shared between the activities so the transition framework can connect them during the animation.

    https://developer.android.com/guide/topics/graphics/prop-animation

    Property Animation Overview

    You can define an animation to change any object property over time, regardless of whether it draws to the screen or not. A property animation changes a property’s (a field in an object) value over a specified length of time.

    The property animation system lets you define the following characteristics of an animation:

    • Duration: The default length is 300 ms.
    • Time interpolation
    • Repeat count and behavior: You can specify whether or not to have an animation repeat and how many times to repeat the animation. You can also specify whether you want the animation to play back in reverse. Setting it to reverse plays the animation forwards then backwards repeatedly, until the number of repeats is reached.
    • Animator sets: You can group animations into logical sets that play together or sequentially or after specified delays.
    • Frame refresh delay: You can specify how often to refresh frames of your animation.

    Property Animation Overview

    The property animation system is a robust framework that allows you to animate almost anything. You can define an animation to change any object property over time, regardless of whether it draws to the screen or not. A property animation changes a property’s (a field in an object) value over a specified length of time. To animate something, you specify the object property that you want to animate, such as an object’s position on the screen, how long you want to animate it for, and what values you want to animate between.

    The property animation system lets you define the following characteristics of an animation:

    • Duration: You can specify the duration of an animation. The default length is 300 ms.
    • Time interpolation: You can specify how the values for the property are calculated as a function of the animation’s current elapsed time.
    • Repeat count and behavior: You can specify whether or not to have an animation repeat when it reaches the end of a duration and how many times to repeat the animation. You can also specify whether you want the animation to play back in reverse. Setting it to reverse plays the animation forwards then backwards repeatedly, until the number of repeats is reached.
    • Animator sets: You can group animations into logical sets that play together or sequentially or after specified delays.
    • Frame refresh delay: You can specify how often to refresh frames of your animation. The default is set to refresh every 10 ms, but the speed in which your application can refresh frames is ultimately dependent on how busy the system is overall and how fast the system can service the underlying timer.

    To see a full example of property animation, see the ChangeColor class in the android-CustomTransition sample on GitHub.

    How property animation differs from view animation

    The view animation system provides the capability to only animate View objects, so if you wanted to animate non-View objects, you have to implement your own code to do so. The view animation system is also constrained in the fact that it only exposes a few aspects of a View object to animate, such as the scaling and rotation of a View but not the background color, for instance.

    Another disadvantage of the view animation system is that it only modified where the View was drawn, and not the actual View itself. For instance, if you animated a button to move across the screen, the button draws correctly, but the actual location where you can click the button does not change, so you have to implement your own logic to handle this.

    • Depending on what property or object you are animating, you might need to call the invalidate() method on a View to force the screen to redraw itself with the updated animated values. You do this in the onAnimationUpdate() callback. For example, animating the color property of a Drawable object only causes updates to the screen when that object redraws itself. All of the property setters on View, such as setAlpha() and setTranslationX() invalidate the View properly, so you do not need to invalidate the View when calling these methods with new values. For more information on listeners, see the section about Animation listeners.

    Choreograph multiple animations using an AnimatorSet

    The Android system lets you bundle animations together into an AnimatorSet, so that you can specify whether to start animations simultaneously, sequentially, or after a specified delay. You can also nest AnimatorSet objects within each other.

    Animation listeners

    You can listen for important events during an animation

    • Animator.AnimatorListener
    • ValueAnimator.AnimatorUpdateListener
    • onAnimationStart() – Called when the animation starts.
    • onAnimationEnd() – Called when the animation ends.
    • onAnimationRepeat() – Called when the animation repeats itself.
    • onAnimationCancel() – Called when the animation is canceled. A cancelled animation also calls onAnimationEnd(), regardless of how they were ended.
    • onAnimationUpdate() – called on every frame of the animation. Depending on what property or object you are animating, you might need to call invalidate() on a View to force that area of the screen to redraw itself with the new animated values. setAlpha() and setTranslationX() need invalidate() 

    You can extend the AnimatorListenerAdapter class instead of implementing the Animator.AnimatorListener interface.

    Animate layout changes to ViewGroup objects

    실제작동) https://youtu.be/55wLsaWpQ4g

    customizing 하려면 아래 내용 참조

    You can animate layout changes within a ViewGroup with the LayoutTransition class. Views inside a ViewGroup can go through an appearing and disappearing animation when you add them to or remove them from a ViewGroup or when you call a View’s setVisibility() method with VISIBLE, INVISIBLE, or GONE. The remaining Views in the ViewGroup can also animate into their new positions when you add or remove Views. You can define the following animations in a LayoutTransition object by calling setAnimator() and passing in an Animator object with one of the following LayoutTransition constants:

    • APPEARING – A flag indicating the animation that runs on items that are appearing in the container.
    • CHANGE_APPEARING – A flag indicating the animation that runs on items that are changing due to a new item appearing in the container.
    • DISAPPEARING – A flag indicating the animation that runs on items that are disappearing from the container.
    • CHANGE_DISAPPEARING – A flag indicating the animation that runs on items that are changing due to an item disappearing from the container.

    You can define your own custom animations for these four types of events to customize the look of your layout transitions or just tell the animation system to use the default animations.

    간단한 사용방법

    <LinearLayout 
       android:orientation="vertical"
       android:layout_width="wrap_content"
       android:layout_height="match_parent"
       android:id="@+id/verticalContainer"
       android:animateLayoutChanges="true" />

    Setting this attribute to true automatically animates Views that are added or removed from the ViewGroup as well as the remaining Views in the ViewGroup.

    Animate view state changes using StateListAnimator

    view의 상태 변화에 따른 animation. 이를 구현하는 방법으로는 두가지가 있다. 

    1. property animation – StateListAnimator class 이용하는 방법
    2. drawable animation 

    property animation – StateListAnimator class 이용하는 방법

    The StateListAnimator class lets you define animators that run when the state of a view changes. This object behaves as a wrapper for an Animator object, calling that animation whenever the specified view state (such as “pressed” or “focused”) changes.

    The StateListAnimator can be defined in an XML resource with a root <selector> element and child <item> elements that each specify a different view state defined by the StateListAnimator class. Each <item> contains the definition for a property animation set ( 여러개의 animation 모음 ).

    res/xml/animate_scale.xml

    <?xml version="1.0" encoding="utf-8"?> 
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
       <!-- the pressed state; increase x and y size to 150% -->
       <item android:state_pressed="true">
           <set>
               <objectAnimator android:propertyName="scaleX"
                   android:duration="@android:integer/config_shortAnimTime"
                   android:valueTo="1.5"
                   android:valueType="floatType"/>
               <objectAnimator android:propertyName="scaleY"
                   android:duration="@android:integer/config_shortAnimTime"
                   android:valueTo="1.5"
                   android:valueType="floatType"/>
           </set>
       </item>
       <!-- the default, non-pressed state; set x and y size to 100% -->
       <item android:state_pressed="false">
           <set>
               <objectAnimator android:propertyName="scaleX"
                   android:duration="@android:integer/config_shortAnimTime"
                   android:valueTo="1"
                   android:valueType="floatType"/>
               <objectAnimator android:propertyName="scaleY"
                   android:duration="@android:integer/config_shortAnimTime"
                   android:valueTo="1"
                   android:valueType="floatType"/>
           </set>
       </item>
    </selector>

    위의 state list animator를 view에 덧붙이는 방법은 두가지 

    1. xml 방법
    2. code 방법

    xml 방법

    <Button android:stateListAnimator="@xml/animate_scale" 
           ... />

    code 방법

    AnimatorInflater.loadStateListAnimator() method, and assign the animator to your view with the View.setStateListAnimator() method.

    drawable animation ( 뉴스완장 작업시 내가 사용한 적이 있음 )

    <!-- res/drawable/myanimstatedrawable.xml --> 
    <animated-selector
       xmlns:android="http://schemas.android.com/apk/res/android">

       <!-- provide a different drawable for each state-->
       <item android:id="@+id/pressed" android:drawable="@drawable/drawableP"
           android:state_pressed="true"/>
       <item android:id="@+id/focused" android:drawable="@drawable/drawableF"
           android:state_focused="true"/>
       <item android:id="@id/default"
           android:drawable="@drawable/drawableD"/>

       <!-- specify a transition -->
       <transition android:fromId="@+id/default" android:toId="@+id/pressed">
           <animation-list>
               <item android:duration="15" android:drawable="@drawable/dt1"/>
               <item android:duration="15" android:drawable="@drawable/dt2"/>
               ...
           </animation-list>
       </transition>
       ...
    </animated-selector>

    Use a TypeEvaluator

    animation 진행되면서 변화하는 property value를 만들어주는 class. 

    Android system are int, float, or a color, which are supported by the IntEvaluator, FloatEvaluator, and ArgbEvaluator type evaluators.

    Use Interpolators

    The Android system provides a set of common interpolators in the android.view.animation package

    Specify keyframes

    A Keyframe object consists of a time/value pair that lets you define a specific state at a specific time of an animation. 

    Keyframe.ofFloat( 시간, 밸류 )

    Keyframe kf0 = Keyframe.ofFloat(0f, 0f); 
    Keyframe kf1 = Keyframe.ofFloat(.5f, 360f);
    Keyframe kf2 = Keyframe.ofFloat(1f, 0f);
    PropertyValuesHolder pvhRotation = PropertyValuesHolder.ofKeyframe("rotation", kf0, kf1, kf2);
    ObjectAnimator rotationAnim = ObjectAnimator.ofPropertyValuesHolder(target, pvhRotation);
    rotationAnim.setDuration(5000);

    drawable image를 이용한 keyframe animation – 영화필름작업과 유사 ( 위의 keyframe과는 전혀 무관함 헷갈리지 않기를 ) https://youtu.be/V3ksidLf7vA

    Animate views

    view animation은 겉모양만 변경시킨다.

    The property animation system can animate Views on the screen by changing the actual properties in the View objects. In addition, Views also automatically call the invalidate() method to refresh the screen

    property 종류

    • translationX and translationY
    • rotation, rotationX, and rotationY
    • scaleX and scaleY
    • pivotX and pivotY
    • x and y: These are simple utility properties to describe the final location of the View in its container, as a sum of the left and top values and translationX and translationY values.
    • alpha

    사용 예시

    ObjectAnimator.ofFloat(myView, "rotation", 0f, 360f);

    Animate using ViewPropertyAnimator

    The ViewPropertyAnimator provides a simple way to animate several properties of a View in parallel. 

    아래 세 코드들은 다 같은 결과를 가져온다. 각기 다른 방법으로 구현 가능

    ViewPropertyAnimator

    myView.animate().x(50f).y(100f);

    Multiple ObjectAnimator objects와 AnimatorSet 를 이용한 방법

    ObjectAnimator animX = ObjectAnimator.ofFloat(myView, "x", 50f); 
    ObjectAnimator animY = ObjectAnimator.ofFloat(myView, "y", 100f);
    AnimatorSet animSetXY = new AnimatorSet();
    animSetXY.playTogether(animX, animY);
    animSetXY.start();

    one ObjectAnimator를 이용한 방법

    PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("x", 50f); 
    PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("y", 100f);
    ObjectAnimator.ofPropertyValuesHolder(myView, pvhX, pvhY).start();

    Declare animations in XML

    xml을 이용 animation을 구현하는 방법

    • ValueAnimator<animator>
    • ObjectAnimator<objectAnimator>
    • AnimatorSet<set>
    <set android:ordering="sequentially"> 
       <set>
           <objectAnimator
               android:propertyName="x"
               android:duration="500"
               android:valueTo="400"
               android:valueType="intType"/>
           <objectAnimator
               android:propertyName="y"
               android:duration="500"
               android:valueTo="300"
               android:valueType="intType"/>
       </set>
       <objectAnimator
           android:propertyName="alpha"
           android:duration="500"
           android:valueTo="1f"/>
    </set>

    위와 같이 xml화일을 만들고 아래 코드를 activity, fragment에 넣어줘야 한다.

    AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(myContext, 
       R.animator.property_animator);
    set.setTarget(myObject);
    set.start();

    ValueAnimator를 이용한 예시도 docs에 있다.   https://developer.android.com/guide/topics/graphics/prop-animation

    Animate drawable graphics

    The first option is to use an Animation Drawable. This allows you to specify several static drawable files that will be displayed one at a time to create an animation. The second option is to use an Animated Vector Drawable, which lets you animate the properties of a vector drawable.

    Use AnimationDrawable

    The AnimationDrawable class is the basis for Drawable animations.

    While you can define the frames of an animation in your code, using the AnimationDrawable class API, it’s more simply accomplished with a single XML file that lists the frames that compose the animation. The XML file for this kind of animation belongs in the res/drawable/ directory.

    <animation-list xmlns:android="http://schemas.android.com/apk/res/android" 
       android:oneshot="true">
       <item android:drawable="@drawable/rocket_thrust1" android:duration="200" />
       <item android:drawable="@drawable/rocket_thrust2" android:duration="200" />
       <item android:drawable="@drawable/rocket_thrust3" android:duration="200" />
    </animation-list>

    By setting the android:oneshot attribute of the list to true, it will cycle just once then stop and hold on the last frame. If it is set false then the animation will loop. 

    AnimationDrawable rocketAnimation; 

    public void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     setContentView(R.layout.main);

     ImageView rocketImage = (ImageView) findViewById(R.id.rocket_image);
     rocketImage.setBackgroundResource(R.drawable.rocket_thrust);
     rocketAnimation = (AnimationDrawable) rocketImage.getBackground();

     rocketImage.setOnClickListener(new View.OnClickListener() {
         @Override
         public void onClick(View view) {
           rocketAnimation.start();
         }
     });
    }

    start() method called on the AnimationDrawable cannot be called during the onCreate() method of your Activity, because the AnimationDrawable is not yet fully attached to the window. call it from the onStart() method in your Activity.

    Use AnimatedVectorDrawable

    svg image file을 shapeshifter를 이용해서 android에서 사용가능한 xml화일로 바꾸고 이를 ImageView에서 연다.

    위에서 언급한 과정을 보여주는 예시 동영상 https://youtu.be/TfiZmzqAMgA

    https://developer.android.com/training/animation/reveal-or-hide-view

    Reveal or hide a view using animation

    자주 사용하는 animation 3가지 설명

    Create a crossfade animation

    Create a card flip animation

    Create a circular reveal animation

         – 참고자료)  https://youtu.be/X5hQv2uadjk

    https://developer.android.com/training/animation/reposition-view

    Move a View with Animation

    Change the view position with ObjectAnimator

    The ObjectAnimator API provides an easy way to change the properties of a view with a specified duration.

    ObjectAnimator animation = ObjectAnimator.ofFloat(view, "translationX", 100f); 
    animation.setDuration(2000);
    animation.start();

    Add curved motion

    Use PathInterpolator

    The PathInterpolator class is a new interpolator introduced in Android 5.0 (API 21). view가 이동하는 궤적을 휘어지게 한다.

    // arcTo() and PathInterpolator only available on API 21+ 
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
     Path path = new Path();
     path.arcTo(0f, 0f, 1000f, 1000f, 270f, -180f, true);
     PathInterpolator pathInterpolator = new PathInterpolator(path);
    }

    You can also define a path interpolator as an XML resource:

    <pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android" 
       android:controlX1="0.4"
       android:controlY1="0"
       android:controlX2="1"
       android:controlY2="1"/>
    ObjectAnimator animation = ObjectAnimator.ofFloat(view, "translationX", 100f); 
    animation.setInterpolator(pathInterpolator);
    animation.start();

    Define your own path

    The ObjectAnimator class has new constructors that enable you to animate coordinates along a path using two or more properties at once along with a path.

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 
     Path path = new Path();
     path.arcTo(0f, 0f, 1000f, 1000f, 270f, -180f, true);
     ObjectAnimator animator = ObjectAnimator.ofFloat(view, View.X, View.Y, path);
     animator.setDuration(2000);
     animator.start();
    } else {
     // Create animator without using curved path
    }

    https://developer.android.com/guide/topics/graphics/fling-animation

    Move views using a fling animation

    image

    Add the support library

    dependencies { 
         implementation 'com.android.support:support-dynamic-animation:28.0.0'
     }
     

    Create a fling animation

    FlingAnimation fling = new FlingAnimation(view, DynamicAnimation.SCROLL_X);

    Set velocity

    You can use a fixed value as the starting velocity, or you can base it off of the velocity of a touch gesture. If you choose to provide a fixed value, you should define the value in dp per second, then convert it to pixels per second. Defining the value in dp per second allows the velocity to be independent of a device’s density and form factors.

    Note: Use the GestureDetector.OnGestureListener and the VelocityTracker classes to retrieve and compute the velocity of touch gestures, respectively. ( 사용자의 스와이프 속도에 따른 속도설정 )

    Set an animation value range

    setMinValue() and setMaxValue() methods

    Set friction

    setFriction() method lets you change the animation’s friction. 

    Sample code

    FlingAnimation fling = new FlingAnimation(view, DynamicAnimation.SCROLL_X); 
    fling.setStartVelocity(-velocityX)
           .setMinValue(0)
           .setMaxValue(maxScroll)
           .setFriction(1.1f)
           .start();

    Set the minimum visible change

    anim.setMinimumVisibleChange(DynamicAnimation.MIN_VISIBLE_CHANGE_SCALE);

    https://developer.android.com/guide/topics/graphics/spring-animation

    Animate movement using spring physics

    the SpringForce class lets you customize spring’s stiffness, its damping ratio, and its final position.

    간단한 사용방법

    • Add the support library You must add the support library to your project to use the spring animation classes.
    • Create a spring animation: create an instance of the SpringAnimation class and set the motion behavior parameters.
    • (Optional) Register listeners: Register listeners to watch for animation lifecycle changes and animation value updates.

    Note: Update listener should be registered only if you need per-frame update on the animation value changes. An update listener prevents the animation from potentially running on a separate thread

    • (Optional) Remove listeners
    • (Optional) Set a start value
    • (Optional) Set a value range: Set the animation value range to restrain values within the minimum and the maximum range.
    • (Optional) Set start velocity: Set the start velocity for the animation.
    • (Optional) Set spring properties: Set the damping ratio and the stiffness on the spring.
    • (Optional) Create a custom spring
    • Start animation: Start the spring animation.
    • (Optional) Cancel animation

    .

    Add the support library

    fling animation 에서도 같은 library를 이용한다. 

    (참고로 circular reveal animation는 Android 5.0 (API level 21) and higher 에 기본내장)

    (참고로 zoomin, crossfader, card filp은 원래 sdk에 내장되어있는 library이용)

    1. Open the build.gradle file for your app module.
    2. Add the support library to the dependencies section.
      dependencies { 
         implementation 'com.android.support:support-dynamic-animation:28.0.0'
     }

    Create a spring animation

    final View img = findViewById(R.id.imageView); 
    // Setting up a spring animation to animate the view’s translationY property with the final
    // spring position at 0.
    final SpringAnimation springAnim = new SpringAnimation(img, DynamicAnimation.TRANSLATION_Y, 0);

    The spring-based animation can animate views on the screen by changing the actual properties in the view objects. 아래 property 밸류가 스프링 운동으로 변하게 된다.

    • ALPHA
    • TRANSLATION_X, TRANSLATION_Y, and TRANSLATION_Z

             TRANSLATION_X describes the left coordinate.
             TRANSLATION_Y describes the top coordinate.
             TRANSLATION_Z describes the depth of the view relative to its elevation.

    • ROTATION, ROTATION_X, and ROTATION_Y: These properties control the rotation in 2D (rotation property) and 3D around the pivot point.
    • SCROLL_X and SCROLL_Y: These properties indicate the scroll offset of the source left and the top edge in pixels. It also indicates the position in terms how much the page is scrolled.
    • SCALE_X and SCALE_Y
    • X, Y, and Z: These are basic utility properties to describe the final location of the view in its container.

             X is a sum of the left value and TRANSLATION_X.
             Y is a sum of the top value and TRANSLATION_Y.
             Z is a sum of the elevation value and TRANSLATION_Z

    Register listeners

    DynamicAnimation class ( sprint animation 포함 ) provides two listeners: OnAnimationUpdateListener and OnAnimationEndListener.

    OnAnimationUpdateListener

    When you want to animate multiple views to create a chained animation, you can set up OnAnimationUpdateListener to receive a callback every time there is a change in the current view’s property. The callback notifies the other view to update its spring position based on the change incurred in the current view’s property.

    // Creating two views to demonstrate the registration of the update listener. 
    final View view1 = findViewById(R.id.view1);
    final View view2 = findViewById(R.id.view2);

    // Setting up a spring animation to animate the view1 and view2 translationX and translationY properties
    final SpringAnimation anim1X = new SpringAnimation(view1,
           DynamicAnimation.TRANSLATION_X);
    final SpringAnimation anim1Y = new SpringAnimation(view1,
       DynamicAnimation.TRANSLATION_Y);
    final SpringAnimation anim2X = new SpringAnimation(view2,
           DynamicAnimation.TRANSLATION_X);
    final SpringAnimation anim2Y = new SpringAnimation(view2,
           DynamicAnimation.TRANSLATION_Y);

    // Registering the update listener
    anim1X.addUpdateListener(new DynamicAnimation.OnAnimationUpdateListener() {

    // Overriding the method to notify view2 about the change in the view1’s property.
       @Override
       public void onAnimationUpdate(DynamicAnimation dynamicAnimation, float value,
                                     float velocity) {
           anim2X.animateToFinalPosition(value);
       }
    });

    anim1Y.addUpdateListener(new DynamicAnimation.OnAnimationUpdateListener() {

     @Override
       public void onAnimationUpdate(DynamicAnimation dynamicAnimation, float value,
                                     float velocity) {
           anim2Y.animateToFinalPosition(value);
       }
    });

    OnAnimationEndListener

    1. Call the addEndListener() method and attach the listener to the animation.
    2. Override the onAnimationEnd() method to receive notification whenever an animation reaches equilibrium or is canceled.

    Remove listeners

    call removeUpdateListener() and removeEndListener() methods.

    Set animation start value

    call the setStartValue() method and pass the start value of the animation. If you do not set the start value, the animation uses the current value of the object’s property as the start value.

    Set animation value range

    when you want to restrain the property value to a certain range.

    • setMinValue()
    • setMaxValue()

    아래 작업들은 SpringForce obj에 각 특성들을 설정하는 작업

    Set start velocity ( fling animation과 같다. )

    Start velocity defines the speed at which the animation property changes at the beginning of the animation. The default start velocity is set to zero pixels per second. You can set a fixed value as the start velocity. If you choose to provide a fixed value, we recommend to define the value in dp per second and then convert it to pixels per second. Defining the value in dp per second allows velocity to be independent of density and form factors. For more information about converting value to pixels per second, refer to the Converting dp per second to pixels per second section.

    To set the velocity, call the setStartVelocity() method and pass the velocity in pixels per second. The method returns the spring force object on which the velocity is set.

    Note: Use the GestureDetector.OnGestureListener or the VelocityTracker class methods to retrieve and compute the velocity of touch gestures.

    final View img = findViewById(R.id.imageView); 
    final SpringAnimation anim = new SpringAnimation(img, DynamicAnimation.TRANSLATION_Y);

    // Compute velocity in the unit pixel/second
    vt.computeCurrentVelocity(1000);
    float velocity = vt.getYVelocity();
    anim.setStartVelocity(velocity);

    Converting dp per second to pixels per second

    float pixelPerSecond = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpPerSecond, getResources().getDisplayMetrics());

    Set spring properties

    The SpringForce class defines the getter and the setter methods for each of the spring properties, such as damping ratio and stiffness.

    setting method는 obj 자신을 return 하므로 chaining 이 가능하다. 

    Damping ratio

    1. getSpring() to retrieve the SpringForce obj.
    2. setDampingRatio()  damping ratio must be a non-negative number. If you set the damping ratio to zero, the spring will never reach the rest position. In other words, it oscillates forever.

    ratio constants are available in the system:

    • DAMPING_RATIO_HIGH_BOUNCY
    • DAMPING_RATIO_MEDIUM_BOUNCY
    • DAMPING_RATIO_LOW_BOUNCY
    • DAMPING_RATIO_NO_BOUNCY
    final View img = findViewById(R.id.imageView); 
    final SpringAnimation anim = new SpringAnimation(img, DynamicAnimation.TRANSLATION_Y);

    //Setting the damping ratio to create a low bouncing effect.
    anim.getSpring().setDampingRatio(SpringForce.DAMPING_RATIO_LOW_BOUNCY);

    Stiffness

    the strength of the spring. 

    1. getSpring() to retrieve SpringForce obj.
    2. setStiffness() Note: The stiffness must be a positive number.

    stiffness constants are available in the system:

    • STIFFNESS_HIGH
    • STIFFNESS_MEDIUM
    • STIFFNESS_LOW
    • STIFFNESS_VERY_LOW
    final View img = findViewById(R.id.imageView); 
    final SpringAnimation anim = new SpringAnimation(img, DynamicAnimation.TRANSLATION_Y);

    //Setting the spring with a low stiffness.
    anim.getSpring().setStiffness(SpringForce.STIFFNESS_LOW);

      Create a custom spring force

      1. Create a SpringForce object.
      2. Assign the properties by calling the respective methods. You can also create a method chain.
      3. Call the setSpring() method to set the spring to the animation.

      SpringForce force = new SpringForce();

      force.setDampingRatio(DAMPING_RATIO_LOW_BOUNCY).setStiffness(STIFFNESS_LOW);

      setSpring(force);

      Start animation

      There are two ways you can start a spring animation: By calling the start() or by calling the animateToFinalPosition() method. Both the methods need to be called on the main thread.

      animateToFinalPosition() method performs two tasks:

      • Sets the final position of the spring – setFinalPosition()
      • Starts the animation, if it has not started.
      final View img = findViewById(R.id.imageView); 
      final SpringAnimation anim = new SpringAnimation(img, DynamicAnimation.TRANSLATION_Y);

      //Starting the animation
      anim.start();

      Cancel animation

      사용자 갑자가 exit 하는 경우 cancel 처리한다.

      There are two methods. The cancel() method terminates the animation at the value where it is. The skipToEnd() method skips the animation to the final value and then terminates it.

      Before you can terminate the animation, it is important to first check the state of the spring. If the state is undamped, the animation can never reach the rest position. To check the state of the spring, call the canSkipToEnd() method. If the spring is damped, the method returns true, otherwise false.

      The cancel() method must be called only on the main thread.

      Note: the skipToEnd() method causes a visual jump.

      https://developer.android.com/training/animation/layout

      Auto animate layout updates

      <LinearLayout android:id="@+id/container" 
         android:animateLayoutChanges="true"
         ...
      />

      android:animateLayoutChanges attribute를 설정함으로써 layout안에 element가 만들어지고 사라질때 시스템이 제공하는 애니메이션을 적용할수 있다. 

      Tip: If you want to supply custom layout animations, create a LayoutTransition object and supply it to the layout with the setLayoutTransition() method.

      https://developer.android.com/training/transitions/

      Animate layout changes using a transition

      참고) https://code.tutsplus.com/tutorials/an-introduction-to-android-transitions–cms-21640

      https://www.youtube.com/watch?v=00uf3cwC0I0

      변화전 layout scene 변화후 layout scene을 정하면 자동으로 animation이 적용된다. 적용되는 animation 종류도 여러가지가 있다. 

      scene간의 layout transition animation을 사용할때의 장점

      • Group-level animations: Apply one or more animation effects to all of the views in a view hierarchy.
      • Built-in animations: Use predefined animations for common effects such as fade out or movement.
      • Resource file support: Load view hierarchies and built-in animations from layout resource files.
      • Lifecycle callbacks: Receive callbacks that provide control over the animation and hierarchy change process.

      Note: between layouts within the same activity. If the user is moving between activities then you should instead read Start an activity using an animation.

      The basic process to animate between two layouts is as follows:

      1. Create a Scene object for both the starting layout and the ending layout. However, the starting layout’s scene is often determined automatically from the current layout.
      2. Create a Transition object to define what type of animation you want.
      3. Call TransitionManager.go() and the system runs the animation to swap the layouts.

      Create a scene

      Scenes store the state of a view hierarchy, including all its views and their property values. The transitions framework can run animations between a starting and an ending scene.

      You can create your scenes from a layout resource file or from a group of views in your code. However, the starting scene for your transition is often determined automatically from the current UI.

      A scene can also define its own actions that run when you make a scene change.

      Note: The framework can animate changes in a single view hierarchy without using scenes, as described in Apply a transition without scenes. 

      Create a scene from a layout resource

      You can create a Scene instance directly from a layout resource file. Use this technique when the view hierarchy in the file is mostly static. The resulting scene represents the state of the view hierarchy at the time you created the Scene instance. If you change the view hierarchy, you have to recreate the scene. The framework creates the scene from the entire view hierarchy in the file; you can not create a scene from part of a layout file.

      To create a Scene instance from a layout resource file, retrieve the scene root ( 이란 scene을 포함하게 될 container layout 아래 예에서는 framelayout id scene_root 이 해당된다 ) from your layout as a ViewGroup instance and then call the Scene.getSceneForLayout() function with the scene root and the resource ID of the layout file that contains the view hierarchy for the scene.

      예시코드) 

      res/layout/activity_main.xml

      <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
         android:id="@+id/master_layout">
         <TextView
             android:id="@+id/title"
             ...
             android:text="Title"/>
         <FrameLayout
             android:id="@+id/scene_root">
             <include layout="@layout/a_scene" />
         </FrameLayout>
      </LinearLayout>

      scene은 xml화일 부분을 가지고 만들수 없으므로 예시에서는 scene에 해당하는 layout file을 따로 만들고 include를 이용 포함 시켰다. 

      res/layout/a_scene.xml

      <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
         android:id="@+id/scene_container"
         android:layout_width="match_parent"
         android:layout_height="match_parent" >
         <TextView
             android:id="@+id/text_view1
             android:text="Text Line 1" />
         <TextView
             android:id="@+id/text_view2
             android:text="Text Line 2" />
      </RelativeLayout>

      res/layout/another_scene.xml

      <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
         android:id="@+id/scene_container"
         android:layout_width="match_parent"
         android:layout_height="match_parent" >
         <TextView
             android:id="@+id/text_view2
             android:text="Text Line 2" />
         <TextView
             android:id="@+id/text_view1
             android:text="Text Line 1" />
      </RelativeLayout>

      scenes 이 될 두 xml화일들은 같은 elements를 가지고 있으며 위치만 다르다.( 꼭 이렇게 같은 element로 구성되어야 하는지는 확인이 필요하다. )

      Generate scenes from layouts

      Scene mAScene; 
      Scene mAnotherScene;

      // Create the scene root for the scenes in this app
      mSceneRoot = (ViewGroup) findViewById(R.id.scene_root);

      // Create the scenes
      mAScene = Scene.getSceneForLayout(mSceneRoot, R.layout.a_scene, this);
      mAnotherScene =
         Scene.getSceneForLayout(mSceneRoot, R.layout.another_scene, this);

      Create a scene in your code

      You can also create a Scene instance in your code from a ViewGroup object. Use this technique when you modify the view hierarchies directly in your code or when you generate them dynamically.

      Scene mScene; 

      // Obtain the scene root element
      mSceneRoot = (ViewGroup) mSomeLayoutElement;

      // Obtain the view hierarchy to add as a child of
      // the scene root when this scene is entered
      mViewHierarchy = (ViewGroup) someOtherLayoutElement;

      // Create a scene
      mScene = new Scene(mSceneRoot, mViewHierarchy);

      Create scene actions

      ( layout이 바뀌어 transition되는 과정에 추가 작업을 할수 있는 hook functions에 대한 설명 )

      The framework enables you to define custom scene actions that the system runs when entering or exiting a scene. In many cases, defining custom scene actions is not necessary, since the framework animates the change between scenes automatically.

      Scene actions are useful for handling these cases:

      • Animate views that are not in the same hierarchy. You can animate views for both the starting and ending scenes using exit and entry scene actions.
      • Animate views that the transitions framework cannot animate automatically, such as ListView objects. For more information, see Limitations.

      To provide custom scene actions, define your actions as Runnable objects and pass them to the Scene.setExitAction() or Scene.setEnterAction() functions. The framework calls the setExitAction() function on the starting scene before running the transition animation and the setEnterAction() function on the ending scene after running the transition animation.

      Note: Do not use scene actions to pass data between views in the starting and ending scenes. For more information, see Define transition lifecycle callbacks.

      Apply a transition

      ( Transition은 activity간의 transition에도 사용된다  )

      The transition framework represents the style of animation between scenes with a object. You can instantiate a Transition using several built-in subclasses, such as AutoTransition and Fade, or define your own transition. Then, you can run the animation between scenes by passing your end Scene and the Transition to TransitionManager.go().

      ( Transition을 extend한 animation 역할을 하는 transition 으로는 Fade, AutoTransition, ChangeBounds 있다 )

      The transition lifecycle is similar to the activity lifecycle, and it represents the transition states that the framework monitors between the start and the completion of an animation. 

      Create a transition instance from a resource file

      This technique enables you to modify your transition definition without having to change the code of your activity. This technique is also useful to separate complex transition definitions from your application code, as shown in Specify multiple transitions.

      To specify a built-in transition in a resource file, follow these steps:

      1. Add the res/transition/ directory to your project.
      2. Create a new XML resource file inside this directory.
      3. Add an XML node for one of the built-in transitions.

      For example, the following resource file specifies the Fade transition:

      res/transition/fade_transition.xml

      <fade xmlns:android="http://schemas.android.com/apk/res/android" />

      The following code snippet shows how to inflate a Transition instance inside your activity from a resource file:

      Transition mFadeTransition = 
             TransitionInflater.from(this).
             inflateTransition(R.transition.fade_transition);

      Create a transition instance in your code

      This technique is useful for creating transition objects dynamically if you modify the user interface in your code, and to create simple built-in transition instances with few or no parameters.

      To create an instance of a built-in transition, invoke one of the public constructors in the subclasses of the Transition class. For example, the following code snippet creates an instance of the Fade transition:

      Transition mFadeTransition = new Fade();

      Apply a transition

      TransitionManager.go(mEndingScene, mFadeTransition);

      The starting scene is the ending scene from the last transition. If there was no previous transition, the starting scene is determined automatically from the current state of the user interface.

      If you do not specify a transition instance, the transition manager can apply an automatic transition .

      Choose specific target views

      The framework enables you to select specific views you want to animate.

      Each view that the transition animates is called a target. You can only select targets that are part of the view hierarchy associated with a scene.

      To remove one or more views from the list of targets, call the removeTarget() method before starting the transition. To add only the views you specify to the list of targets, call the addTarget()function.

      Specify multiple transitions

      You do not have to choose only one animation, since the transitions framework enables you to combine animation effects in a transition set that contains a group of individual built-in or custom transitions.

      To define a transition set from a collection of transitions in XML, create a resource file in the res/transitions/ directory and list the transitions under the transitionSet element.

      <transitionSet xmlns:android="http://schemas.android.com/apk/res/android" 
          android:transitionOrdering="sequential">
          <fade android:fadingMode="fade_out" />
          <changeBounds />
          <fade android:fadingMode="fade_in" />
      </transitionSet>

      To inflate the transition set into a TransitionSet object in your code, call the TransitionInflater.from() function in your activity. The TransitionSet class extends from theTransition class, so you can use it with a transition manager just like any other Transition instance.

      Apply a transition without scenes

      처음과 마지막 큰차이가 없는 경우 굳이 scenes를 만들필요없이 간단히 animaation을 만들수 있다. ViewGroup.removeView() function, and add the search results by calling ViewGroup.addView() function.

      참고) https://youtu.be/K3yMV5am-Xo?t=630

      예시코드) 

      res/layout/activity_main.xml

      <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
         android:id="@+id/mainLayout"
         android:layout_width="match_parent"
         android:layout_height="match_parent" >
         <EditText
             android:id="@+id/inputText"
             android:layout_alignParentLeft="true"
             android:layout_alignParentTop="true"
             android:layout_width="match_parent"
             android:layout_height="wrap_content" />
         ...
      </RelativeLayout>

      MainActivity

      private TextView mLabelText; 
      private Fade mFade;
      private ViewGroup mRootView;
      ...

      // Load the layout
      setContentView(R.layout.activity_main);
      ...

      // Create a new TextView and set some View properties
      mLabelText = new TextView(this);
      mLabelText.setText("Label");
      mLabelText.setId(R.id.text);

      // Get the root view and create a transition
      mRootView = (ViewGroup) findViewById(R.id.mainLayout);
      mFade = new Fade(Fade.IN);

      // Start recording changes to the view hierarchy
      TransitionManager.beginDelayedTransition(mRootView, mFade);

      // Add the new TextView to the view hierarchy
      mRootView.addView(mLabelText);

      // When the system redraws the screen to show this update,
      // the framework will animate the addition as a fade in

      Define transition lifecycle callbacks

       the TransitionListener 를 이용한다.

      Transition lifecycle callbacks are useful, for example, for copying a view property value from the starting view hierarchy to the ending view hierarchy during a scene change. You cannot simply copy the value from its starting view to the view in the ending view hierarchy, because the ending view hierarchy is not inflated until the transition is completed. Instead, you need to store the value in a variable and then copy it into the ending view hierarchy when the framework has finished the transition. To get notified when the transition is completed, you can implement the TransitionListener.onTransitionEnd() function in your activity.

      https://developer.android.com/training/transitions/custom-transitions

      Create a custom transition animation 

      ( customized된 transition은 layout 변화에도 사용되고 activity transition에도 사용된다 )

      Extend the Transition class

      public class CustomTransition extends Transition { 

         @Override
         public void captureStartValues(TransitionValues values) {}

         @Override
         public void captureEndValues(TransitionValues values) {}

         @Override
         public Animator createAnimator(ViewGroup sceneRoot,
                                        TransitionValues startValues,
                                        TransitionValues endValues) {}
      }

      Capture view property values

      Transition animations use the property animation system.

      Capture starting values

      To pass the starting view values to the framework, implement the captureStartValues(transitionValues) function. The framework calls this function for every view in the starting scene. The function argument is a TransitionValues object that contains a reference to the view and a Map instance in which you can store the view values you want. In your implementation, retrieve these property values and pass them back to the framework by storing them in the map.

      To ensure that the key for a property value does not conflict with other TransitionValues keys, use the following naming scheme:

      package_name:transition_name:property_name

      public class CustomTransition extends Transition { 

         // Define a key for storing a property value in
         // TransitionValues.values with the syntax
         // package_name:transition_class:property_name to avoid collisions
         private static final String PROPNAME_BACKGROUND =
                 "com.example.android.customtransition:CustomTransition:background";

         @Override
         public void captureStartValues(TransitionValues transitionValues) {
             // Call the convenience method captureValues
             captureValues(transitionValues);
         }


         // For the view in transitionValues.view, get the values you
         // want and put them in transitionValues.values
         private void captureValues(TransitionValues transitionValues) {
             // Get a reference to the view
             View view = transitionValues.view;
             // Store its background property in the values map
             transitionValues.values.put(PROPNAME_BACKGROUND, view.getBackground());
         }
         ...
      }

      Capture ending values

      The framework calls the captureEndValues(TransitionValues) function once for every target view in the ending scene. In all other respects, captureEndValues() works the same as captureStartValues().

      @Override 
      public void captureEndValues(TransitionValues transitionValues) {
         captureValues(transitionValues);
      }

      In this example, both the captureStartValues() and captureEndValues() functions invoke captureValues() to retrieve and store values. The view property that captureValues() retrieves is the same, but it has different values in the starting and ending scenes. The framework maintains separate maps for the starting and ending states of a view.

      Create a custom animator

      To animate the changes to a view between its state in the starting scene and its state in the ending scene, you provide an animator by overriding the createAnimator() function. When the framework calls this function, it passes in the scene root view and the TransitionValues objects that contain the starting and ending values you captured.

      The number of times the framework calls the createAnimator() function depends on the changes that occur between the starting and ending scenes. For example, consider a fade out/fade in animation implemented as a custom transition. If the starting scene has five targets of which two are removed from the ending scene, and the ending scene has the three targets from the starting scene plus a new target, then the framework calls createAnimator() six times: three of the calls animate the fading out and fading in of the targets that stay in both scene objects; two more calls animate the fading out of the targets removed from the ending scene; and one call animates the fading in of the new target in the ending scene.

      For target views that exist on both the starting and ending scenes, the framework provides a TransitionValues object for both the startValues and endValues arguments. For target views that only exist in the starting or the ending scene, the framework provides a TransitionValues object for the corresponding argument and null for the other.

      To implement the createAnimator(ViewGroup, TransitionValues, TransitionValues)function when you create a custom transition, use the view property values you captured to create an Animator object and return it to the framework. For an example implementation, see the ChangeColor class in the CustomTransition sample. For more information about property animators, see Property animation.

      Apply a custom transition

      Custom transitions work the same as built-in transitions. You can apply a custom transition using a transition manager, as described in Apply a transition.

      https://developer.android.com/training/transitions/start-activity

      Start an activity using an animation

      ( activity간의 transition이나 layout 변경에 따른 transition이나 다 같은 Transition class를 기본으로 사용한다. customizing하려는 경우 조금 위에 있는 https://developer.android.com/training/transitions/custom-transitions
      Create a custom transition animation 를 이용한다 )

      기본 3가지 종류

      • An enter transition determines how views in an activity enter the scene. 
      • An exit transition determines how views in an activity exit the scene. 
      • A shared elements transition determines how views that are shared between two activities transition between these activities.

      기본적으로 제공되는 enter and exit transitions:

      • explode – Moves views in or out from the center of the scene.
      • slide 
      • fade

      the default cross-fading transition is activated between the entering and exiting activities.

      Any transition that extends the Visibility class is supported as an enter or exit transition. 

      기본적으로 제공되는 shared elements transitions:

      • changeBounds – Animates the changes in layout bounds of target views.
      • changeClipBounds – Animates the changes in clip bounds of target views.
      • changeTransform – Animates the changes in scale and rotation of target views.
      • changeImageTransform – Animates changes in size and scale of target images.

      Check the system version

      Activity transition APIs are available on Android 5.0 (API 21) and up. 

      // Check if we're running on Android 5.0 or higher 
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
         // Apply activity transition
      } else {
         // Swap without transition
      }

      activity 간 transition을 사용하려는 작업

      1. style xml 화일을 이용 activity 간 transition을 구현하는 방법 ( app의 style로서 적용하는 방법 )

      First, enable window content transitions with the android:windowActivityTransitions attribute when you define a style that inherits from the material theme. You can also specify enter, exit, and shared element transitions in your style definition:

      <style name="BaseAppTheme" parent="android:Theme.Material"> 
       <!-- enable window content transitions -->
       <item name="android:windowActivityTransitions">true</item>

       <!-- specify enter and exit transitions -->
       <item name="android:windowEnterTransition">@transition/explode</item>
       <item name="android:windowExitTransition">@transition/explode</item>

       <!-- specify shared element transitions -->
       <item name="android:windowSharedElementEnterTransition">
         @transition/change_image_transform</item>
       <item name="android:windowSharedElementExitTransition">
         @transition/change_image_transform</item>
      </style>

      The change_image_transform transition in this example is defined as follows ( 다양한 transition을 같이 적용가능하다. https://developer.android.com/training/transitions/Animate layout changes using a transition 참고 가능  )

      <!-- res/transition/change_image_transform.xml --> 
      <!-- (see also Shared Transitions below) -->
      <transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
       <changeImageTransform/>
      </transitionSet>

      The changeImageTransform element corresponds to the ChangeImageTransform class. For more information, see the API reference for Transition.

      2. code에서 activity 간 transition을 구현하는 방법

      To enable window content transitions in your code instead, call the Window.requestFeature()function:

      // inside your activity (if you did not enable transitions in your theme) 
      getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);

      // set an exit transition
      getWindow().setExitTransition(new Explode());

      To specify transitions in your code, call these functions with a Transition object:

      • Window.setEnterTransition()
      • Window.setExitTransition()
      • Window.setSharedElementEnterTransition()
      • Window.setSharedElementExitTransition()

      The setExitTransition() and setSharedElementExitTransition() functions define the exit transition for the calling activity. The setEnterTransition() and setSharedElementEnterTransition() functions define the enter transition for the called activity.

      To start an enter transition as soon as possible, use the Window.setAllowEnterTransitionOverlap() function on the called activity. This lets you have more dramatic enter transitions.

      Start an activity using transitions

      startActivity(intent, 
                   ActivityOptions.makeSceneTransitionAnimation(this).toBundle());

      If you have set an enter transition for the second activity, the transition is also activated when the activity starts. To disable transitions when you start another activity, provide a null options bundle

      참고 ) https://youtu.be/BF4yvhpMPcg?t=760

      Start an activity with a shared element

      To make a screen transition animation between two activities that have a shared element:

      1. Enable window content transitions in your theme.
      2. Specify a shared elements transition in your style.
      3. Define your transition as an XML resource.
      4. Assign a common name to the shared elements in both layouts with theandroid:transitionName attribute.
      5. Use the ActivityOptions.makeSceneTransitionAnimation() function.
      // get the element that receives the click event 
      final View imgContainerView = findViewById(R.id.img_container);

      // get the common element for the transition in this activity
      final View androidRobotView = findViewById(R.id.image_small);

      // define a click listener
      imgContainerView.setOnClickListener(new View.OnClickListener() {
         @Override
         public void onClick(View view) {
             Intent intent = new Intent(this, Activity2.class);
             // create the transition animation - the images in the layouts
             // of both activities are defined with android:transitionName="robot"
             ActivityOptions options = ActivityOptions
                 .makeSceneTransitionAnimation(this, androidRobotView, "robot");
             // start the new activity
             startActivity(intent, options.toBundle());
         }
      });

      For shared dynamic views that you generate in your code, use the View.setTransitionName()function to specify a common element name in both activities.

      To reverse the scene transition animation when you finish the second activity, call theActivity.finishAfterTransition() function instead of Activity.finish().

      Start an activity with multiple shared elements

      To make a scene transition animation between two activities that have more than one shared element, define the shared elements in both layouts with the android:transitionName attribute (or use the View.setTransitionName() function in both activities), and create an ActivityOptions object as follows:

      ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(this, 
             Pair.create(view1, "agreedName1"),
             Pair.create(view2, "agreedName2"));

      https://developer.android.com/training/animation/overview

      Animate bitmaps

      When you want to animate a bitmap graphic such as an icon or illustration, you should use the drawable animation APIs. Usually, these animations are defined statically with a drawable resource, but you can also define the animation behavior at runtime.

      Animate UI visibility and motion

      When you need to change the visibility or position of views in your layout, you should include subtle animations to help the user understand how the UI is changing.

      To move, reveal, or hide views within the current layout, you can use the property animation system provided by the android.animation package,

      To create these animations with the least amount of effort, you can enable animations on your layout so that when you simply change the visibility of a view, an animation applies automatically.

      Physics-based motion

      Two common physics-based animations are the following:

      • Spring Animation
      • Fling Animation

      Animations not based on physics—such as those built with ObjectAnimator APIs—are fairly static and have a fixed duration. If the target value changes, you need to cancel the animation at the time of target value change, re-configure the animation with a new value as the new start value, and add the new target value. Visually, this process creates an abrupt stop in the animation, and a disjointed movement afterwards, as shown in figure 3.

      Whereas, animations built by with physics-based animation APIs such as DynamicAnimation are driven by force. The change in the target value results in a change in force. The new force applies on the existing velocity, which makes a continuous transition to the new target. This process results in a more natural-looking animation, as shown in figure 4.

      Animate layout changes

      On Android 4.4 (API level 19) and higher, you can use the transition framework to create animations when you swap the layout within the current activity or fragment. All you need to do is specify the starting and ending layout, and what type of animation you want to use. Then the system figures out and executes an animation between the two layouts. You can use this to swap out the entire UI or to move/replace just some views.

      The starting and ending layout are each stored in a Scene, though the starting scene is usually determined automatically from the current layout. You then create a Transition to tell the system what type of animation you want, and then call TransitionManager.go() and the system runs the animation to swap the layouts.

      Animate between activities

      On Android 5.0 (API level 21) and higher, you can also create animations that transition between your activities. This is based on the same transition framework described above to animate layout changes, but it allows you to create animations between layouts in separate activities.

      You can apply simple animations such as sliding the new activity in from the side or fading it in, but you can also create animations that transition between shared views in each activity.

      As usual, you call startActivity(), but pass it a bundle of options provided by ActivityOptions.makeSceneTransitionAnimation(). This bundle of options may include which views are shared between the activities so the transition framework can connect them during the animation.

      https://developer.android.com/guide/topics/graphics/prop-animation

      Property Animation Overview

      You can define an animation to change any object property over time, regardless of whether it draws to the screen or not. A property animation changes a property’s (a field in an object) value over a specified length of time.

      The property animation system lets you define the following characteristics of an animation:

      • Duration: The default length is 300 ms.
      • Time interpolation
      • Repeat count and behavior: You can specify whether or not to have an animation repeat and how many times to repeat the animation. You can also specify whether you want the animation to play back in reverse. Setting it to reverse plays the animation forwards then backwards repeatedly, until the number of repeats is reached.
      • Animator sets: You can group animations into logical sets that play together or sequentially or after specified delays.
      • Frame refresh delay: You can specify how often to refresh frames of your animation.

      Property Animation Overview

      The property animation system is a robust framework that allows you to animate almost anything. You can define an animation to change any object property over time, regardless of whether it draws to the screen or not. A property animation changes a property’s (a field in an object) value over a specified length of time. To animate something, you specify the object property that you want to animate, such as an object’s position on the screen, how long you want to animate it for, and what values you want to animate between.

      The property animation system lets you define the following characteristics of an animation:

      • Duration: You can specify the duration of an animation. The default length is 300 ms.
      • Time interpolation: You can specify how the values for the property are calculated as a function of the animation’s current elapsed time.
      • Repeat count and behavior: You can specify whether or not to have an animation repeat when it reaches the end of a duration and how many times to repeat the animation. You can also specify whether you want the animation to play back in reverse. Setting it to reverse plays the animation forwards then backwards repeatedly, until the number of repeats is reached.
      • Animator sets: You can group animations into logical sets that play together or sequentially or after specified delays.
      • Frame refresh delay: You can specify how often to refresh frames of your animation. The default is set to refresh every 10 ms, but the speed in which your application can refresh frames is ultimately dependent on how busy the system is overall and how fast the system can service the underlying timer.

      To see a full example of property animation, see the ChangeColor class in the android-CustomTransition sample on GitHub.

      How property animation differs from view animation

      The view animation system provides the capability to only animate View objects, so if you wanted to animate non-View objects, you have to implement your own code to do so. The view animation system is also constrained in the fact that it only exposes a few aspects of a View object to animate, such as the scaling and rotation of a View but not the background color, for instance.

      Another disadvantage of the view animation system is that it only modified where the View was drawn, and not the actual View itself. For instance, if you animated a button to move across the screen, the button draws correctly, but the actual location where you can click the button does not change, so you have to implement your own logic to handle this.

      • Depending on what property or object you are animating, you might need to call the invalidate() method on a View to force the screen to redraw itself with the updated animated values. You do this in the onAnimationUpdate() callback. For example, animating the color property of a Drawable object only causes updates to the screen when that object redraws itself. All of the property setters on View, such as setAlpha() and setTranslationX() invalidate the View properly, so you do not need to invalidate the View when calling these methods with new values. For more information on listeners, see the section about Animation listeners.

      Choreograph multiple animations using an AnimatorSet

      The Android system lets you bundle animations together into an AnimatorSet, so that you can specify whether to start animations simultaneously, sequentially, or after a specified delay. You can also nest AnimatorSet objects within each other.

      Animation listeners

      You can listen for important events during an animation

      • Animator.AnimatorListener
      • ValueAnimator.AnimatorUpdateListener
      • onAnimationStart() – Called when the animation starts.
      • onAnimationEnd() – Called when the animation ends.
      • onAnimationRepeat() – Called when the animation repeats itself.
      • onAnimationCancel() – Called when the animation is canceled. A cancelled animation also calls onAnimationEnd(), regardless of how they were ended.
      • onAnimationUpdate() – called on every frame of the animation. Depending on what property or object you are animating, you might need to call invalidate() on a View to force that area of the screen to redraw itself with the new animated values. setAlpha() and setTranslationX() need invalidate() 

      You can extend the AnimatorListenerAdapter class instead of implementing the Animator.AnimatorListener interface.

      Animate layout changes to ViewGroup objects

      실제작동) https://youtu.be/55wLsaWpQ4g

      customizing 하려면 아래 내용 참조

      You can animate layout changes within a ViewGroup with the LayoutTransition class. Views inside a ViewGroup can go through an appearing and disappearing animation when you add them to or remove them from a ViewGroup or when you call a View’s setVisibility() method with VISIBLE, INVISIBLE, or GONE. The remaining Views in the ViewGroup can also animate into their new positions when you add or remove Views. You can define the following animations in a LayoutTransition object by calling setAnimator() and passing in an Animator object with one of the following LayoutTransition constants:

      • APPEARING – A flag indicating the animation that runs on items that are appearing in the container.
      • CHANGE_APPEARING – A flag indicating the animation that runs on items that are changing due to a new item appearing in the container.
      • DISAPPEARING – A flag indicating the animation that runs on items that are disappearing from the container.
      • CHANGE_DISAPPEARING – A flag indicating the animation that runs on items that are changing due to an item disappearing from the container.

      You can define your own custom animations for these four types of events to customize the look of your layout transitions or just tell the animation system to use the default animations.

      간단한 사용방법

      <LinearLayout 
         android:orientation="vertical"
         android:layout_width="wrap_content"
         android:layout_height="match_parent"
         android:id="@+id/verticalContainer"
         android:animateLayoutChanges="true" />

      Setting this attribute to true automatically animates Views that are added or removed from the ViewGroup as well as the remaining Views in the ViewGroup.

      Animate view state changes using StateListAnimator

      view의 상태 변화에 따른 animation. 이를 구현하는 방법으로는 두가지가 있다. 

      1. property animation – StateListAnimator class 이용하는 방법
      2. drawable animation 

      property animation – StateListAnimator class 이용하는 방법

      The StateListAnimator class lets you define animators that run when the state of a view changes. This object behaves as a wrapper for an Animator object, calling that animation whenever the specified view state (such as “pressed” or “focused”) changes.

      The StateListAnimator can be defined in an XML resource with a root <selector> element and child <item> elements that each specify a different view state defined by the StateListAnimator class. Each <item> contains the definition for a property animation set ( 여러개의 animation 모음 ).

      res/xml/animate_scale.xml

      <?xml version="1.0" encoding="utf-8"?> 
      <selector xmlns:android="http://schemas.android.com/apk/res/android">
         <!-- the pressed state; increase x and y size to 150% -->
         <item android:state_pressed="true">
             <set>
                 <objectAnimator android:propertyName="scaleX"
                     android:duration="@android:integer/config_shortAnimTime"
                     android:valueTo="1.5"
                     android:valueType="floatType"/>
                 <objectAnimator android:propertyName="scaleY"
                     android:duration="@android:integer/config_shortAnimTime"
                     android:valueTo="1.5"
                     android:valueType="floatType"/>
             </set>
         </item>
         <!-- the default, non-pressed state; set x and y size to 100% -->
         <item android:state_pressed="false">
             <set>
                 <objectAnimator android:propertyName="scaleX"
                     android:duration="@android:integer/config_shortAnimTime"
                     android:valueTo="1"
                     android:valueType="floatType"/>
                 <objectAnimator android:propertyName="scaleY"
                     android:duration="@android:integer/config_shortAnimTime"
                     android:valueTo="1"
                     android:valueType="floatType"/>
             </set>
         </item>
      </selector>

      위의 state list animator를 view에 덧붙이는 방법은 두가지 

      1. xml 방법
      2. code 방법

      xml 방법

      <Button android:stateListAnimator="@xml/animate_scale" 
             ... />

      code 방법

      AnimatorInflater.loadStateListAnimator() method, and assign the animator to your view with the View.setStateListAnimator() method.

      drawable animation ( 뉴스완장 작업시 내가 사용한 적이 있음 )

      <!-- res/drawable/myanimstatedrawable.xml --> 
      <animated-selector
         xmlns:android="http://schemas.android.com/apk/res/android">

         <!-- provide a different drawable for each state-->
         <item android:id="@+id/pressed" android:drawable="@drawable/drawableP"
             android:state_pressed="true"/>
         <item android:id="@+id/focused" android:drawable="@drawable/drawableF"
             android:state_focused="true"/>
         <item android:id="@id/default"
             android:drawable="@drawable/drawableD"/>

         <!-- specify a transition -->
         <transition android:fromId="@+id/default" android:toId="@+id/pressed">
             <animation-list>
                 <item android:duration="15" android:drawable="@drawable/dt1"/>
                 <item android:duration="15" android:drawable="@drawable/dt2"/>
                 ...
             </animation-list>
         </transition>
         ...
      </animated-selector>

      Use a TypeEvaluator

      animation 진행되면서 변화하는 property value를 만들어주는 class. 

      Android system are int, float, or a color, which are supported by the IntEvaluator, FloatEvaluator, and ArgbEvaluator type evaluators.

      Use Interpolators

      The Android system provides a set of common interpolators in the android.view.animation package

      Specify keyframes

      A Keyframe object consists of a time/value pair that lets you define a specific state at a specific time of an animation. 

      Keyframe.ofFloat( 시간, 밸류 )

      Keyframe kf0 = Keyframe.ofFloat(0f, 0f); 
      Keyframe kf1 = Keyframe.ofFloat(.5f, 360f);
      Keyframe kf2 = Keyframe.ofFloat(1f, 0f);
      PropertyValuesHolder pvhRotation = PropertyValuesHolder.ofKeyframe("rotation", kf0, kf1, kf2);
      ObjectAnimator rotationAnim = ObjectAnimator.ofPropertyValuesHolder(target, pvhRotation);
      rotationAnim.setDuration(5000);

      drawable image를 이용한 keyframe animation – 영화필름작업과 유사 ( 위의 keyframe과는 전혀 무관함 헷갈리지 않기를 ) https://youtu.be/V3ksidLf7vA

      Animate views

      view animation은 겉모양만 변경시킨다.

      The property animation system can animate Views on the screen by changing the actual properties in the View objects. In addition, Views also automatically call the invalidate() method to refresh the screen

      property 종류

      • translationX and translationY
      • rotation, rotationX, and rotationY
      • scaleX and scaleY
      • pivotX and pivotY
      • x and y: These are simple utility properties to describe the final location of the View in its container, as a sum of the left and top values and translationX and translationY values.
      • alpha

      사용 예시

      ObjectAnimator.ofFloat(myView, "rotation", 0f, 360f);

      Animate using ViewPropertyAnimator

      The ViewPropertyAnimator provides a simple way to animate several properties of a View in parallel. 

      아래 세 코드들은 다 같은 결과를 가져온다. 각기 다른 방법으로 구현 가능

      ViewPropertyAnimator

      myView.animate().x(50f).y(100f);

      Multiple ObjectAnimator objects와 AnimatorSet 를 이용한 방법

      ObjectAnimator animX = ObjectAnimator.ofFloat(myView, "x", 50f); 
      ObjectAnimator animY = ObjectAnimator.ofFloat(myView, "y", 100f);
      AnimatorSet animSetXY = new AnimatorSet();
      animSetXY.playTogether(animX, animY);
      animSetXY.start();

      one ObjectAnimator를 이용한 방법

      PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("x", 50f); 
      PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("y", 100f);
      ObjectAnimator.ofPropertyValuesHolder(myView, pvhX, pvhY).start();

      Declare animations in XML

      xml을 이용 animation을 구현하는 방법

      • ValueAnimator<animator>
      • ObjectAnimator<objectAnimator>
      • AnimatorSet<set>
      <set android:ordering="sequentially"> 
         <set>
             <objectAnimator
                 android:propertyName="x"
                 android:duration="500"
                 android:valueTo="400"
                 android:valueType="intType"/>
             <objectAnimator
                 android:propertyName="y"
                 android:duration="500"
                 android:valueTo="300"
                 android:valueType="intType"/>
         </set>
         <objectAnimator
             android:propertyName="alpha"
             android:duration="500"
             android:valueTo="1f"/>
      </set>

      위와 같이 xml화일을 만들고 아래 코드를 activity, fragment에 넣어줘야 한다.

      AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(myContext, 
         R.animator.property_animator);
      set.setTarget(myObject);
      set.start();

      ValueAnimator를 이용한 예시도 docs에 있다.   https://developer.android.com/guide/topics/graphics/prop-animation

      Animate drawable graphics

      The first option is to use an Animation Drawable. This allows you to specify several static drawable files that will be displayed one at a time to create an animation. The second option is to use an Animated Vector Drawable, which lets you animate the properties of a vector drawable.

      Use AnimationDrawable

      The AnimationDrawable class is the basis for Drawable animations.

      While you can define the frames of an animation in your code, using the AnimationDrawable class API, it’s more simply accomplished with a single XML file that lists the frames that compose the animation. The XML file for this kind of animation belongs in the res/drawable/ directory.

      <animation-list xmlns:android="http://schemas.android.com/apk/res/android" 
         android:oneshot="true">
         <item android:drawable="@drawable/rocket_thrust1" android:duration="200" />
         <item android:drawable="@drawable/rocket_thrust2" android:duration="200" />
         <item android:drawable="@drawable/rocket_thrust3" android:duration="200" />
      </animation-list>

      By setting the android:oneshot attribute of the list to true, it will cycle just once then stop and hold on the last frame. If it is set false then the animation will loop. 

      AnimationDrawable rocketAnimation; 

      public void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.main);

       ImageView rocketImage = (ImageView) findViewById(R.id.rocket_image);
       rocketImage.setBackgroundResource(R.drawable.rocket_thrust);
       rocketAnimation = (AnimationDrawable) rocketImage.getBackground();

       rocketImage.setOnClickListener(new View.OnClickListener() {
           @Override
           public void onClick(View view) {
             rocketAnimation.start();
           }
       });
      }

      start() method called on the AnimationDrawable cannot be called during the onCreate() method of your Activity, because the AnimationDrawable is not yet fully attached to the window. call it from the onStart() method in your Activity.

      Use AnimatedVectorDrawable

      svg image file을 shapeshifter를 이용해서 android에서 사용가능한 xml화일로 바꾸고 이를 ImageView에서 연다.

      위에서 언급한 과정을 보여주는 예시 동영상 https://youtu.be/TfiZmzqAMgA

      https://developer.android.com/training/animation/reveal-or-hide-view

      Reveal or hide a view using animation

      자주 사용하는 animation 3가지 설명

      Create a crossfade animation

      Create a card flip animation

      Create a circular reveal animation

           – 참고자료)  https://youtu.be/X5hQv2uadjk

      https://developer.android.com/training/animation/reposition-view

      Move a View with Animation

      Change the view position with ObjectAnimator

      The ObjectAnimator API provides an easy way to change the properties of a view with a specified duration.

      ObjectAnimator animation = ObjectAnimator.ofFloat(view, "translationX", 100f); 
      animation.setDuration(2000);
      animation.start();

      Add curved motion

      Use PathInterpolator

      The PathInterpolator class is a new interpolator introduced in Android 5.0 (API 21). view가 이동하는 궤적을 휘어지게 한다.

      // arcTo() and PathInterpolator only available on API 21+ 
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
       Path path = new Path();
       path.arcTo(0f, 0f, 1000f, 1000f, 270f, -180f, true);
       PathInterpolator pathInterpolator = new PathInterpolator(path);
      }

      You can also define a path interpolator as an XML resource:

      <pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android" 
         android:controlX1="0.4"
         android:controlY1="0"
         android:controlX2="1"
         android:controlY2="1"/>
      ObjectAnimator animation = ObjectAnimator.ofFloat(view, "translationX", 100f); 
      animation.setInterpolator(pathInterpolator);
      animation.start();

      Define your own path

      The ObjectAnimator class has new constructors that enable you to animate coordinates along a path using two or more properties at once along with a path.

      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 
       Path path = new Path();
       path.arcTo(0f, 0f, 1000f, 1000f, 270f, -180f, true);
       ObjectAnimator animator = ObjectAnimator.ofFloat(view, View.X, View.Y, path);
       animator.setDuration(2000);
       animator.start();
      } else {
       // Create animator without using curved path
      }

      https://developer.android.com/guide/topics/graphics/fling-animation

      Move views using a fling animation

      image

      Add the support library

      dependencies { 
           implementation 'com.android.support:support-dynamic-animation:28.0.0'
       }
       

      Create a fling animation

      FlingAnimation fling = new FlingAnimation(view, DynamicAnimation.SCROLL_X);

      Set velocity

      You can use a fixed value as the starting velocity, or you can base it off of the velocity of a touch gesture. If you choose to provide a fixed value, you should define the value in dp per second, then convert it to pixels per second. Defining the value in dp per second allows the velocity to be independent of a device’s density and form factors.

      Note: Use the GestureDetector.OnGestureListener and the VelocityTracker classes to retrieve and compute the velocity of touch gestures, respectively. ( 사용자의 스와이프 속도에 따른 속도설정 )

      Set an animation value range

      setMinValue() and setMaxValue() methods

      Set friction

      setFriction() method lets you change the animation’s friction. 

      Sample code

      FlingAnimation fling = new FlingAnimation(view, DynamicAnimation.SCROLL_X); 
      fling.setStartVelocity(-velocityX)
             .setMinValue(0)
             .setMaxValue(maxScroll)
             .setFriction(1.1f)
             .start();

      Set the minimum visible change

      anim.setMinimumVisibleChange(DynamicAnimation.MIN_VISIBLE_CHANGE_SCALE);

      https://developer.android.com/guide/topics/graphics/spring-animation

      Animate movement using spring physics

      the SpringForce class lets you customize spring’s stiffness, its damping ratio, and its final position.

      간단한 사용방법

      • Add the support library You must add the support library to your project to use the spring animation classes.
      • Create a spring animation: create an instance of the SpringAnimation class and set the motion behavior parameters.
      • (Optional) Register listeners: Register listeners to watch for animation lifecycle changes and animation value updates.

      Note: Update listener should be registered only if you need per-frame update on the animation value changes. An update listener prevents the animation from potentially running on a separate thread

      • (Optional) Remove listeners
      • (Optional) Set a start value
      • (Optional) Set a value range: Set the animation value range to restrain values within the minimum and the maximum range.
      • (Optional) Set start velocity: Set the start velocity for the animation.
      • (Optional) Set spring properties: Set the damping ratio and the stiffness on the spring.
      • (Optional) Create a custom spring
      • Start animation: Start the spring animation.
      • (Optional) Cancel animation

      .

      Add the support library

      fling animation 에서도 같은 library를 이용한다. 

      (참고로 circular reveal animation는 Android 5.0 (API level 21) and higher 에 기본내장)

      (참고로 zoomin, crossfader, card filp은 원래 sdk에 내장되어있는 library이용)

      1. Open the build.gradle file for your app module.
      2. Add the support library to the dependencies section.
        dependencies { 
           implementation 'com.android.support:support-dynamic-animation:28.0.0'
       }

      Create a spring animation

      final View img = findViewById(R.id.imageView); 
      // Setting up a spring animation to animate the view’s translationY property with the final
      // spring position at 0.
      final SpringAnimation springAnim = new SpringAnimation(img, DynamicAnimation.TRANSLATION_Y, 0);

      The spring-based animation can animate views on the screen by changing the actual properties in the view objects. 아래 property 밸류가 스프링 운동으로 변하게 된다.

      • ALPHA
      • TRANSLATION_X, TRANSLATION_Y, and TRANSLATION_Z

               TRANSLATION_X describes the left coordinate.
               TRANSLATION_Y describes the top coordinate.
               TRANSLATION_Z describes the depth of the view relative to its elevation.

      • ROTATION, ROTATION_X, and ROTATION_Y: These properties control the rotation in 2D (rotation property) and 3D around the pivot point.
      • SCROLL_X and SCROLL_Y: These properties indicate the scroll offset of the source left and the top edge in pixels. It also indicates the position in terms how much the page is scrolled.
      • SCALE_X and SCALE_Y
      • X, Y, and Z: These are basic utility properties to describe the final location of the view in its container.

               X is a sum of the left value and TRANSLATION_X.
               Y is a sum of the top value and TRANSLATION_Y.
               Z is a sum of the elevation value and TRANSLATION_Z

      Register listeners

      DynamicAnimation class ( sprint animation 포함 ) provides two listeners: OnAnimationUpdateListener and OnAnimationEndListener.

      OnAnimationUpdateListener

      When you want to animate multiple views to create a chained animation, you can set up OnAnimationUpdateListener to receive a callback every time there is a change in the current view’s property. The callback notifies the other view to update its spring position based on the change incurred in the current view’s property.

      // Creating two views to demonstrate the registration of the update listener. 
      final View view1 = findViewById(R.id.view1);
      final View view2 = findViewById(R.id.view2);

      // Setting up a spring animation to animate the view1 and view2 translationX and translationY properties
      final SpringAnimation anim1X = new SpringAnimation(view1,
             DynamicAnimation.TRANSLATION_X);
      final SpringAnimation anim1Y = new SpringAnimation(view1,
         DynamicAnimation.TRANSLATION_Y);
      final SpringAnimation anim2X = new SpringAnimation(view2,
             DynamicAnimation.TRANSLATION_X);
      final SpringAnimation anim2Y = new SpringAnimation(view2,
             DynamicAnimation.TRANSLATION_Y);

      // Registering the update listener
      anim1X.addUpdateListener(new DynamicAnimation.OnAnimationUpdateListener() {

      // Overriding the method to notify view2 about the change in the view1’s property.
         @Override
         public void onAnimationUpdate(DynamicAnimation dynamicAnimation, float value,
                                       float velocity) {
             anim2X.animateToFinalPosition(value);
         }
      });

      anim1Y.addUpdateListener(new DynamicAnimation.OnAnimationUpdateListener() {

       @Override
         public void onAnimationUpdate(DynamicAnimation dynamicAnimation, float value,
                                       float velocity) {
             anim2Y.animateToFinalPosition(value);
         }
      });

      OnAnimationEndListener

      1. Call the addEndListener() method and attach the listener to the animation.
      2. Override the onAnimationEnd() method to receive notification whenever an animation reaches equilibrium or is canceled.

      Remove listeners

      call removeUpdateListener() and removeEndListener() methods.

      Set animation start value

      call the setStartValue() method and pass the start value of the animation. If you do not set the start value, the animation uses the current value of the object’s property as the start value.

      Set animation value range

      when you want to restrain the property value to a certain range.

      • setMinValue()
      • setMaxValue()

      아래 작업들은 SpringForce obj에 각 특성들을 설정하는 작업

      Set start velocity ( fling animation과 같다. )

      Start velocity defines the speed at which the animation property changes at the beginning of the animation. The default start velocity is set to zero pixels per second. You can set a fixed value as the start velocity. If you choose to provide a fixed value, we recommend to define the value in dp per second and then convert it to pixels per second. Defining the value in dp per second allows velocity to be independent of density and form factors. For more information about converting value to pixels per second, refer to the Converting dp per second to pixels per second section.

      To set the velocity, call the setStartVelocity() method and pass the velocity in pixels per second. The method returns the spring force object on which the velocity is set.

      Note: Use the GestureDetector.OnGestureListener or the VelocityTracker class methods to retrieve and compute the velocity of touch gestures.

      final View img = findViewById(R.id.imageView); 
      final SpringAnimation anim = new SpringAnimation(img, DynamicAnimation.TRANSLATION_Y);

      // Compute velocity in the unit pixel/second
      vt.computeCurrentVelocity(1000);
      float velocity = vt.getYVelocity();
      anim.setStartVelocity(velocity);

      Converting dp per second to pixels per second

      float pixelPerSecond = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpPerSecond, getResources().getDisplayMetrics());

      Set spring properties

      The SpringForce class defines the getter and the setter methods for each of the spring properties, such as damping ratio and stiffness.

      setting method는 obj 자신을 return 하므로 chaining 이 가능하다. 

      Damping ratio

      1. getSpring() to retrieve the SpringForce obj.
      2. setDampingRatio()  damping ratio must be a non-negative number. If you set the damping ratio to zero, the spring will never reach the rest position. In other words, it oscillates forever.

      ratio constants are available in the system:

      • DAMPING_RATIO_HIGH_BOUNCY
      • DAMPING_RATIO_MEDIUM_BOUNCY
      • DAMPING_RATIO_LOW_BOUNCY
      • DAMPING_RATIO_NO_BOUNCY
      final View img = findViewById(R.id.imageView); 
      final SpringAnimation anim = new SpringAnimation(img, DynamicAnimation.TRANSLATION_Y);

      //Setting the damping ratio to create a low bouncing effect.
      anim.getSpring().setDampingRatio(SpringForce.DAMPING_RATIO_LOW_BOUNCY);

      Stiffness

      the strength of the spring. 

      1. getSpring() to retrieve SpringForce obj.
      2. setStiffness() Note: The stiffness must be a positive number.

      stiffness constants are available in the system:

      • STIFFNESS_HIGH
      • STIFFNESS_MEDIUM
      • STIFFNESS_LOW
      • STIFFNESS_VERY_LOW
      final View img = findViewById(R.id.imageView); 
      final SpringAnimation anim = new SpringAnimation(img, DynamicAnimation.TRANSLATION_Y);

      //Setting the spring with a low stiffness.
      anim.getSpring().setStiffness(SpringForce.STIFFNESS_LOW);

        Create a custom spring force

        1. Create a SpringForce object.
        2. Assign the properties by calling the respective methods. You can also create a method chain.
        3. Call the setSpring() method to set the spring to the animation.

        SpringForce force = new SpringForce();

        force.setDampingRatio(DAMPING_RATIO_LOW_BOUNCY).setStiffness(STIFFNESS_LOW);

        setSpring(force);

        Start animation

        There are two ways you can start a spring animation: By calling the start() or by calling the animateToFinalPosition() method. Both the methods need to be called on the main thread.

        animateToFinalPosition() method performs two tasks:

        • Sets the final position of the spring – setFinalPosition()
        • Starts the animation, if it has not started.
        final View img = findViewById(R.id.imageView); 
        final SpringAnimation anim = new SpringAnimation(img, DynamicAnimation.TRANSLATION_Y);

        //Starting the animation
        anim.start();

        Cancel animation

        사용자 갑자가 exit 하는 경우 cancel 처리한다.

        There are two methods. The cancel() method terminates the animation at the value where it is. The skipToEnd() method skips the animation to the final value and then terminates it.

        Before you can terminate the animation, it is important to first check the state of the spring. If the state is undamped, the animation can never reach the rest position. To check the state of the spring, call the canSkipToEnd() method. If the spring is damped, the method returns true, otherwise false.

        The cancel() method must be called only on the main thread.

        Note: the skipToEnd() method causes a visual jump.

        https://developer.android.com/training/animation/layout

        Auto animate layout updates

        <LinearLayout android:id="@+id/container" 
           android:animateLayoutChanges="true"
           ...
        />

        android:animateLayoutChanges attribute를 설정함으로써 layout안에 element가 만들어지고 사라질때 시스템이 제공하는 애니메이션을 적용할수 있다. 

        Tip: If you want to supply custom layout animations, create a LayoutTransition object and supply it to the layout with the setLayoutTransition() method.

        https://developer.android.com/training/transitions/

        Animate layout changes using a transition

        참고) https://code.tutsplus.com/tutorials/an-introduction-to-android-transitions–cms-21640

        https://www.youtube.com/watch?v=00uf3cwC0I0

        변화전 layout scene 변화후 layout scene을 정하면 자동으로 animation이 적용된다. 적용되는 animation 종류도 여러가지가 있다. 

        scene간의 layout transition animation을 사용할때의 장점

        • Group-level animations: Apply one or more animation effects to all of the views in a view hierarchy.
        • Built-in animations: Use predefined animations for common effects such as fade out or movement.
        • Resource file support: Load view hierarchies and built-in animations from layout resource files.
        • Lifecycle callbacks: Receive callbacks that provide control over the animation and hierarchy change process.

        Note: between layouts within the same activity. If the user is moving between activities then you should instead read Start an activity using an animation.

        The basic process to animate between two layouts is as follows:

        1. Create a Scene object for both the starting layout and the ending layout. However, the starting layout’s scene is often determined automatically from the current layout.
        2. Create a Transition object to define what type of animation you want.
        3. Call TransitionManager.go() and the system runs the animation to swap the layouts.

        Create a scene

        Scenes store the state of a view hierarchy, including all its views and their property values. The transitions framework can run animations between a starting and an ending scene.

        You can create your scenes from a layout resource file or from a group of views in your code. However, the starting scene for your transition is often determined automatically from the current UI.

        A scene can also define its own actions that run when you make a scene change.

        Note: The framework can animate changes in a single view hierarchy without using scenes, as described in Apply a transition without scenes. 

        Create a scene from a layout resource

        You can create a Scene instance directly from a layout resource file. Use this technique when the view hierarchy in the file is mostly static. The resulting scene represents the state of the view hierarchy at the time you created the Scene instance. If you change the view hierarchy, you have to recreate the scene. The framework creates the scene from the entire view hierarchy in the file; you can not create a scene from part of a layout file.

        To create a Scene instance from a layout resource file, retrieve the scene root ( 이란 scene을 포함하게 될 container layout 아래 예에서는 framelayout id scene_root 이 해당된다 ) from your layout as a ViewGroup instance and then call the Scene.getSceneForLayout() function with the scene root and the resource ID of the layout file that contains the view hierarchy for the scene.

        예시코드) 

        res/layout/activity_main.xml

        <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
           android:id="@+id/master_layout">
           <TextView
               android:id="@+id/title"
               ...
               android:text="Title"/>
           <FrameLayout
               android:id="@+id/scene_root">
               <include layout="@layout/a_scene" />
           </FrameLayout>
        </LinearLayout>

        scene은 xml화일 부분을 가지고 만들수 없으므로 예시에서는 scene에 해당하는 layout file을 따로 만들고 include를 이용 포함 시켰다. 

        res/layout/a_scene.xml

        <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
           android:id="@+id/scene_container"
           android:layout_width="match_parent"
           android:layout_height="match_parent" >
           <TextView
               android:id="@+id/text_view1
               android:text="Text Line 1" />
           <TextView
               android:id="@+id/text_view2
               android:text="Text Line 2" />
        </RelativeLayout>

        res/layout/another_scene.xml

        <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
           android:id="@+id/scene_container"
           android:layout_width="match_parent"
           android:layout_height="match_parent" >
           <TextView
               android:id="@+id/text_view2
               android:text="Text Line 2" />
           <TextView
               android:id="@+id/text_view1
               android:text="Text Line 1" />
        </RelativeLayout>

        scenes 이 될 두 xml화일들은 같은 elements를 가지고 있으며 위치만 다르다.( 꼭 이렇게 같은 element로 구성되어야 하는지는 확인이 필요하다. )

        Generate scenes from layouts

        Scene mAScene; 
        Scene mAnotherScene;

        // Create the scene root for the scenes in this app
        mSceneRoot = (ViewGroup) findViewById(R.id.scene_root);

        // Create the scenes
        mAScene = Scene.getSceneForLayout(mSceneRoot, R.layout.a_scene, this);
        mAnotherScene =
           Scene.getSceneForLayout(mSceneRoot, R.layout.another_scene, this);

        Create a scene in your code

        You can also create a Scene instance in your code from a ViewGroup object. Use this technique when you modify the view hierarchies directly in your code or when you generate them dynamically.

        Scene mScene; 

        // Obtain the scene root element
        mSceneRoot = (ViewGroup) mSomeLayoutElement;

        // Obtain the view hierarchy to add as a child of
        // the scene root when this scene is entered
        mViewHierarchy = (ViewGroup) someOtherLayoutElement;

        // Create a scene
        mScene = new Scene(mSceneRoot, mViewHierarchy);

        Create scene actions

        ( layout이 바뀌어 transition되는 과정에 추가 작업을 할수 있는 hook functions에 대한 설명 )

        The framework enables you to define custom scene actions that the system runs when entering or exiting a scene. In many cases, defining custom scene actions is not necessary, since the framework animates the change between scenes automatically.

        Scene actions are useful for handling these cases:

        • Animate views that are not in the same hierarchy. You can animate views for both the starting and ending scenes using exit and entry scene actions.
        • Animate views that the transitions framework cannot animate automatically, such as ListView objects. For more information, see Limitations.

        To provide custom scene actions, define your actions as Runnable objects and pass them to the Scene.setExitAction() or Scene.setEnterAction() functions. The framework calls the setExitAction() function on the starting scene before running the transition animation and the setEnterAction() function on the ending scene after running the transition animation.

        Note: Do not use scene actions to pass data between views in the starting and ending scenes. For more information, see Define transition lifecycle callbacks.

        Apply a transition

        ( Transition은 activity간의 transition에도 사용된다  )

        The transition framework represents the style of animation between scenes with a object. You can instantiate a Transition using several built-in subclasses, such as AutoTransition and Fade, or define your own transition. Then, you can run the animation between scenes by passing your end Scene and the Transition to TransitionManager.go().

        ( Transition을 extend한 animation 역할을 하는 transition 으로는 Fade, AutoTransition, ChangeBounds 있다 )

        The transition lifecycle is similar to the activity lifecycle, and it represents the transition states that the framework monitors between the start and the completion of an animation. 

        Create a transition instance from a resource file

        This technique enables you to modify your transition definition without having to change the code of your activity. This technique is also useful to separate complex transition definitions from your application code, as shown in Specify multiple transitions.

        To specify a built-in transition in a resource file, follow these steps:

        1. Add the res/transition/ directory to your project.
        2. Create a new XML resource file inside this directory.
        3. Add an XML node for one of the built-in transitions.

        For example, the following resource file specifies the Fade transition:

        res/transition/fade_transition.xml

        <fade xmlns:android="http://schemas.android.com/apk/res/android" />

        The following code snippet shows how to inflate a Transition instance inside your activity from a resource file:

        Transition mFadeTransition = 
               TransitionInflater.from(this).
               inflateTransition(R.transition.fade_transition);

        Create a transition instance in your code

        This technique is useful for creating transition objects dynamically if you modify the user interface in your code, and to create simple built-in transition instances with few or no parameters.

        To create an instance of a built-in transition, invoke one of the public constructors in the subclasses of the Transition class. For example, the following code snippet creates an instance of the Fade transition:

        Transition mFadeTransition = new Fade();

        Apply a transition

        TransitionManager.go(mEndingScene, mFadeTransition);

        The starting scene is the ending scene from the last transition. If there was no previous transition, the starting scene is determined automatically from the current state of the user interface.

        If you do not specify a transition instance, the transition manager can apply an automatic transition .

        Choose specific target views

        The framework enables you to select specific views you want to animate.

        Each view that the transition animates is called a target. You can only select targets that are part of the view hierarchy associated with a scene.

        To remove one or more views from the list of targets, call the removeTarget() method before starting the transition. To add only the views you specify to the list of targets, call the addTarget()function.

        Specify multiple transitions

        You do not have to choose only one animation, since the transitions framework enables you to combine animation effects in a transition set that contains a group of individual built-in or custom transitions.

        To define a transition set from a collection of transitions in XML, create a resource file in the res/transitions/ directory and list the transitions under the transitionSet element.

        <transitionSet xmlns:android="http://schemas.android.com/apk/res/android" 
            android:transitionOrdering="sequential">
            <fade android:fadingMode="fade_out" />
            <changeBounds />
            <fade android:fadingMode="fade_in" />
        </transitionSet>

        To inflate the transition set into a TransitionSet object in your code, call the TransitionInflater.from() function in your activity. The TransitionSet class extends from theTransition class, so you can use it with a transition manager just like any other Transition instance.

        Apply a transition without scenes

        처음과 마지막 큰차이가 없는 경우 굳이 scenes를 만들필요없이 간단히 animaation을 만들수 있다. ViewGroup.removeView() function, and add the search results by calling ViewGroup.addView() function.

        참고) https://youtu.be/K3yMV5am-Xo?t=630

        예시코드) 

        res/layout/activity_main.xml

        <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
           android:id="@+id/mainLayout"
           android:layout_width="match_parent"
           android:layout_height="match_parent" >
           <EditText
               android:id="@+id/inputText"
               android:layout_alignParentLeft="true"
               android:layout_alignParentTop="true"
               android:layout_width="match_parent"
               android:layout_height="wrap_content" />
           ...
        </RelativeLayout>

        MainActivity

        private TextView mLabelText; 
        private Fade mFade;
        private ViewGroup mRootView;
        ...

        // Load the layout
        setContentView(R.layout.activity_main);
        ...

        // Create a new TextView and set some View properties
        mLabelText = new TextView(this);
        mLabelText.setText("Label");
        mLabelText.setId(R.id.text);

        // Get the root view and create a transition
        mRootView = (ViewGroup) findViewById(R.id.mainLayout);
        mFade = new Fade(Fade.IN);

        // Start recording changes to the view hierarchy
        TransitionManager.beginDelayedTransition(mRootView, mFade);

        // Add the new TextView to the view hierarchy
        mRootView.addView(mLabelText);

        // When the system redraws the screen to show this update,
        // the framework will animate the addition as a fade in

        Define transition lifecycle callbacks

         the TransitionListener 를 이용한다.

        Transition lifecycle callbacks are useful, for example, for copying a view property value from the starting view hierarchy to the ending view hierarchy during a scene change. You cannot simply copy the value from its starting view to the view in the ending view hierarchy, because the ending view hierarchy is not inflated until the transition is completed. Instead, you need to store the value in a variable and then copy it into the ending view hierarchy when the framework has finished the transition. To get notified when the transition is completed, you can implement the TransitionListener.onTransitionEnd() function in your activity.

        https://developer.android.com/training/transitions/custom-transitions

        Create a custom transition animation 

        ( customized된 transition은 layout 변화에도 사용되고 activity transition에도 사용된다 )

        Extend the Transition class

        public class CustomTransition extends Transition { 

           @Override
           public void captureStartValues(TransitionValues values) {}

           @Override
           public void captureEndValues(TransitionValues values) {}

           @Override
           public Animator createAnimator(ViewGroup sceneRoot,
                                          TransitionValues startValues,
                                          TransitionValues endValues) {}
        }

        Capture view property values

        Transition animations use the property animation system.

        Capture starting values

        To pass the starting view values to the framework, implement the captureStartValues(transitionValues) function. The framework calls this function for every view in the starting scene. The function argument is a TransitionValues object that contains a reference to the view and a Map instance in which you can store the view values you want. In your implementation, retrieve these property values and pass them back to the framework by storing them in the map.

        To ensure that the key for a property value does not conflict with other TransitionValues keys, use the following naming scheme:

        package_name:transition_name:property_name

        public class CustomTransition extends Transition { 

           // Define a key for storing a property value in
           // TransitionValues.values with the syntax
           // package_name:transition_class:property_name to avoid collisions
           private static final String PROPNAME_BACKGROUND =
                   "com.example.android.customtransition:CustomTransition:background";

           @Override
           public void captureStartValues(TransitionValues transitionValues) {
               // Call the convenience method captureValues
               captureValues(transitionValues);
           }


           // For the view in transitionValues.view, get the values you
           // want and put them in transitionValues.values
           private void captureValues(TransitionValues transitionValues) {
               // Get a reference to the view
               View view = transitionValues.view;
               // Store its background property in the values map
               transitionValues.values.put(PROPNAME_BACKGROUND, view.getBackground());
           }
           ...
        }

        Capture ending values

        The framework calls the captureEndValues(TransitionValues) function once for every target view in the ending scene. In all other respects, captureEndValues() works the same as captureStartValues().

        @Override 
        public void captureEndValues(TransitionValues transitionValues) {
           captureValues(transitionValues);
        }

        In this example, both the captureStartValues() and captureEndValues() functions invoke captureValues() to retrieve and store values. The view property that captureValues() retrieves is the same, but it has different values in the starting and ending scenes. The framework maintains separate maps for the starting and ending states of a view.

        Create a custom animator

        To animate the changes to a view between its state in the starting scene and its state in the ending scene, you provide an animator by overriding the createAnimator() function. When the framework calls this function, it passes in the scene root view and the TransitionValues objects that contain the starting and ending values you captured.

        The number of times the framework calls the createAnimator() function depends on the changes that occur between the starting and ending scenes. For example, consider a fade out/fade in animation implemented as a custom transition. If the starting scene has five targets of which two are removed from the ending scene, and the ending scene has the three targets from the starting scene plus a new target, then the framework calls createAnimator() six times: three of the calls animate the fading out and fading in of the targets that stay in both scene objects; two more calls animate the fading out of the targets removed from the ending scene; and one call animates the fading in of the new target in the ending scene.

        For target views that exist on both the starting and ending scenes, the framework provides a TransitionValues object for both the startValues and endValues arguments. For target views that only exist in the starting or the ending scene, the framework provides a TransitionValues object for the corresponding argument and null for the other.

        To implement the createAnimator(ViewGroup, TransitionValues, TransitionValues)function when you create a custom transition, use the view property values you captured to create an Animator object and return it to the framework. For an example implementation, see the ChangeColor class in the CustomTransition sample. For more information about property animators, see Property animation.

        Apply a custom transition

        Custom transitions work the same as built-in transitions. You can apply a custom transition using a transition manager, as described in Apply a transition.

        https://developer.android.com/training/transitions/start-activity

        Start an activity using an animation

        ( activity간의 transition이나 layout 변경에 따른 transition이나 다 같은 Transition class를 기본으로 사용한다. customizing하려는 경우 조금 위에 있는 https://developer.android.com/training/transitions/custom-transitions
        Create a custom transition animation 를 이용한다 )

        기본 3가지 종류

        • An enter transition determines how views in an activity enter the scene. 
        • An exit transition determines how views in an activity exit the scene. 
        • A shared elements transition determines how views that are shared between two activities transition between these activities.

        기본적으로 제공되는 enter and exit transitions:

        • explode – Moves views in or out from the center of the scene.
        • slide 
        • fade

        the default cross-fading transition is activated between the entering and exiting activities.

        Any transition that extends the Visibility class is supported as an enter or exit transition. 

        기본적으로 제공되는 shared elements transitions:

        • changeBounds – Animates the changes in layout bounds of target views.
        • changeClipBounds – Animates the changes in clip bounds of target views.
        • changeTransform – Animates the changes in scale and rotation of target views.
        • changeImageTransform – Animates changes in size and scale of target images.

        Check the system version

        Activity transition APIs are available on Android 5.0 (API 21) and up. 

        // Check if we're running on Android 5.0 or higher 
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
           // Apply activity transition
        } else {
           // Swap without transition
        }

        activity 간 transition을 사용하려는 작업

        1. style xml 화일을 이용 activity 간 transition을 구현하는 방법 ( app의 style로서 적용하는 방법 )

        First, enable window content transitions with the android:windowActivityTransitions attribute when you define a style that inherits from the material theme. You can also specify enter, exit, and shared element transitions in your style definition:

        <style name="BaseAppTheme" parent="android:Theme.Material"> 
         <!-- enable window content transitions -->
         <item name="android:windowActivityTransitions">true</item>

         <!-- specify enter and exit transitions -->
         <item name="android:windowEnterTransition">@transition/explode</item>
         <item name="android:windowExitTransition">@transition/explode</item>

         <!-- specify shared element transitions -->
         <item name="android:windowSharedElementEnterTransition">
           @transition/change_image_transform</item>
         <item name="android:windowSharedElementExitTransition">
           @transition/change_image_transform</item>
        </style>

        The change_image_transform transition in this example is defined as follows ( 다양한 transition을 같이 적용가능하다. https://developer.android.com/training/transitions/Animate layout changes using a transition 참고 가능  )

        <!-- res/transition/change_image_transform.xml --> 
        <!-- (see also Shared Transitions below) -->
        <transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
         <changeImageTransform/>
        </transitionSet>

        The changeImageTransform element corresponds to the ChangeImageTransform class. For more information, see the API reference for Transition.

        2. code에서 activity 간 transition을 구현하는 방법

        To enable window content transitions in your code instead, call the Window.requestFeature()function:

        // inside your activity (if you did not enable transitions in your theme) 
        getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);

        // set an exit transition
        getWindow().setExitTransition(new Explode());

        To specify transitions in your code, call these functions with a Transition object:

        • Window.setEnterTransition()
        • Window.setExitTransition()
        • Window.setSharedElementEnterTransition()
        • Window.setSharedElementExitTransition()

        The setExitTransition() and setSharedElementExitTransition() functions define the exit transition for the calling activity. The setEnterTransition() and setSharedElementEnterTransition() functions define the enter transition for the called activity.

        To start an enter transition as soon as possible, use the Window.setAllowEnterTransitionOverlap() function on the called activity. This lets you have more dramatic enter transitions.

        Start an activity using transitions

        startActivity(intent, 
                     ActivityOptions.makeSceneTransitionAnimation(this).toBundle());

        If you have set an enter transition for the second activity, the transition is also activated when the activity starts. To disable transitions when you start another activity, provide a null options bundle

        참고 ) https://youtu.be/BF4yvhpMPcg?t=760

        Start an activity with a shared element

        To make a screen transition animation between two activities that have a shared element:

        1. Enable window content transitions in your theme.
        2. Specify a shared elements transition in your style.
        3. Define your transition as an XML resource.
        4. Assign a common name to the shared elements in both layouts with theandroid:transitionName attribute.
        5. Use the ActivityOptions.makeSceneTransitionAnimation() function.
        // get the element that receives the click event 
        final View imgContainerView = findViewById(R.id.img_container);

        // get the common element for the transition in this activity
        final View androidRobotView = findViewById(R.id.image_small);

        // define a click listener
        imgContainerView.setOnClickListener(new View.OnClickListener() {
           @Override
           public void onClick(View view) {
               Intent intent = new Intent(this, Activity2.class);
               // create the transition animation - the images in the layouts
               // of both activities are defined with android:transitionName="robot"
               ActivityOptions options = ActivityOptions
                   .makeSceneTransitionAnimation(this, androidRobotView, "robot");
               // start the new activity
               startActivity(intent, options.toBundle());
           }
        });

        For shared dynamic views that you generate in your code, use the View.setTransitionName()function to specify a common element name in both activities.

        To reverse the scene transition animation when you finish the second activity, call theActivity.finishAfterTransition() function instead of Activity.finish().

        Start an activity with multiple shared elements

        To make a scene transition animation between two activities that have more than one shared element, define the shared elements in both layouts with the android:transitionName attribute (or use the View.setTransitionName() function in both activities), and create an ActivityOptions object as follows:

        ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(this, 
               Pair.create(view1, "agreedName1"),
               Pair.create(view2, "agreedName2"));

        VIEW ANIMATION , PROPERTY ANIMATION 둘다 같은 작업을 수행할수있다. 차이점이 있다면 view animation의 경우 animation후에 보이는 것은 변경되었을지 모르지만 실제 존재하는 위치는 같으므로 클릭을 한다고 하면 본래 위치에 클릭해야 해당 view가 이벤트를 받아들이게 된다.Their state changes but their property does not change. 

         ObjectAnimator를 이용하는 것은 property animation이다. ObjectAnimator is a subclass of ValueAnimator

        TranslateAnimationRotateAnimationScaleAnimationAlphaAnimation 을 이용하는 것은 view animation이다.  

        When using View Animations, use XML instead of doing it programmatically. Using XML files, it is more readable and can be shared among other views.

        참조 https://youtu.be/_UWXqFBF86U?t=204

        basics  3 types of Animations:

        1. Property Animations— They are used to alter property of objects (Views or non view objects). We specify certain properties(like translateX, TextScaleX) of the objects to change. Various characteristics of animation which can be manipulated are animation duration, whether to reverse it and for how many times we want to repeat the animation etc. They were introduced in Android 3.0 (API level 11).
        2. View Animations — They are used to do simple animations like changing size, position, rotation, control transparency. They are easy to build and are very fast but have their own constraints. For eg — Their state changes but their property does not change. View animations will be covered in part 2.
        3. Drawable Animations — This is used to do animation using drawables. An XML file specifying various list of drawables is made which are run one by one just like a roll of a film. This is not much used so I won’t cover it.

        property animation 

        •      – ObjectAnimator를 이용한다. ( ValueAnimator를 기반으로 한다 )
        •      – AnimatorSet 를 이용 여러 view들의 animations을 동시에 진행가능하다. ( with()를 사용하기도한다 )
        •      – 하나의 view에 대한 여러 animation을 동시에 진행하는 경우 ViewPropertyAnimator 를 이용한다. 
        animateTextView.animate().rotation(360f).y(500f).setDuration(2000);

        View Animation

        • Tween Animation — These are the animations applied on a view which is responsible for scaling, translating, rotating or fading a view (either together or one by one).
        • Frame Animation — These animations are applied using various drawables. In this, we just have to specify a list of drawables in the XML code and the animation runs just like frames of a video.

        View Animations are not much used because the same thing can be using ViewPropertyAnimator object which is much faster and readable. Frame animation is similar to Drawable Animation. The more important thing is to understand the new Transition framework which is much useful and provide beautiful animations.

        API 21이후에 추간된 ANIMATION

        Shared Element Transitions 

        Activity Transitions

        Circular Reveal

        Shared Element Transitions 

        http://blogs.quovantis.com/how-to-apply-shared-element-transitions-in-android/


        참고자료) 

        view animation brief explanation

        https://youtu.be/_UWXqFBF86U

        A beginners guide to implement Android Animations — Part 1 (2 part series)

        https://medium.com/@shubham.bestfriendforu/a-beginners-guide-to-implement-android-animations-part-1-2-part-series-b5fce1fc85

        VIEW ANIMATION VS PROPERTY ANIMATION IN ANDROID

        https://mahbubzaman.wordpress.com/2015/06/03/view-animation-vs-property-animation-in-android/

        Sometimes we need to animate some view in our application. Here is a sample code for translate a view over x axis from its location.


        Button bt;
        bt = (Button) findViewById(R.id.bt);
        bt.setOnClickListener(this);

        TranslateAnimation animation = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 300, Animation.RELATIVE_TO_SELF, Animation.RELATIVE_TO_SELF);
        animation.setDuration(1000);
        animation.setFillAfter(true);
        bt.setAnimation(animation);

        But the problem of this code is if you want to click this button after animate you can not, why lets read the documentation from android developer site

        disadvantage of the view animation system is that it only modified where the View was drawn, and not the actual View itself. For instance, if you animated a button to move across the screen, the button draws correctly, but the actual location where you can click the button does not change, so you have to implement your own logic to handle this.

        more

        To solve this issue we will use ObjectAnimator class to animate our view.


        ObjectAnimator animXNext = ObjectAnimator.ofFloat(bt, "translationX", Animation.RELATIVE_TO_SELF, 300);
        animXNext.setDuration(1000);
        animXNext.start();

        Now you can click on the button. Enjoy

        VIEW ANIMATION , PROPERTY ANIMATION 둘다 같은 작업을 수행할수있다. 차이점이 있다면 view animation의 경우 animation후에 보이는 것은 변경되었을지 모르지만 실제 존재하는 위치는 같으므로 클릭을 한다고 하면 본래 위치에 클릭해야 해당 view가 이벤트를 받아들이게 된다.Their state changes but their property does not change. 

         ObjectAnimator를 이용하는 것은 property animation이다. ObjectAnimator is a subclass of ValueAnimator

        TranslateAnimationRotateAnimationScaleAnimationAlphaAnimation 을 이용하는 것은 view animation이다.  

        When using View Animations, use XML instead of doing it programmatically. Using XML files, it is more readable and can be shared among other views.

        참조 https://youtu.be/_UWXqFBF86U?t=204

        basics  3 types of Animations:

        1. Property Animations— They are used to alter property of objects (Views or non view objects). We specify certain properties(like translateX, TextScaleX) of the objects to change. Various characteristics of animation which can be manipulated are animation duration, whether to reverse it and for how many times we want to repeat the animation etc. They were introduced in Android 3.0 (API level 11).
        2. View Animations — They are used to do simple animations like changing size, position, rotation, control transparency. They are easy to build and are very fast but have their own constraints. For eg — Their state changes but their property does not change. View animations will be covered in part 2.
        3. Drawable Animations — This is used to do animation using drawables. An XML file specifying various list of drawables is made which are run one by one just like a roll of a film. This is not much used so I won’t cover it.

        property animation 

        •      – ObjectAnimator를 이용한다. ( ValueAnimator를 기반으로 한다 )
        •      – AnimatorSet 를 이용 여러 view들의 animations을 동시에 진행가능하다. ( with()를 사용하기도한다 )
        •      – 하나의 view에 대한 여러 animation을 동시에 진행하는 경우 ViewPropertyAnimator 를 이용한다. 
        animateTextView.animate().rotation(360f).y(500f).setDuration(2000);

        View Animation

        • Tween Animation — These are the animations applied on a view which is responsible for scaling, translating, rotating or fading a view (either together or one by one).
        • Frame Animation — These animations are applied using various drawables. In this, we just have to specify a list of drawables in the XML code and the animation runs just like frames of a video.

        View Animations are not much used because the same thing can be using ViewPropertyAnimator object which is much faster and readable. Frame animation is similar to Drawable Animation. The more important thing is to understand the new Transition framework which is much useful and provide beautiful animations.

        API 21이후에 추간된 ANIMATION

        Shared Element Transitions 

        Activity Transitions

        Circular Reveal

        Shared Element Transitions 

        http://blogs.quovantis.com/how-to-apply-shared-element-transitions-in-android/


        참고자료) 

        view animation brief explanation

        https://youtu.be/_UWXqFBF86U

        A beginners guide to implement Android Animations — Part 1 (2 part series)

        https://medium.com/@shubham.bestfriendforu/a-beginners-guide-to-implement-android-animations-part-1-2-part-series-b5fce1fc85

        VIEW ANIMATION VS PROPERTY ANIMATION IN ANDROID

        https://mahbubzaman.wordpress.com/2015/06/03/view-animation-vs-property-animation-in-android/

        Sometimes we need to animate some view in our application. Here is a sample code for translate a view over x axis from its location.


        Button bt;
        bt = (Button) findViewById(R.id.bt);
        bt.setOnClickListener(this);

        TranslateAnimation animation = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 300, Animation.RELATIVE_TO_SELF, Animation.RELATIVE_TO_SELF);
        animation.setDuration(1000);
        animation.setFillAfter(true);
        bt.setAnimation(animation);

        But the problem of this code is if you want to click this button after animate you can not, why lets read the documentation from android developer site

        disadvantage of the view animation system is that it only modified where the View was drawn, and not the actual View itself. For instance, if you animated a button to move across the screen, the button draws correctly, but the actual location where you can click the button does not change, so you have to implement your own logic to handle this.

        more

        To solve this issue we will use ObjectAnimator class to animate our view.


        ObjectAnimator animXNext = ObjectAnimator.ofFloat(bt, "translationX", Animation.RELATIVE_TO_SELF, 300);
        animXNext.setDuration(1000);
        animXNext.start();

        Now you can click on the button. Enjoy

        A beginners guide to implement Android Animations — Part 1 (2 part series)

        A beginners guide to implement Android Animations — Part 1 (2 part series)