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 theonAnimationUpdate()
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 assetAlpha()
andsetTranslationX()
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 callsonAnimationEnd()
, 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 callinvalidate()
on a View to force that area of the screen to redraw itself with the new animated values.setAlpha()
andsetTranslationX()
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. 이를 구현하는 방법으로는 두가지가 있다.
- property animation –
StateListAnimator
class 이용하는 방법 - 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에 덧붙이는 방법은 두가지
- xml 방법
- 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
andtranslationY
rotation
,rotationX
, androtationY
scaleX
andscaleY
pivotX
andpivotY
x
andy
: 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
method in your Activity. onStart()
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
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이용)
- Open the
build.gradle
file for your app module. - 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
, andTRANSLATION_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
, andROTATION_Y
: These properties control the rotation in 2D (rotation
property) and 3D around the pivot point.SCROLL_X
andSCROLL_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
andSCALE_Y
X
,Y
, andZ
: 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
- Call the
addEndListener()
method and attach the listener to the animation. - 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
getSpring()
to retrieve the SpringForce obj.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.
getSpring()
to retrieve SpringForce obj.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
- Create a
SpringForce
object. - Assign the properties by calling the respective methods. You can also create a method chain.
- 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 thesetLayoutTransition()
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:
- 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. - Create a
Transition
object to define what type of animation you want. - 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 x
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:
- Add the
res/transition/
directory to your project. - Create a new XML resource file inside this directory.
- 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:
- Enable window content transitions in your theme.
- Specify a shared elements transition in your style.
- Define your transition as an XML resource.
- Assign a common name to the shared elements in both layouts with the
android:transitionName
attribute. - 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"));