SlideShare une entreprise Scribd logo
1  sur  71
10-12 September 2015
droidcon Greece
Thessaloniki
Animate me !
#AnimateMe
by(Mathias Seguy== Android2EE){
French AndroidTrainer}
Animateme !
If you don't do it for me,
do it for chet !
Demonstration !
The tutorial
Animation is life
Animationis comprehension
Animation is engagements
Animation is delightedyour UX
Animationis necessary
Animation is simple
Why Animation ?
Animations framework goals
Make Animations simple
Make Animation frameworks simple
Make Animation more simplethan that
Make Animation frameworks so simplethat a 6 years oldkids can use it
It's still not simplest enough,keep simplifyingit.
Animations frameworks's goals?
Because we wantyou to animate your
application !
Animations frameworks's goals?
Animations
Elementary Principles
AlphaRotate
Translate
Scale
And the plantransformations are yours
What we know: Tween Animations V1
<set
android:interpolator="@[package:]anim/interpolator_resource">
<alpha
android:duration="float"
android:fromAlpha="float" android:toAlpha="float" />
<scale
android:duration="float"
android:fromXScale="float" android:toXScale="float"
android:fromYScale="float" android:toYScale="float"
android:pivotX="float" android:pivotY="float" />
<translate
android:duration="float"
android:fromXDelta="float" android:toXDelta="float"
android:fromYDelta="float" android:toYDelta="float" />
<rotate
android:duration="float"
android:fromDegrees="float" android:toDegrees="float"
android:pivotX="float" android:pivotY="float" />
<set>
...
</set>
</set>
Animation animIn= AnimationUtils.loadAnimation(ctx, R.anim.generic_anim);
edtMessage.startAnimation(animIn);
animation/generic_anim.xml
Onlychange the pixels notthe state of the view
Makes animations generic
What we know:ObjectAnimator V11
/** * The in Animation for after HC */
AnimatorSet animInHC;
animInHC = (AnimatorSet) AnimatorInflater.loadAnimator(ctx, R.animator.generic_anim);
animInHC.setTarget(edtMessage);
animInHC.setTarget(btnAdd);
animInHC.start();
<set >
<objectAnimator
android:duration="1000"
android:propertyName="translationX"
android:valueFrom="-250"
android:valueTo="0"
android:valueType="floatType" />
<objectAnimator
android:duration="1000"
android:propertyName="scaleX"
android:valueFrom="0.0"
android:valueTo="1.0"
android:valueType="floatType" />
</set>
animator-v11/generic_anim.xml
Changes the state of the object
Uses Handler and Runnable
Simplebut dangerous(memory leak, runsin UIthread, can generates frames drops)
Not optimized
Animation: Elementary Principles
Animationis changingthe view/objectstate by droppingchanges inthe UI thread
Handler clipDrawableHandler=new Handler();
Runnable clipDrawableRunnable=new Runnable() {
@Override
public void run() {
myView.changeSomething(level);
clipDrawableHandler.postDelayed(clipDrawableRunnable,32);
}
};
V1
Handler clipDrawableHandler=new Handler();
Runnable clipDrawableRunnable=new Runnable() {
@Override
public void run() {
myView.changeSomething(level);
clipDrawableHandler.postDelayed(clipDrawableRunnable,32);
}
};
Uses Handler and Runnable
Simplebut dangerous(memory leak, runsin UIthread, can generates frames drops)
Not optimized
Animation: Elementary Principles V11
Animationis changingthe view/objectstate by droppingchanges inthe UI thread
Handler clipDrawableHandler=new Handler();
Runnable clipDrawableRunnable=new Runnable() {
@Override
public void run() {
myView.changeSomething(level);
clipDrawableHandler.postDelayed(clipDrawableRunnable,32);
}
};
Uses Handler and Runnable
Simplebut dangerous(memory leak, runsin UIthread, can generates frames drops)
Not optimized
Animation: Elementary Principles V11
Animationis changingthe view/objectstate by droppingchanges inthe UI thread
Make movement real :
Interpolators are simple
Don't be scared, it's simple.
How do yougofrom the pointAto the pointB?
Interpolator V1
t1
t0
v0
v1
A
B
?
i(t)=v,
where i(t0)=v0
and i(t1)=v1
float
time
It can be straight
Interpolartor V1
t1
t0
v0
v1
from
to
linear
Youcan use the system's ones
Interpolartor V1
t1
t0
v0
v1
from
to
deceleration
t1
t0
v0
v1
acceleration
to
from
t1
t0
v0
v1
to
bouncing
from
<set android:interpolator=
"@android:anim/accelerate_interpolator">
<set android:interpolator=
"@android:anim/decelerate_interpolator">
<set android:interpolator=
"@android:anim/bounce_interpolator">
Or buildyour own.
Interpolartor V1
t1
t0
v0
v1
from
to
alcoholic
public class MyInterpolator implements Interpolator {
float v;
@Override
public float getInterpolation(float input) {
//v=i(input)
return v;
}
}
Drawables are your best friends
Think Drawable
myDrawable= (ImageView)findViewById(R.id.imvToto).getDrawable();
<ImageView
android:id="@+id/imvToto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:src="@drawable/my_drawable"/>
V
1
ClipDrawable
RotateDrawable
ScaleDrawable
AnimationDrawable
StateListDrawable
AnimatedStateListDrawable
TransitionDrawable
AnimatedVectorDrawable
ThinkDrawable
Handler clipDrawableHandler=new Handler();
Runnable clipDrawableRunnable=new Runnable() {
@Override
public void run() {level++;
clipDrawableHorizontal.setLevel(level);
clipDrawableHandler.postDelayed(clipDrawableRunnable,32);
}
};
<?xml version="1.0" encoding="utf-8"?>
<clip xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/ic_android2ee"
android:clipOrientation="horizontal"
android:gravity="left" />
V1
Think Drawable
RotateDrawable rotateDrawableWheel;
Handler rotateDrawableHandler=new Handler();
Runnable rotateDrawableRunnable=new Runnable() {
public void run() {level++;
rotateDrawableWheel.setLevel(level);
rotateDrawableHandler.postDelayed(rotateDrawableRunnable,32);
}
};
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/ic_android2ee"
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="360" />
V
1
ClipDrawable
RotateDrawable
ScaleDrawable
AnimationDrawable
StateListDrawable
AnimatedStateListDraw
able
TransitionDrawable
AnimatedVectorDrawabl
e
Think Drawable
ScaleDrawable scaleDrawable;
Handler scaleDrawableHandler=new Handler();
Runnable scaleDrawableRunnable=new Runnable() {
public void run() {level++;
scaleDrawable.setLevel(level);
scaleDrawableHandler.postDelayed(scaleeDrawableRunnable,32);
}
};
<?xml version="1.0" encoding="utf-8"?>
<scale
xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@mipmap/ic_edit"
android:scaleGravity="center"
android:scaleHeight="100%"
android:scaleWidth="100%" />
V
1
ClipDrawable
RotateDrawable
ScaleDrawable
AnimationDrawable
StateListDrawable
AnimatedStateListDraw
able
TransitionDrawable
AnimatedVectorDrawabl
e
Think Drawable
animationDrawable.start();
<animation-list
android:id="@+id/selected" android:oneshot="false">
<item android:drawable="@drawable/attack_magic1"
android:duration="100" />
<item android:drawable="@drawable/attack_magic2"
android:duration="100" />
<item android:drawable="@drawable/attack_magic3"
android:duration="100" />
<item android:drawable="@drawable/attack_magic4"
android:duration="100" />
</animation-list>
V
1
ClipDrawable
RotateDrawable
ScaleDrawable
AnimationDrawable
StateListDrawable
AnimatedStateListDraw
able
TransitionDrawable
AnimatedVectorDrawabl
e
Think Drawable
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
android:enterFadeDuration="300"
android:exitFadeDuration="300">
<!--Sorry below v21 there is no animated selector
you can just fade in and fade out-->
<item android:id="@+id/item_pressed"
android:state_pressed="true">
<bitmap android:src="@drawable/ic_android2ee"/></item>
<item android:id="@+id/item_normal">
<bitmap android:src="@drawable/ic_nut"/> </item>
</selector>
fade fade
Norma
l
Press
ed
Norma
l
View
state
Displ
ay
V
1
ClipDrawable
RotateDrawable
ScaleDrawable
AnimationDrawable
StateListDrawable
AnimatedStateListDraw
able
TransitionDrawable
AnimatedVectorDrawabl
e
<?xml version="1.0" encoding="utf-8"?>
<animated-selector >
<item android:id="@+id/item_pressed"
android:state_pressed="true">
<bitmap android:src="@drawable/ic_android2ee"/></item>
<item android:id="@+id/item_normal">
<bitmap android:src="@drawable/ic_nut"/> </item>
<transition android:fromId="@+id/item_pressed"
android:toId="@+id/item_normal">
<animation-list android:id="@+id/selected"
android:oneshot="true">
<item android:drawable="@drawable/attack_magic1"
android:duration="100" />
<item android:drawable="@drawable/attack_magic2"
android:duration="100" />
</animation-list></transition></animated-selector>
Think Drawable V21
Norma
l
Press
ed
Norma
l
View
state
Displ
ay
ClipDrawable
RotateDrawable
ScaleDrawable
AnimationDrawable
StateListDrawable
AnimatedStateListDraw
able
TransitionDrawable
AnimatedVectorDrawabl
e
Think Drawable
transitionDrawable.startTransition(3000);
transitionDrawable.reverseTransition(3000);
<?xml version="1.0" encoding="utf-8"?>
<transition
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@mipmap/ic_ok" />
<item android:drawable="@mipmap/ic_nok" />
</transition>
V
1
ClipDrawable
RotateDrawable
ScaleDrawable
AnimationDrawable
StateListDrawable
AnimatedStateListDraw
able
TransitionDrawable
AnimatedVectorDrawabl
e
AnimatedVectorDrawable: Animate Shape
<?xml version="1.0" encoding="utf-8"?>
<vector
android:viewportWidth="500"
android:viewportHeight="500"
android:width="500px"
android:height="500px">
<!--Make group to animate them
separately using ObjectAnimator-->
<!--Define the pivot in the group they
will be used by ObjectAnimator-->
<group android:name="tete"
android:pivotX="250.0"
android:pivotY="100.0">
<path
android:name="head"
android:fillColor="#9FBF3B"
android:pathData="..." />
</group>...</vector>
<?xml version="1.0" encoding="utf-8"?>
<animated-vector
android:drawable="@drawable/my_svg" >
<target
android:name="tete"
android:animation="@anim/anim_svg"
/>
</animated-vector>
<?xml version="1.0" encoding="utf-8"?>
<set
xmlns:android="http://schemas.android.com/ap
k/res/android">
<!-- res/anim/rotation.xml -->
<objectAnimator
android:duration="6000"
android:propertyName="rotation"
android:valueFrom="0"
android:valueTo="360" />
</set>
drawable/my_svg drawable/my_svg_animated anim/anim_svg
use
use
layout/my_view
use
<ImageView
android:id="@+id/imvAnimatedVector"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:src="@drawable/my_svg_animated"/>
V21
RotateDrawable
ScaleDrawable
AnimationDrawable
StateListDrawable
AnimatedStateListDraw
able
TransitionDrawable
animatedVectorDrawable.start();
AnimatedVectorDrawable: Morph between
shapes
<?xml version="1.0" encoding="utf-8"?>
<vector
android:viewportWidth="500"
android:viewportHeight="500"
android:width="500px"
android:height="500px">
<!--Make group to animate them
separately using ObjectAnimator-->
<!--Define the pivot in the group they
will be used by ObjectAnimator-->
<group android:name="tete"
android:pivotX="250.0"
android:pivotY="100.0">
<path
android:name="head"
android:fillColor="#9FBF3B"
android:pathData="..." />
</group>...</vector>
<?xml version="1.0" encoding="utf-8"?>
<animated-vector
android:drawable="@drawable/my_svg" >
<target
android:name="tete"
android:animation="@anim/animpath_svg"
/>
</animated-vector>
<?xml version="1.0" encoding="utf-8"?>
<set >
<!-- res/anim/rotation.xml -->
<objectAnimator
android:duration="6000"
android:propertyName="pathData"
android:valueFrom="M300,70 l 0,-70
70,70 0,0 -70,70z"
android:valueTo="M300,70 l 0,-70
70,0 0,140 -70,0 z"
android:valueType="pathType"/>
</set>
drawable/my_svg drawable/my_svg_animated anim/animpath_svg
use
use
layout/my_view
use
<ImageView
android:id="@+id/imvAnimatedVector2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:src="@drawable/my_svg_animated"/>
V21
RotateDrawable
ScaleDrawable
AnimationDrawable
StateListDrawable
AnimatedStateListDraw
able
TransitionDrawable
animatedVectorDrawable.start();
The constraints that killfor path transformation:
"Note that the paths must be compatible for morphing.In more details, the paths shouldhave
exact same lengthof commands , and exact same lengthof parameters for each commands."
It means: youwon't use it expect for so simpletrick (arrow to hamburger).
=>Waiting for tools !
AnimatedVectorDrawable: constrained V21
And here it is !!!
https://github.com/bonnyfone/vectalign
AnimatedVectorDrawable: constrained V21
Others best friends
Animations is simple
Make it simple and magic:
Youcan animate any view
translationX ,translationY, rotationX, rotationY, rotation, scaleX, scaleY, pivotX,pivotY,
x,y,alphaand more
with onelineof code!
myView.animate().setDuration(300).x(20).rotationY(60).start();
ViewPropertyAnimator V13
myView.animate().rotation(360);
is equivalent to
ObjectAnimator.ofFloat(myView, "rotation", 0f, 360f).start();
ViewPropertyAnimator is based on ObjectAnimator V13
Makes animations simple,magic and generic
ObjectAnimator Demystify V13
First extends what youwant
(Objector View or what ever)
public class BlueDot extends View {
ObjectAnimator Demistify V13
Define the propertyto animate
using set/*MyProperty*/
public class BlueDot extends View {
/** * The property to animate *
* @param parameter value of the state to calculate the animation of the object
*/
private void setToto(int parameter) {
/*Do your stuff,
(call invalidate to redraw view)*/
ObjectAnimator Demystify V13
Then animate
public class BlueDot extends View {
/** * The property to animate *
@param parameter value of the state to calculate the animation of the object */
private void setToto(int parameter) {/*Do your stuff,(call invalidate to redraw view)*/
ObjectAnimator.ofInt(blueDot, "toto", 0, 110)
.start();
ObjectAnimator Demystify V13
ClipDrawable
ObjectAnimator Demystify
Handler clipDrawableHandler=new Handler();
Runnable clipDrawableRunnable=new Runnable() {
@Override
public void run() {level++;
clipDrawableHorizontal.setLevel(level);
clipDrawableHandler.postDelayed(clipDrawableRunnable,32);
}
};
<?xml version="1.0" encoding="utf-8"?>
<clip xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/ic_android2ee"
android:clipOrientation="horizontal"
android:gravity="left" />
V1
It was before
Works with every think !
Works with every think !
public class MyActivity extends Activity{
private void setMoveDrawable(int level){
clipDrawableHorizontal.setLevel(level); }
private void animateDrawable() {
ObjectAnimator.ofInt(this, "MoveDrawable", 0, 10000)
.start(); }
ObjectAnimator Demystify V13
Works with every think !
public class MyActivity extends Activity{
private void setMoveDrawable(int level){
clipDrawableHorizontal.setLevel(level); }
private void animateDrawable() {
ObjectAnimator.ofInt(this, "MoveDrawable", 0, 10000)
.start(); }
ObjectAnimator Demystify V13
Another old trick :PageTransformer
4
Animation: ViewPager V13
Demonstration !
View Pager
Animation: ViewFlipper (basics)
4
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.view.ViewPager
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/viewpager"
android:background="#FF00F0F0">
</android.support.v4.view.ViewPager>
public class MainActivity extends ActionBarActivity {
private MyPagerAdapter pagerAdapter;
private ViewPager viewPager;
@Override
protected void onCreate(Bundle savedInstanceState) {
...
//instanciate the PageAdapter
pagerAdapter=new MyPagerAdapter(this);
//Find the viewPager
viewPager = (ViewPager) super.findViewById(R.id.viewpager);
// Affectation de l'adapter au ViewPager
viewPager.setAdapter(pagerAdapter);
}
V13
Animation: ViewFlipper (basics)
4
public class MyPagerAdapter extends FragmentPagerAdapter {
private final ArrayList<Fragment> fragments;
public MyPagerAdapter(ActionBarActivity ctx) {
super(ctx.getSupportFragmentManager());
fragments = new ArrayList<Fragment>();
//A stuff I never did before, instanciate my fragment
Fragment frag =new MyFragment1();
fragments.add(frag);...
}
public Fragment getItem(int position) { return fragments.get(position); }
public int getCount() {return fragments.size(); }
public float getPageWidth (int position) {
//this is used to disaplyed the view a little bit smaller than
// it is really so you can see the right and the left view around the central view
return 0.93f;
}
}
V13
Animation: ViewPager adding Animation
4
//instanciate the PageAdapter
pagerAdapter=new MyPagerAdapter(this);
//Find the viewPager
viewPager = (ViewPager) super.findViewById(R.id.viewpager);
// Affectation de l'adapter au ViewPager
viewPager.setAdapter(pagerAdapter);
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.HONEYCOMB){
viewPager.setPageTransformer(true, new PageTransformer(this));
}
V13
Animation: ViewPager
4
public class PageTransformer implements ViewPager.PageTransformer {
public void transformPage(View view, float position) {
//Only the main layout is passed here
pageWidth = view.getWidth();
if (position < -1) // This page is way off-screen to the left.
view.setAlpha(0);
} else if (position <= 1) { //this page is displayed on the screen
if (position < 0) {
left(view, position);
} else {
right(view, position);
}
} else // This page is way off-screen to the right.
view.setAlpha(0);
}
}
V13
Animation: ViewFlipper
5
Also works with views
You don't need fragments.
V13
Brand new simplifications
Demonstration !
Sceneand transition
One xmllineto add
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/llSceneRoot"
android:animateLayoutChanges="true"
>
Animation: Scene et Transition v16
One xmllineto add
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/llSceneRoot"
android:animateLayoutChanges="true"
>
Animation: Scene et Transition v16
One lineof code to add
if(postICS){
LayoutTransition transition = ((ViewGroup)findViewById(R.id.llSceneRoot)).getLayoutTransition();
// New capability as of Jellybean; monitor the container for *all* layout changes
// (not just add/remove/visibility changes) and animate these changes as well.(==size)
transition.enableTransitionType(LayoutTransition.CHANGING);
}
Demonstration !
Activities transitions
Youhave the choicebetween
Custom animation
Animation: Activities/Fragments Transition v16v8
Intent slidingActivity = new Intent(this, SlidingActivity.class);
ActivityCompat.startActivity(this, slidingActivity, translationBundle);}
Bundle translationBundle = ActivityOptionsCompat.makeCustomAnimation(this,
R.anim.anim_push_left_in_a2ee,R.anim.anim_push_left_out_a2ee).toBundle();
Youhave the choicebetween
Custom animation
Scaling Component
Animation: Activities/Fragments Transition v16v8
Intent slidingActivity = new Intent(this, SlidingActivity.class);
ActivityCompat.startActivity(this, slidingActivity, translationBundle);}
Bundle translationBundle = ActivityOptionsCompat.makeCustomAnimation(this,
R.anim.anim_push_left_in_a2ee,R.anim.anim_push_left_out_a2ee).toBundle();
Bundle translationBundle =
ActivityOptionsCompat.makeScaleUpAnimation(btnScaling,0,0,btnScaling.getWidth(
),btnScaling.getHeight() ).toBundle();
Youhave the choicebetween:
Custom animation
Scaling Component
Scaling bitmap
Animation: Activities/Fragments Transition v16v8
Intent slidingActivity = new Intent(this, SlidingActivity.class);
ActivityCompat.startActivity(this, slidingActivity, translationBundle);}
Bundle translationBundle = ActivityOptionsCompat.makeCustomAnimation(this,
R.anim.anim_push_left_in_a2ee,R.anim.anim_push_left_out_a2ee).toBundle();
Bundle translationBundle =
ActivityOptionsCompat.makeScaleUpAnimation(btnScaling,0,0,btnScaling.getWidth(
),btnScaling.getHeight() ).toBundle();
Bundle translationBundle =
ActivityOptionsCompat.makeThumbnailScaleUpAnimation(imvSmiley,bitmap,0,0)
.toBundle();
Youhave the choicebetween:
Custom animation
Scaling Component
Scaling bitmap
You needto reverse:
Animation: Activities/Fragments Transition v16v8
public class otherActivity extends Activity {
public void finish() {
super.finish();
//this work for all version superior to level 5
overridePendingTransition(R.anim.anim_push_right_in_a2ee,
R.anim.anim_push_right_out_a2ee);
}}
Awesome
First manage your theme
Animation: new Activity Transition v21
<resources>
<!-- Thanks to :-->
<!-- http://code.tutsplus.com/tutorials/introduction-to-the-new-lollipop-activity-
transitions&#45;&#45;cms-23711-->
<!-- Base application theme. -->
<style name="AppTheme" parent="BaseTheme">
<!-- Set the transition between activities effective -->
<item name="android:windowContentTransitions">true</item>
<item name="android:windowEnterTransition">@android:transition/slide_bottom</item>
<item name="android:windowExitTransition">@android:transition/slide_bottom</item>
<item name="android:windowAllowEnterTransitionOverlap">true</item>
<item name="android:windowAllowReturnTransitionOverlap">true</item>
<item name="android:windowSharedElementEnterTransition">@android:transition/move</item>
<item name="android:windowSharedElementExitTransition">@android:transition/move</item>
</style>
</resources>
Set the android:transitionName to your components
Animation: new Activity Transition v21
<ImageButton
android:id="@+id/ibtnSprite"
android:transitionName="@string/imvSprite_transition"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_gravity="center"
android:src="@drawable/attack_magic_animation"
/>
<ImageView
android:id="@+id/imvSprite"
android:transitionName="@string/imvSprite_transition"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/attack_magic_animation"
/>
layout/main_activity layout/other_activity
Make yourpairs and launchthe new Activity
Animation: new Activity Transition v21
if (isPostLollipop) {
ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(
this,
new Pair<View, String>(imvSprites, getString(R.string.imvSprite_transition)),
);
}
ActivityCompat.startActivity(MainActivity.this, intent, options.toBundle());
}
Tips
How to get the screen size ?
Get screen size
@SuppressLint("NewApi")
private void getViewSize() {
//this is an usual trick when we want to know the dimension of our view
//initialize dimensions of the view
WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
if (postICS) {
Point size = new Point();
display.getSize(size);
width = size.x;
height = size.y;
} else {
width = display.getWidth(); // deprecated
height = display.getHeight(); // deprecated
}
}
V1
Whencustomizing youview, youhave to overwrite the followingmethod:
Get custom view size
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
this.w = w;
this.h = h;
centerX = w / 2;
centerY = h / 2;
//...}
V1
Use the ViewTreeObserver
Get view size
private void getEditButtonWidth() {
//this is an usual trick when we want to know the dimension of the elements of our view
//find the dimension of the EditButton
ViewTreeObserver vto = btnEdit.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
btnEdit.getViewTreeObserver().removeGlobalOnLayoutListener(this);
btnEditWidth = btnEdit.getMeasuredWidth();
}
});
}
V1
Use the LayoutParameter of the ViewGroup
Changecomponents size
private void changeImvSprite1Size(){
//Change the LayoutParameter to change the size of view
if(isImvSprite1Expended){
imvSprite1.setLayoutParams(imvSpritesLayoutParamNormal);
}else{
imvSprite1.setLayoutParams(imvSpritesLayoutParamExpanded);
}
isImvSprite1Expended=!isImvSprite1Expended;
}
V1
private void initializeImvSpriteSize() {
//get the real size of the components
imvSprite1Height = imvSprite1.getMeasuredHeight();
//initialize the layout parameter for the normal size
imvSpritesLayoutParamNormal = new LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, imvSprite1Height);
//initialize the layout parameter for the expanded size
imvSpritesLayoutParamExpanded= new LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, 2*imvSprite1Height);}
private LinearLayout.LayoutParams imvSpritesLayoutParamNormal, imvSpritesLayoutParamExpanded ;
Invalidate and dirtyArea
or layoutRequest
Redraw V1
Make yourownpaint :
Make rainbow paint
Paint dotPaint= new Paint();
//initialize the shader (stuff that make the color of the paint depending on
// the location in the screen and a set of colors)
//@chiuki at droidcon london
int[] rainbow = getRainbowColors();
Shader shader = new LinearGradient(0, 0, 0, w, rainbow,
null, Shader.TileMode.MIRROR);
Matrix matrix = new Matrix();
matrix.setRotate(90);
shader.setLocalMatrix(matrix);
dotPaint.setShader(shader);
V1
private int[] getRainbowColors() {
return new int[]{
getResources().getColor(R.color.rainbow_red),
getResources().getColor(R.color.rainbow_yellow),
getResources().getColor(R.color.rainbow_green),
getResources().getColor(R.color.rainbow_turquoise),
getResources().getColor(R.color.rainbow_blue),
getResources().getColor(R.color.rainbow_purple)
};}
Question ?
#android2ee
mathias.seguy@android2ee.com
www.android2ee.com
Code:
https://github.com/MathiasSeguy-Android2EEAndroid2EE
@android2ee
Thank you!
droidcon Greece Thessaloniki
MathiasSeguy
Slides:
http://fr.slideshare.net/Android2EE

Contenu connexe

En vedette

(Computer) Animation Technique
(Computer) Animation Technique(Computer) Animation Technique
(Computer) Animation Technique
justinesolano
 
Computer Animation PowerPoint
Computer Animation PowerPointComputer Animation PowerPoint
Computer Animation PowerPoint
oacore2
 
Conférence "Architecture Android" du 19 Mars 2013 par Mathias Seguy fondateur...
Conférence "Architecture Android" du 19 Mars 2013 par Mathias Seguy fondateur...Conférence "Architecture Android" du 19 Mars 2013 par Mathias Seguy fondateur...
Conférence "Architecture Android" du 19 Mars 2013 par Mathias Seguy fondateur...
Mathias Seguy
 

En vedette (14)

Mise en place de l'ActionBarCompat dans vos projets Android.
Mise en place de l'ActionBarCompat dans vos projets Android.Mise en place de l'ActionBarCompat dans vos projets Android.
Mise en place de l'ActionBarCompat dans vos projets Android.
 
Android2EE training: Tutorials list of Android projects
Android2EE training: Tutorials list of Android projectsAndroid2EE training: Tutorials list of Android projects
Android2EE training: Tutorials list of Android projects
 
Treatment, Architecture and Threads
Treatment, Architecture and ThreadsTreatment, Architecture and Threads
Treatment, Architecture and Threads
 
Présentation et bonnes pratiques du pattern MVVM - MIC Belgique
Présentation et bonnes pratiques du pattern MVVM - MIC BelgiquePrésentation et bonnes pratiques du pattern MVVM - MIC Belgique
Présentation et bonnes pratiques du pattern MVVM - MIC Belgique
 
Architecture et Bonnes pratiques Android #DevoxxFr2016 Part1
Architecture et Bonnes pratiques Android #DevoxxFr2016 Part1Architecture et Bonnes pratiques Android #DevoxxFr2016 Part1
Architecture et Bonnes pratiques Android #DevoxxFr2016 Part1
 
Architecture et Bonnes pratiques Android #DevoxxFr2016 Part2
Architecture et Bonnes pratiques Android #DevoxxFr2016 Part2Architecture et Bonnes pratiques Android #DevoxxFr2016 Part2
Architecture et Bonnes pratiques Android #DevoxxFr2016 Part2
 
2d Animation Syllabus & Activities
2d Animation Syllabus & Activities2d Animation Syllabus & Activities
2d Animation Syllabus & Activities
 
Creating Animated PPT presentations
Creating Animated PPT presentationsCreating Animated PPT presentations
Creating Animated PPT presentations
 
Animation Techniques
Animation TechniquesAnimation Techniques
Animation Techniques
 
(Computer) Animation Technique
(Computer) Animation Technique(Computer) Animation Technique
(Computer) Animation Technique
 
Grade 10 arts q3&q4
Grade 10 arts q3&q4Grade 10 arts q3&q4
Grade 10 arts q3&q4
 
ANIMATION PPT
ANIMATION PPTANIMATION PPT
ANIMATION PPT
 
Computer Animation PowerPoint
Computer Animation PowerPointComputer Animation PowerPoint
Computer Animation PowerPoint
 
Conférence "Architecture Android" du 19 Mars 2013 par Mathias Seguy fondateur...
Conférence "Architecture Android" du 19 Mars 2013 par Mathias Seguy fondateur...Conférence "Architecture Android" du 19 Mars 2013 par Mathias Seguy fondateur...
Conférence "Architecture Android" du 19 Mars 2013 par Mathias Seguy fondateur...
 

Similaire à Animate me, If you don't do it for me do it for Chet :)

Crafting interactions with Core Animations, David Ortinau
Crafting interactions with Core Animations, David OrtinauCrafting interactions with Core Animations, David Ortinau
Crafting interactions with Core Animations, David Ortinau
Xamarin
 

Similaire à Animate me, If you don't do it for me do it for Chet :) (20)

How to Create Custom Animations in Flutter – A Step-by-Step Guide.pdf
How to Create Custom Animations in Flutter – A Step-by-Step Guide.pdfHow to Create Custom Animations in Flutter – A Step-by-Step Guide.pdf
How to Create Custom Animations in Flutter – A Step-by-Step Guide.pdf
 
Seven Peaks Speaks - Android Jetpack Compose Animation
Seven Peaks Speaks - Android Jetpack Compose AnimationSeven Peaks Speaks - Android Jetpack Compose Animation
Seven Peaks Speaks - Android Jetpack Compose Animation
 
Constraint-ly motion - making your app dance - John Hoford, Google
Constraint-ly motion - making your app dance - John Hoford, GoogleConstraint-ly motion - making your app dance - John Hoford, Google
Constraint-ly motion - making your app dance - John Hoford, Google
 
Project Prague & RealSense: il potere nelle mani!!
Project Prague & RealSense: il potere nelle mani!!Project Prague & RealSense: il potere nelle mani!!
Project Prague & RealSense: il potere nelle mani!!
 
Project Gesture & RealSense: gestures in a simple way!!
Project Gesture & RealSense: gestures in a simple way!!Project Gesture & RealSense: gestures in a simple way!!
Project Gesture & RealSense: gestures in a simple way!!
 
slides-export.pdf
slides-export.pdfslides-export.pdf
slides-export.pdf
 
Android view animation in android-chapter18
Android view animation in android-chapter18Android view animation in android-chapter18
Android view animation in android-chapter18
 
ARM: Enhancing your Unity mobile VR experience
ARM: Enhancing your Unity mobile VR experienceARM: Enhancing your Unity mobile VR experience
ARM: Enhancing your Unity mobile VR experience
 
Basic Android Animation
Basic Android Animation Basic Android Animation
Basic Android Animation
 
Android animation in android-chapter17
Android animation in android-chapter17Android animation in android-chapter17
Android animation in android-chapter17
 
Major_Project_Group 03_KIIT-1.pptx
Major_Project_Group 03_KIIT-1.pptxMajor_Project_Group 03_KIIT-1.pptx
Major_Project_Group 03_KIIT-1.pptx
 
Project Gesture & Real Sense: il potere nelle mani!!
Project Gesture & Real Sense: il potere nelle mani!!Project Gesture & Real Sense: il potere nelle mani!!
Project Gesture & Real Sense: il potere nelle mani!!
 
Crafting interactions with Core Animations, David Ortinau
Crafting interactions with Core Animations, David OrtinauCrafting interactions with Core Animations, David Ortinau
Crafting interactions with Core Animations, David Ortinau
 
Traffic sign detection and recognition
Traffic sign detection and recognitionTraffic sign detection and recognition
Traffic sign detection and recognition
 
Lec 1 intro
Lec 1 introLec 1 intro
Lec 1 intro
 
Postmortem of a uwp xaml application development
Postmortem of a uwp xaml application developmentPostmortem of a uwp xaml application development
Postmortem of a uwp xaml application development
 
CSS3 Animations & Transitions with PhoneGap
CSS3 Animations & Transitions with PhoneGapCSS3 Animations & Transitions with PhoneGap
CSS3 Animations & Transitions with PhoneGap
 
Ch07
Ch07Ch07
Ch07
 
Om Pawar MP AJP.docx
Om Pawar MP AJP.docxOm Pawar MP AJP.docx
Om Pawar MP AJP.docx
 
Motion Layout - Easy animations for everyone
Motion Layout - Easy animations for everyoneMotion Layout - Easy animations for everyone
Motion Layout - Easy animations for everyone
 

Dernier

IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
Enterprise Knowledge
 

Dernier (20)

Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 

Animate me, If you don't do it for me do it for Chet :)

  • 1. 10-12 September 2015 droidcon Greece Thessaloniki
  • 2. Animate me ! #AnimateMe by(Mathias Seguy== Android2EE){ French AndroidTrainer}
  • 3. Animateme ! If you don't do it for me, do it for chet !
  • 5. Animation is life Animationis comprehension Animation is engagements Animation is delightedyour UX Animationis necessary Animation is simple Why Animation ?
  • 7. Make Animations simple Make Animation frameworks simple Make Animation more simplethan that Make Animation frameworks so simplethat a 6 years oldkids can use it It's still not simplest enough,keep simplifyingit. Animations frameworks's goals?
  • 8. Because we wantyou to animate your application ! Animations frameworks's goals?
  • 10. AlphaRotate Translate Scale And the plantransformations are yours What we know: Tween Animations V1 <set android:interpolator="@[package:]anim/interpolator_resource"> <alpha android:duration="float" android:fromAlpha="float" android:toAlpha="float" /> <scale android:duration="float" android:fromXScale="float" android:toXScale="float" android:fromYScale="float" android:toYScale="float" android:pivotX="float" android:pivotY="float" /> <translate android:duration="float" android:fromXDelta="float" android:toXDelta="float" android:fromYDelta="float" android:toYDelta="float" /> <rotate android:duration="float" android:fromDegrees="float" android:toDegrees="float" android:pivotX="float" android:pivotY="float" /> <set> ... </set> </set> Animation animIn= AnimationUtils.loadAnimation(ctx, R.anim.generic_anim); edtMessage.startAnimation(animIn); animation/generic_anim.xml Onlychange the pixels notthe state of the view
  • 11. Makes animations generic What we know:ObjectAnimator V11 /** * The in Animation for after HC */ AnimatorSet animInHC; animInHC = (AnimatorSet) AnimatorInflater.loadAnimator(ctx, R.animator.generic_anim); animInHC.setTarget(edtMessage); animInHC.setTarget(btnAdd); animInHC.start(); <set > <objectAnimator android:duration="1000" android:propertyName="translationX" android:valueFrom="-250" android:valueTo="0" android:valueType="floatType" /> <objectAnimator android:duration="1000" android:propertyName="scaleX" android:valueFrom="0.0" android:valueTo="1.0" android:valueType="floatType" /> </set> animator-v11/generic_anim.xml Changes the state of the object
  • 12. Uses Handler and Runnable Simplebut dangerous(memory leak, runsin UIthread, can generates frames drops) Not optimized Animation: Elementary Principles Animationis changingthe view/objectstate by droppingchanges inthe UI thread Handler clipDrawableHandler=new Handler(); Runnable clipDrawableRunnable=new Runnable() { @Override public void run() { myView.changeSomething(level); clipDrawableHandler.postDelayed(clipDrawableRunnable,32); } }; V1
  • 13. Handler clipDrawableHandler=new Handler(); Runnable clipDrawableRunnable=new Runnable() { @Override public void run() { myView.changeSomething(level); clipDrawableHandler.postDelayed(clipDrawableRunnable,32); } }; Uses Handler and Runnable Simplebut dangerous(memory leak, runsin UIthread, can generates frames drops) Not optimized Animation: Elementary Principles V11 Animationis changingthe view/objectstate by droppingchanges inthe UI thread
  • 14. Handler clipDrawableHandler=new Handler(); Runnable clipDrawableRunnable=new Runnable() { @Override public void run() { myView.changeSomething(level); clipDrawableHandler.postDelayed(clipDrawableRunnable,32); } }; Uses Handler and Runnable Simplebut dangerous(memory leak, runsin UIthread, can generates frames drops) Not optimized Animation: Elementary Principles V11 Animationis changingthe view/objectstate by droppingchanges inthe UI thread
  • 15. Make movement real : Interpolators are simple
  • 16. Don't be scared, it's simple. How do yougofrom the pointAto the pointB? Interpolator V1 t1 t0 v0 v1 A B ? i(t)=v, where i(t0)=v0 and i(t1)=v1 float time
  • 17. It can be straight Interpolartor V1 t1 t0 v0 v1 from to linear
  • 18. Youcan use the system's ones Interpolartor V1 t1 t0 v0 v1 from to deceleration t1 t0 v0 v1 acceleration to from t1 t0 v0 v1 to bouncing from <set android:interpolator= "@android:anim/accelerate_interpolator"> <set android:interpolator= "@android:anim/decelerate_interpolator"> <set android:interpolator= "@android:anim/bounce_interpolator">
  • 19. Or buildyour own. Interpolartor V1 t1 t0 v0 v1 from to alcoholic public class MyInterpolator implements Interpolator { float v; @Override public float getInterpolation(float input) { //v=i(input) return v; } }
  • 20. Drawables are your best friends
  • 22. ClipDrawable RotateDrawable ScaleDrawable AnimationDrawable StateListDrawable AnimatedStateListDrawable TransitionDrawable AnimatedVectorDrawable ThinkDrawable Handler clipDrawableHandler=new Handler(); Runnable clipDrawableRunnable=new Runnable() { @Override public void run() {level++; clipDrawableHorizontal.setLevel(level); clipDrawableHandler.postDelayed(clipDrawableRunnable,32); } }; <?xml version="1.0" encoding="utf-8"?> <clip xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/ic_android2ee" android:clipOrientation="horizontal" android:gravity="left" /> V1
  • 23. Think Drawable RotateDrawable rotateDrawableWheel; Handler rotateDrawableHandler=new Handler(); Runnable rotateDrawableRunnable=new Runnable() { public void run() {level++; rotateDrawableWheel.setLevel(level); rotateDrawableHandler.postDelayed(rotateDrawableRunnable,32); } }; <?xml version="1.0" encoding="utf-8"?> <rotate xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/ic_android2ee" android:fromDegrees="0" android:pivotX="50%" android:pivotY="50%" android:toDegrees="360" /> V 1 ClipDrawable RotateDrawable ScaleDrawable AnimationDrawable StateListDrawable AnimatedStateListDraw able TransitionDrawable AnimatedVectorDrawabl e
  • 24. Think Drawable ScaleDrawable scaleDrawable; Handler scaleDrawableHandler=new Handler(); Runnable scaleDrawableRunnable=new Runnable() { public void run() {level++; scaleDrawable.setLevel(level); scaleDrawableHandler.postDelayed(scaleeDrawableRunnable,32); } }; <?xml version="1.0" encoding="utf-8"?> <scale xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@mipmap/ic_edit" android:scaleGravity="center" android:scaleHeight="100%" android:scaleWidth="100%" /> V 1 ClipDrawable RotateDrawable ScaleDrawable AnimationDrawable StateListDrawable AnimatedStateListDraw able TransitionDrawable AnimatedVectorDrawabl e
  • 25. Think Drawable animationDrawable.start(); <animation-list android:id="@+id/selected" android:oneshot="false"> <item android:drawable="@drawable/attack_magic1" android:duration="100" /> <item android:drawable="@drawable/attack_magic2" android:duration="100" /> <item android:drawable="@drawable/attack_magic3" android:duration="100" /> <item android:drawable="@drawable/attack_magic4" android:duration="100" /> </animation-list> V 1 ClipDrawable RotateDrawable ScaleDrawable AnimationDrawable StateListDrawable AnimatedStateListDraw able TransitionDrawable AnimatedVectorDrawabl e
  • 26. Think Drawable <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android" android:enterFadeDuration="300" android:exitFadeDuration="300"> <!--Sorry below v21 there is no animated selector you can just fade in and fade out--> <item android:id="@+id/item_pressed" android:state_pressed="true"> <bitmap android:src="@drawable/ic_android2ee"/></item> <item android:id="@+id/item_normal"> <bitmap android:src="@drawable/ic_nut"/> </item> </selector> fade fade Norma l Press ed Norma l View state Displ ay V 1 ClipDrawable RotateDrawable ScaleDrawable AnimationDrawable StateListDrawable AnimatedStateListDraw able TransitionDrawable AnimatedVectorDrawabl e
  • 27. <?xml version="1.0" encoding="utf-8"?> <animated-selector > <item android:id="@+id/item_pressed" android:state_pressed="true"> <bitmap android:src="@drawable/ic_android2ee"/></item> <item android:id="@+id/item_normal"> <bitmap android:src="@drawable/ic_nut"/> </item> <transition android:fromId="@+id/item_pressed" android:toId="@+id/item_normal"> <animation-list android:id="@+id/selected" android:oneshot="true"> <item android:drawable="@drawable/attack_magic1" android:duration="100" /> <item android:drawable="@drawable/attack_magic2" android:duration="100" /> </animation-list></transition></animated-selector> Think Drawable V21 Norma l Press ed Norma l View state Displ ay ClipDrawable RotateDrawable ScaleDrawable AnimationDrawable StateListDrawable AnimatedStateListDraw able TransitionDrawable AnimatedVectorDrawabl e
  • 28. Think Drawable transitionDrawable.startTransition(3000); transitionDrawable.reverseTransition(3000); <?xml version="1.0" encoding="utf-8"?> <transition xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@mipmap/ic_ok" /> <item android:drawable="@mipmap/ic_nok" /> </transition> V 1 ClipDrawable RotateDrawable ScaleDrawable AnimationDrawable StateListDrawable AnimatedStateListDraw able TransitionDrawable AnimatedVectorDrawabl e
  • 29. AnimatedVectorDrawable: Animate Shape <?xml version="1.0" encoding="utf-8"?> <vector android:viewportWidth="500" android:viewportHeight="500" android:width="500px" android:height="500px"> <!--Make group to animate them separately using ObjectAnimator--> <!--Define the pivot in the group they will be used by ObjectAnimator--> <group android:name="tete" android:pivotX="250.0" android:pivotY="100.0"> <path android:name="head" android:fillColor="#9FBF3B" android:pathData="..." /> </group>...</vector> <?xml version="1.0" encoding="utf-8"?> <animated-vector android:drawable="@drawable/my_svg" > <target android:name="tete" android:animation="@anim/anim_svg" /> </animated-vector> <?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/ap k/res/android"> <!-- res/anim/rotation.xml --> <objectAnimator android:duration="6000" android:propertyName="rotation" android:valueFrom="0" android:valueTo="360" /> </set> drawable/my_svg drawable/my_svg_animated anim/anim_svg use use layout/my_view use <ImageView android:id="@+id/imvAnimatedVector" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:src="@drawable/my_svg_animated"/> V21 RotateDrawable ScaleDrawable AnimationDrawable StateListDrawable AnimatedStateListDraw able TransitionDrawable animatedVectorDrawable.start();
  • 30. AnimatedVectorDrawable: Morph between shapes <?xml version="1.0" encoding="utf-8"?> <vector android:viewportWidth="500" android:viewportHeight="500" android:width="500px" android:height="500px"> <!--Make group to animate them separately using ObjectAnimator--> <!--Define the pivot in the group they will be used by ObjectAnimator--> <group android:name="tete" android:pivotX="250.0" android:pivotY="100.0"> <path android:name="head" android:fillColor="#9FBF3B" android:pathData="..." /> </group>...</vector> <?xml version="1.0" encoding="utf-8"?> <animated-vector android:drawable="@drawable/my_svg" > <target android:name="tete" android:animation="@anim/animpath_svg" /> </animated-vector> <?xml version="1.0" encoding="utf-8"?> <set > <!-- res/anim/rotation.xml --> <objectAnimator android:duration="6000" android:propertyName="pathData" android:valueFrom="M300,70 l 0,-70 70,70 0,0 -70,70z" android:valueTo="M300,70 l 0,-70 70,0 0,140 -70,0 z" android:valueType="pathType"/> </set> drawable/my_svg drawable/my_svg_animated anim/animpath_svg use use layout/my_view use <ImageView android:id="@+id/imvAnimatedVector2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:src="@drawable/my_svg_animated"/> V21 RotateDrawable ScaleDrawable AnimationDrawable StateListDrawable AnimatedStateListDraw able TransitionDrawable animatedVectorDrawable.start();
  • 31. The constraints that killfor path transformation: "Note that the paths must be compatible for morphing.In more details, the paths shouldhave exact same lengthof commands , and exact same lengthof parameters for each commands." It means: youwon't use it expect for so simpletrick (arrow to hamburger). =>Waiting for tools ! AnimatedVectorDrawable: constrained V21
  • 32. And here it is !!! https://github.com/bonnyfone/vectalign AnimatedVectorDrawable: constrained V21
  • 34. Make it simple and magic: Youcan animate any view translationX ,translationY, rotationX, rotationY, rotation, scaleX, scaleY, pivotX,pivotY, x,y,alphaand more with onelineof code! myView.animate().setDuration(300).x(20).rotationY(60).start(); ViewPropertyAnimator V13
  • 35. myView.animate().rotation(360); is equivalent to ObjectAnimator.ofFloat(myView, "rotation", 0f, 360f).start(); ViewPropertyAnimator is based on ObjectAnimator V13
  • 36. Makes animations simple,magic and generic ObjectAnimator Demystify V13
  • 37. First extends what youwant (Objector View or what ever) public class BlueDot extends View { ObjectAnimator Demistify V13
  • 38. Define the propertyto animate using set/*MyProperty*/ public class BlueDot extends View { /** * The property to animate * * @param parameter value of the state to calculate the animation of the object */ private void setToto(int parameter) { /*Do your stuff, (call invalidate to redraw view)*/ ObjectAnimator Demystify V13
  • 39. Then animate public class BlueDot extends View { /** * The property to animate * @param parameter value of the state to calculate the animation of the object */ private void setToto(int parameter) {/*Do your stuff,(call invalidate to redraw view)*/ ObjectAnimator.ofInt(blueDot, "toto", 0, 110) .start(); ObjectAnimator Demystify V13
  • 40. ClipDrawable ObjectAnimator Demystify Handler clipDrawableHandler=new Handler(); Runnable clipDrawableRunnable=new Runnable() { @Override public void run() {level++; clipDrawableHorizontal.setLevel(level); clipDrawableHandler.postDelayed(clipDrawableRunnable,32); } }; <?xml version="1.0" encoding="utf-8"?> <clip xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/ic_android2ee" android:clipOrientation="horizontal" android:gravity="left" /> V1 It was before Works with every think !
  • 41. Works with every think ! public class MyActivity extends Activity{ private void setMoveDrawable(int level){ clipDrawableHorizontal.setLevel(level); } private void animateDrawable() { ObjectAnimator.ofInt(this, "MoveDrawable", 0, 10000) .start(); } ObjectAnimator Demystify V13
  • 42. Works with every think ! public class MyActivity extends Activity{ private void setMoveDrawable(int level){ clipDrawableHorizontal.setLevel(level); } private void animateDrawable() { ObjectAnimator.ofInt(this, "MoveDrawable", 0, 10000) .start(); } ObjectAnimator Demystify V13
  • 43. Another old trick :PageTransformer
  • 46. Animation: ViewFlipper (basics) 4 activity_main.xml <?xml version="1.0" encoding="utf-8"?> <android.support.v4.view.ViewPager android:layout_width="fill_parent" android:layout_height="fill_parent" android:id="@+id/viewpager" android:background="#FF00F0F0"> </android.support.v4.view.ViewPager> public class MainActivity extends ActionBarActivity { private MyPagerAdapter pagerAdapter; private ViewPager viewPager; @Override protected void onCreate(Bundle savedInstanceState) { ... //instanciate the PageAdapter pagerAdapter=new MyPagerAdapter(this); //Find the viewPager viewPager = (ViewPager) super.findViewById(R.id.viewpager); // Affectation de l'adapter au ViewPager viewPager.setAdapter(pagerAdapter); } V13
  • 47. Animation: ViewFlipper (basics) 4 public class MyPagerAdapter extends FragmentPagerAdapter { private final ArrayList<Fragment> fragments; public MyPagerAdapter(ActionBarActivity ctx) { super(ctx.getSupportFragmentManager()); fragments = new ArrayList<Fragment>(); //A stuff I never did before, instanciate my fragment Fragment frag =new MyFragment1(); fragments.add(frag);... } public Fragment getItem(int position) { return fragments.get(position); } public int getCount() {return fragments.size(); } public float getPageWidth (int position) { //this is used to disaplyed the view a little bit smaller than // it is really so you can see the right and the left view around the central view return 0.93f; } } V13
  • 48. Animation: ViewPager adding Animation 4 //instanciate the PageAdapter pagerAdapter=new MyPagerAdapter(this); //Find the viewPager viewPager = (ViewPager) super.findViewById(R.id.viewpager); // Affectation de l'adapter au ViewPager viewPager.setAdapter(pagerAdapter); if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.HONEYCOMB){ viewPager.setPageTransformer(true, new PageTransformer(this)); } V13
  • 49. Animation: ViewPager 4 public class PageTransformer implements ViewPager.PageTransformer { public void transformPage(View view, float position) { //Only the main layout is passed here pageWidth = view.getWidth(); if (position < -1) // This page is way off-screen to the left. view.setAlpha(0); } else if (position <= 1) { //this page is displayed on the screen if (position < 0) { left(view, position); } else { right(view, position); } } else // This page is way off-screen to the right. view.setAlpha(0); } } V13
  • 50. Animation: ViewFlipper 5 Also works with views You don't need fragments. V13
  • 54. One xmllineto add <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/llSceneRoot" android:animateLayoutChanges="true" > Animation: Scene et Transition v16 One lineof code to add if(postICS){ LayoutTransition transition = ((ViewGroup)findViewById(R.id.llSceneRoot)).getLayoutTransition(); // New capability as of Jellybean; monitor the container for *all* layout changes // (not just add/remove/visibility changes) and animate these changes as well.(==size) transition.enableTransitionType(LayoutTransition.CHANGING); }
  • 56. Youhave the choicebetween Custom animation Animation: Activities/Fragments Transition v16v8 Intent slidingActivity = new Intent(this, SlidingActivity.class); ActivityCompat.startActivity(this, slidingActivity, translationBundle);} Bundle translationBundle = ActivityOptionsCompat.makeCustomAnimation(this, R.anim.anim_push_left_in_a2ee,R.anim.anim_push_left_out_a2ee).toBundle();
  • 57. Youhave the choicebetween Custom animation Scaling Component Animation: Activities/Fragments Transition v16v8 Intent slidingActivity = new Intent(this, SlidingActivity.class); ActivityCompat.startActivity(this, slidingActivity, translationBundle);} Bundle translationBundle = ActivityOptionsCompat.makeCustomAnimation(this, R.anim.anim_push_left_in_a2ee,R.anim.anim_push_left_out_a2ee).toBundle(); Bundle translationBundle = ActivityOptionsCompat.makeScaleUpAnimation(btnScaling,0,0,btnScaling.getWidth( ),btnScaling.getHeight() ).toBundle();
  • 58. Youhave the choicebetween: Custom animation Scaling Component Scaling bitmap Animation: Activities/Fragments Transition v16v8 Intent slidingActivity = new Intent(this, SlidingActivity.class); ActivityCompat.startActivity(this, slidingActivity, translationBundle);} Bundle translationBundle = ActivityOptionsCompat.makeCustomAnimation(this, R.anim.anim_push_left_in_a2ee,R.anim.anim_push_left_out_a2ee).toBundle(); Bundle translationBundle = ActivityOptionsCompat.makeScaleUpAnimation(btnScaling,0,0,btnScaling.getWidth( ),btnScaling.getHeight() ).toBundle(); Bundle translationBundle = ActivityOptionsCompat.makeThumbnailScaleUpAnimation(imvSmiley,bitmap,0,0) .toBundle();
  • 59. Youhave the choicebetween: Custom animation Scaling Component Scaling bitmap You needto reverse: Animation: Activities/Fragments Transition v16v8 public class otherActivity extends Activity { public void finish() { super.finish(); //this work for all version superior to level 5 overridePendingTransition(R.anim.anim_push_right_in_a2ee, R.anim.anim_push_right_out_a2ee); }}
  • 60. Awesome First manage your theme Animation: new Activity Transition v21 <resources> <!-- Thanks to :--> <!-- http://code.tutsplus.com/tutorials/introduction-to-the-new-lollipop-activity- transitions&#45;&#45;cms-23711--> <!-- Base application theme. --> <style name="AppTheme" parent="BaseTheme"> <!-- Set the transition between activities effective --> <item name="android:windowContentTransitions">true</item> <item name="android:windowEnterTransition">@android:transition/slide_bottom</item> <item name="android:windowExitTransition">@android:transition/slide_bottom</item> <item name="android:windowAllowEnterTransitionOverlap">true</item> <item name="android:windowAllowReturnTransitionOverlap">true</item> <item name="android:windowSharedElementEnterTransition">@android:transition/move</item> <item name="android:windowSharedElementExitTransition">@android:transition/move</item> </style> </resources>
  • 61. Set the android:transitionName to your components Animation: new Activity Transition v21 <ImageButton android:id="@+id/ibtnSprite" android:transitionName="@string/imvSprite_transition" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_alignParentTop="true" android:layout_gravity="center" android:src="@drawable/attack_magic_animation" /> <ImageView android:id="@+id/imvSprite" android:transitionName="@string/imvSprite_transition" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:src="@drawable/attack_magic_animation" /> layout/main_activity layout/other_activity
  • 62. Make yourpairs and launchthe new Activity Animation: new Activity Transition v21 if (isPostLollipop) { ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation( this, new Pair<View, String>(imvSprites, getString(R.string.imvSprite_transition)), ); } ActivityCompat.startActivity(MainActivity.this, intent, options.toBundle()); }
  • 63. Tips
  • 64. How to get the screen size ? Get screen size @SuppressLint("NewApi") private void getViewSize() { //this is an usual trick when we want to know the dimension of our view //initialize dimensions of the view WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE); Display display = wm.getDefaultDisplay(); if (postICS) { Point size = new Point(); display.getSize(size); width = size.x; height = size.y; } else { width = display.getWidth(); // deprecated height = display.getHeight(); // deprecated } } V1
  • 65. Whencustomizing youview, youhave to overwrite the followingmethod: Get custom view size protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); this.w = w; this.h = h; centerX = w / 2; centerY = h / 2; //...} V1
  • 66. Use the ViewTreeObserver Get view size private void getEditButtonWidth() { //this is an usual trick when we want to know the dimension of the elements of our view //find the dimension of the EditButton ViewTreeObserver vto = btnEdit.getViewTreeObserver(); vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { btnEdit.getViewTreeObserver().removeGlobalOnLayoutListener(this); btnEditWidth = btnEdit.getMeasuredWidth(); } }); } V1
  • 67. Use the LayoutParameter of the ViewGroup Changecomponents size private void changeImvSprite1Size(){ //Change the LayoutParameter to change the size of view if(isImvSprite1Expended){ imvSprite1.setLayoutParams(imvSpritesLayoutParamNormal); }else{ imvSprite1.setLayoutParams(imvSpritesLayoutParamExpanded); } isImvSprite1Expended=!isImvSprite1Expended; } V1 private void initializeImvSpriteSize() { //get the real size of the components imvSprite1Height = imvSprite1.getMeasuredHeight(); //initialize the layout parameter for the normal size imvSpritesLayoutParamNormal = new LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, imvSprite1Height); //initialize the layout parameter for the expanded size imvSpritesLayoutParamExpanded= new LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, 2*imvSprite1Height);} private LinearLayout.LayoutParams imvSpritesLayoutParamNormal, imvSpritesLayoutParamExpanded ;
  • 68. Invalidate and dirtyArea or layoutRequest Redraw V1
  • 69. Make yourownpaint : Make rainbow paint Paint dotPaint= new Paint(); //initialize the shader (stuff that make the color of the paint depending on // the location in the screen and a set of colors) //@chiuki at droidcon london int[] rainbow = getRainbowColors(); Shader shader = new LinearGradient(0, 0, 0, w, rainbow, null, Shader.TileMode.MIRROR); Matrix matrix = new Matrix(); matrix.setRotate(90); shader.setLocalMatrix(matrix); dotPaint.setShader(shader); V1 private int[] getRainbowColors() { return new int[]{ getResources().getColor(R.color.rainbow_red), getResources().getColor(R.color.rainbow_yellow), getResources().getColor(R.color.rainbow_green), getResources().getColor(R.color.rainbow_turquoise), getResources().getColor(R.color.rainbow_blue), getResources().getColor(R.color.rainbow_purple) };}
  • 71. Code: https://github.com/MathiasSeguy-Android2EEAndroid2EE @android2ee Thank you! droidcon Greece Thessaloniki MathiasSeguy Slides: http://fr.slideshare.net/Android2EE