#AnimateMe
by(Mathias Seguy== Android2EE){
French AndroidTrainer}
If you don't do it for me,
do it for chet !
Demonstration !
Animation is life
Animation is comprehension
Animation is engagements
Animationis delightedyour UX
Animation is necessary
...
Make Animations simple
Because we wantyou to animate your
application !
Alpha
Rotate
Translate
Scale
And the plantransformations are yours
V1
<set
android:interpolator="@[package:]anim/interpola...
Makes animations generic
V11
/** * The in Animation for after HC */
AnimatorSet animInHC;
animInHC = (AnimatorSet) Animato...
Uses Handler and Runnable
Simplebut dangerous(memory leak, runsin UIthread, can generates frames drops)
Not optimized
Anim...
Uses Handler and Runnable
Simplebut dangerous(memory leak, runsin UIthread, can generates frames drops)
Not optimized
V11
...
Don't be scared, it's simple.
How doyougofrom the pointfromto the pointto?
V1
t1t0
v0
v1
from
to
?
i(t)=v,
where i(t0)=v0
...
It can be straight
V1
t1t0
v0
v1
from
to
linear
t1t0
v0
v1
Youcan use the system's ones
V1
t1t0
v0
v1
from
to
deceleration acceleration
to
from
t1t0
v0
v1
to
bouncing
fro...
Or buildyour own.
V1
t1t0
v0
v1
from
to
alcoholic
public class MyInterpolator implements Interpolator {
float v;
@Override...
myDrawable= (ImageView)findViewById(R.id.imvToto).getDrawable();
<ImageView
android:id="@+id/imvToto"
android:layout_width...
ClipDrawable
RotateDrawable
ScaleDrawable
AnimationDrawable
TransitionDrawable
StateListDrawable
AnimatedStateListDrawable...
RotateDrawable rotateDrawableWheel;
Handler rotateDrawableHandler=new Handler();
Runnable rotateDrawableRunnable=new Runna...
ScaleDrawable scaleDrawable;
Handler scaleDrawableHandler=new Handler();
Runnable scaleDrawableRunnable=new Runnable() {
p...
animationDrawable.start();
<animation-list
android:id="@+id/selected" android:oneshot="false">
<item android:drawable="@dr...
transitionDrawable.startTransition(3000);
transitionDrawable.reverseTransition(3000);
<?xml version="1.0" encoding="utf-8"...
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
android:enterF...
<?xml version="1.0" encoding="utf-8"?>
<animated-selector >
<item android:id="@+id/item_pressed"
android:state_pressed="tr...
<?xml version="1.0" encoding="utf-8"?>
<vector
android:viewportWidth="500"
android:viewportHeight="500"
android:width="500...
<?xml version="1.0" encoding="utf-8"?>
<vector
android:viewportWidth="500"
android:viewportHeight="500"
android:width="500...
The constraints that killfor path transformation:
"Note thatthe paths must be compatiblefor morphing.In more details, the ...
And here it is !!!
https://github.com/bonnyfone/vectalign
V21
To create Svg and/orsimplify them
https://inkscape.org/
To convert Svg intoVectorDrawable
http://inloop.github.io/svg2andr...
Make it simple and magic:
Youcan animate any view
translationX ,translationY, rotationX, rotationY, rotation, scaleX, scal...
myView.animate().rotation(360);
is equivalent to
ObjectAnimator.ofFloat(myView, "rotation", 0f, 360f).start();
V13
Makes animations simple,magic and generic
V13
First extends what youwant
(Object or View or what ever)
public class BlueDot extends View {
V13
Define the propertyto animate
usingset/*MyProperty*/
public class BlueDot extends View {
/** * The property to animate *
*...
Then animate
public class BlueDot extends View {
/** * The property to animate *
@param parameter value of the state to ca...
ClipDrawable
Handler clipDrawableHandler=new Handler();
Runnable clipDrawableRunnable=new Runnable() {
@Override
public vo...
Works with every think !
public class MyActivity extends Activity{
private void setMoveDrawable(int level){
clipDrawableHo...
Demonstration !
v16
One xmllineto add
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/...
One xmllineto add
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/...
v16v8
Youhave the choicebetween
Custom animation
Intent slidingActivity = new Intent(this, SlidingActivity.class);
ActivityCompa...
Youhave the choicebetween
Custom animation
Scaling Component
Intent slidingActivity = new Intent(this, SlidingActivity.cla...
Youhave the choicebetween:
Custom animation
ScalingComponent
Scaling bitmap
Intent slidingActivity = new Intent(this, Slid...
Youhave the choicebetween:
Custom animation
ScalingComponent
Scaling bitmap
You need to reverse :
public class otherActivi...
Awesome
First manage your theme
<resources>
<!-- Thanks to :-->
<!-- http://code.tutsplus.com/tutorials/introduction-to-th...
Set the android:transitionName to your components
<ImageButton
android:id="@+id/ibtnSprite"
android:transitionName="@strin...
Make your pairs and launch the new Activity
if (isPostLollipop) {
ActivityOptionsCompat options = ActivityOptionsCompat.ma...
V7
53
V7
54
dependencies {
...
compile 'com.android.support:recyclerview-v7:23.0.1'
<!-- A RecyclerView with some commonly used att...
55
RecyclerView
Adapter
ViewHolder
LayoutManager
ItemAnimator ItemDecorator
ItemView management
(ClickListener,Animation.....
56
Its the natural evolution of the ListView, the ViewHolder is the one responsible of the view management
public View onC...
57
This is the same code as for the ListView (ViewHolder next slide)
public class RecyclerViewAdapter extends
RecyclerView...
58
This is the same code as for the ListView (ViewHolder next slide)
public class RecyclerViewAdapter extends
RecyclerView...
59
Le ViewHolder gère la vue qu'il encapsule
public class ViewHolder extends RecyclerView.ViewHolder{
TextView txvName=nul...
60
Le LinearLayoutManager
public RecyclerView.LayoutManager getLayoutManager() {
return new LinearLayoutManager(getContext...
61
Le StaggeredLayoutManager
public RecyclerView.LayoutManager getLayoutManager() {
StaggeredGridLayoutManager stagLayoutM...
62
Le GridLayoutManager
public RecyclerView.LayoutManager getLayoutManager() {
GridLayoutManager gridLayoutManager=new Gri...
63
V7
64
dependencies {
...
compile 'com.android.support:design:23.0.1'
V7
65
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools...
V7
66
<android.support.design.widget.CoordinatorLayout >
<android.support.design.widget.AppBarLayout
...
android:theme="@s...
V7
67
<android.support.design.widget.AppBarLayout
... >
<android.support.design.widget.CollapsingToolbarLayout
android:id=...
V7
68
<android.support.design.widget.AppBarLayout...>
<android.support.design.widget.CollapsingToolbarLayout...>
<ImageVie...
V7
69
<android.support.design.widget.AppBarLayout...>
<android.support.design.widget.CollapsingToolbarLayout...>
<ImageVie...
V7
71
<android.support.design.widget.AppBarLayout ... >
<android.support.design.widget.CollapsingToolbarLayout ... >
<Imag...
73
V13
Demonstration !
V13
75
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.view.ViewPager
android:layout_width="fill_...
76
public class MyPagerAdapter extends FragmentPagerAdapter {
private final ArrayList<Fragment> fragments;
public MyPagerA...
77
public class MainActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
.....
78
public class MyPageTransformer implements ViewPager.PageTransformer{
RecyclerView myRecyclerView;
public void transform...
First: Simplifyyour layout !!!
if not enoughyoucan also:
User LayerType Hardware accelerated
btnDoNotPress.setLayerType(Vi...
Use Interface andFactory
/** * The animation */
MainActivityAnimMother anim;
//the factory for the animations (you can
cre...
#android2ee
mathias.seguy@android2ee.com
www.android2ee.com
Code:
https://github.com/MathiasSeguy-Android2EE
Android2EE
@android2ee
Thank you!
MathiasSeguy
Slides:
http://fr.slidesha...
Animate Me, if you don't do it for me do it for chet (DroidCon Paris)
Animate Me, if you don't do it for me do it for chet (DroidCon Paris)
Animate Me, if you don't do it for me do it for chet (DroidCon Paris)
Animate Me, if you don't do it for me do it for chet (DroidCon Paris)
Animate Me, if you don't do it for me do it for chet (DroidCon Paris)
Animate Me, if you don't do it for me do it for chet (DroidCon Paris)
Animate Me, if you don't do it for me do it for chet (DroidCon Paris)
Prochain SlideShare
Chargement dans…5
×

Animate Me, if you don't do it for me do it for chet (DroidCon Paris)

1 177 vues

Publié le

This is the slide of the conference gave at the DroidCon Paris 2015 by Mathias Seguy.
The pitch:
Animation is a key point when building your application….
But, “Animation is complicated with Android”, is your feeling.
Well, in fact, it’s not. I will show you how simples they are, how magic they could be and how fun your application can become.
I will explains which animation to use for which version of the system, what are your choices and what is your strategy. We will have a complete overview on the Android Animation framework.
So I hope to see you in the room for this conference, because at the end, your application will be enhanced :)

Publié dans : Technologie
0 commentaire
0 j’aime
Statistiques
Remarques
  • Soyez le premier à commenter

  • Soyez le premier à aimer ceci

Aucun téléchargement
Vues
Nombre de vues
1 177
Sur SlideShare
0
Issues des intégrations
0
Intégrations
17
Actions
Partages
0
Téléchargements
11
Commentaires
0
J’aime
0
Intégrations 0
Aucune incorporation

Aucune remarque pour cette diapositive

Animate Me, if you don't do it for me do it for chet (DroidCon Paris)

  1. 1. #AnimateMe by(Mathias Seguy== Android2EE){ French AndroidTrainer}
  2. 2. If you don't do it for me, do it for chet !
  3. 3. Demonstration !
  4. 4. Animation is life Animation is comprehension Animation is engagements Animationis delightedyour UX Animation is necessary Animationis simple
  5. 5. Make Animations simple
  6. 6. Because we wantyou to animate your application !
  7. 7. Alpha Rotate Translate Scale And the plantransformations are yours 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 pixels notthe state of the view
  8. 8. Makes animations generic 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
  9. 9. Uses Handler and Runnable Simplebut dangerous(memory leak, runsin UIthread, can generates frames drops) Not optimized 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
  10. 10. Uses Handler and Runnable Simplebut dangerous(memory leak, runsin UIthread, can generates frames drops) Not optimized 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); } };
  11. 11. Don't be scared, it's simple. How doyougofrom the pointfromto the pointto? V1 t1t0 v0 v1 from to ? i(t)=v, where i(t0)=v0 and i(t1)=v1 float time
  12. 12. It can be straight V1 t1t0 v0 v1 from to linear
  13. 13. t1t0 v0 v1 Youcan use the system's ones V1 t1t0 v0 v1 from to deceleration acceleration to from t1t0 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" >
  14. 14. Or buildyour own. V1 t1t0 v0 v1 from to alcoholic public class MyInterpolator implements Interpolator { float v; @Override public float getInterpolation(float input) { //v=i(input) return v; }...}
  15. 15. 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"/> V1
  16. 16. ClipDrawable RotateDrawable ScaleDrawable AnimationDrawable TransitionDrawable StateListDrawable AnimatedStateListDrawable AnimatedVectorDrawable 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
  17. 17. 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" /> V1 ClipDrawable RotateDrawable ScaleDrawable AnimationDrawable TransitionDrawable StateListDrawable AnimatedStateListDrawable AnimatedVectorDrawable
  18. 18. 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%" /> V1 ClipDrawable RotateDrawable ScaleDrawable AnimationDrawable TransitionDrawable StateListDrawable AnimatedStateListDrawable AnimatedVectorDrawable
  19. 19. 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> ClipDrawable RotateDrawable ScaleDrawable AnimationDrawable TransitionDrawable StateListDrawable AnimatedStateListDrawable AnimatedVectorDrawable V1
  20. 20. 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> ClipDrawable RotateDrawable ScaleDrawable AnimationDrawable TransitionDrawable StateListDrawable AnimatedStateListDrawable AnimatedVectorDrawable V1
  21. 21. <?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 TransitionDrawable StateListDrawable AnimatedStateListDraw able AnimatedVectorDrawabl e
  22. 22. <?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> V21 Normal Pressed NormalView state Display ClipDrawable RotateDrawable ScaleDrawable AnimationDrawable TransitionDrawable StateListDrawable AnimatedStateListDrawable AnimatedVectorDrawable
  23. 23. <?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/apk/res/a ndroid"> <!-- 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 us e 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"/> animatedVectorDrawable.start(); V21 TransitionDrawable StateListDrawable AnimatedStateListDrawable AnimatedVectorDrawable
  24. 24. <?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 us e 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"/> animatedVectorDrawable.start(); V21 TransitionDrawable StateListDrawable AnimatedStateListDrawable AnimatedVectorDrawable
  25. 25. The constraints that killfor path transformation: "Note thatthe paths must be compatiblefor morphing.In more details, the pathsshouldhave exact same lengthof commands , and exact same lengthof parameters for each commands." It means: youwon't use it expectfor so simple trick (arrow to hamburger). =>Waiting for tools ! V21
  26. 26. And here it is !!! https://github.com/bonnyfone/vectalign V21
  27. 27. To create Svg and/orsimplify them https://inkscape.org/ To convert Svg intoVectorDrawable http://inloop.github.io/svg2android/ A goodpractice : Define your path in aString file (resvaluesmy_path_string.xml) V21 But even with that it's the hell on earth =>working ona Github project
  28. 28. Make it simple and magic: Youcan animate any view translationX ,translationY, rotationX, rotationY, rotation, scaleX, scaleY, pivotX,pivotY, x,y,alphaand more with one lineof code! myView.animate().setDuration(300).x(20).rotationY(60).start(); V13
  29. 29. myView.animate().rotation(360); is equivalent to ObjectAnimator.ofFloat(myView, "rotation", 0f, 360f).start(); V13
  30. 30. Makes animations simple,magic and generic V13
  31. 31. First extends what youwant (Object or View or what ever) public class BlueDot extends View { V13
  32. 32. Define the propertyto animate usingset/*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)*/ V13
  33. 33. 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(); V13
  34. 34. ClipDrawable 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" /> It was before Works with every think ! V13
  35. 35. 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(); } No moreHandler neither Runnable!!! yes thanks Chet ! V13
  36. 36. Demonstration ! v16
  37. 37. One xmllineto add <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/llSceneRoot" android:animateLayoutChanges="true" > v16
  38. 38. One xmllineto add <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/llSceneRoot" android:animateLayoutChanges="true" > One lineof codeto 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); } v16
  39. 39. v16v8
  40. 40. Youhave the choicebetween Custom animation Intent slidingActivity = new Intent(this, SlidingActivity.class); ActivityCompat.startActivity(this, slidingActivity, translationBundle);} v16v8 Bundle translationBundle = ActivityOptionsCompat.makeCustomAnimation(this, R.anim.anim_push_left_in_a2ee,R.anim.anim_push_left_out_a2ee).toBundle();
  41. 41. Youhave the choicebetween Custom animation Scaling Component Intent slidingActivity = new Intent(this, SlidingActivity.class); ActivityCompat.startActivity(this, slidingActivity, translationBundle);} v16v8 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();
  42. 42. Youhave the choicebetween: Custom animation ScalingComponent Scaling bitmap 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(); v16v8
  43. 43. Youhave the choicebetween: Custom animation ScalingComponent Scaling bitmap You need to reverse : 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); }} v16v8
  44. 44. Awesome First manage your theme <resources> <!-- Thanks to :--> <!-- http://code.tutsplus.com/tutorials/introduction-to-the-new-lollipop-activity-transitions--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> v21
  45. 45. Set the android:transitionName to your components <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 v21
  46. 46. Make your pairs and launch the new Activity if (isPostLollipop) { ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation( this, new Pair<View, String>(imvSprites, getString(R.string.imvSprite_transition)), ); } ActivityCompat.startActivity(MainActivity.this, intent, options.toBundle()); } v21
  47. 47. V7
  48. 48. 53 V7
  49. 49. 54 dependencies { ... compile 'com.android.support:recyclerview-v7:23.0.1' <!-- A RecyclerView with some commonly used attributes --> <android.support.v7.widget.RecyclerView android:id="@+id/my_recycler_view" android:scrollbars="vertical" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior" /> V7
  50. 50. 55 RecyclerView Adapter ViewHolder LayoutManager ItemAnimator ItemDecorator ItemView management (ClickListener,Animation...) dataSet V7
  51. 51. 56 Its the natural evolution of the ListView, the ViewHolder is the one responsible of the view management public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View myView=inflater.inflate(R.layout.recyclerview,container,false); recyclerView= (RecyclerView) myView.findViewById(R.id.my_recycler_view); // use a layout manager recyclerViewLayoutManager = getLayoutManager(); recyclerView.setLayoutManager(recyclerViewLayoutManager); // specify an adapter (see also next example) recyclerViewAdapter = new RecyclerViewAdapter(humans,getActivity()); recyclerView.setAdapter(recyclerViewAdapter); return myView ; } find the View set the LayoutManager set the Adapter V7
  52. 52. 57 This is the same code as for the ListView (ViewHolder next slide) public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder>{ /****Attributes (t for temp)**/ private ArrayList<Human> humans; private LayoutInflater inflater; private View tNewView; private ViewHolder tViewHolder; private Human tHuman; /****** Constructor**/ public RecyclerViewAdapter(ArrayList<Human> dataSet,Context ctx){ humans=dataSet; inflater=LayoutInflater.from(ctx); } @Override public RecyclerViewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { tNewView=inflater.inflate(R.layout.simple_item,parent,false); tViewHolder=new ViewHolder(tNewView); return tViewHolder; } @Override public void onBindViewHolder(RecyclerViewAdapter.ViewHolder holder, int position) { tHuman=humans.get(position); holder.getTxvName().setText(tHuman.getName()); holder.getTxvFirstName().setText(tHuman.getFirstName()); holder.getTxvMessage().setText(tHuman.getMessage()); } @Override public int getItemCount() { return humans.size(); } V7
  53. 53. 58 This is the same code as for the ListView (ViewHolder next slide) public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder>{ /****Attributes (t for temp)**/ private ArrayList<Human> humans; private LayoutInflater inflater; private View tNewView; private ViewHolder tViewHolder; private Human tHuman; /****** Constructor**/ public RecyclerViewAdapter(ArrayList<Human> dataSet,Context ctx){ humans=dataSet; inflater=LayoutInflater.from(ctx); } @Override public RecyclerViewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { tNewView=inflater.inflate(R.layout.simple_item,parent,false); tViewHolder=new ViewHolder(tNewView); return tViewHolder; } @Override public void onBindViewHolder(RecyclerViewAdapter.ViewHolder holder, int position) { tHuman=humans.get(position); holder.getTxvName().setText(tHuman.getName()); holder.getTxvFirstName().setText(tHuman.getFirstName()); holder.getTxvMessage().setText(tHuman.getMessage()); } @Override public int getItemCount() { return humans.size(); } Inflate the view and its viewHolder Return the ViewHolder Update the View using the ViewHolder Set your DataSet and your LayoutInflater V7
  54. 54. 59 Le ViewHolder gère la vue qu'il encapsule public class ViewHolder extends RecyclerView.ViewHolder{ TextView txvName=null; TextView txvFirstName=null; TextView txvMessage=null; View.OnClickListener clickListener; int position; public ViewHolder(View itemView) { super(itemView); txvName= (TextView) itemView.findViewById(R.id.txvName); txvFirstName= (TextView) itemView.findViewById(R.id.txvFirstName); txvMessage= (TextView) itemView.findViewById(R.id.txvMessage); clickListener=new View.OnClickListener() { public void onClick(View v) {changeTxvMessageVisibilityState(); } }; itemView.setOnClickListener(clickListener); } public TextView getTxvFirstName() {return txvFirstName;} public TextView getTxvMessage() {return txvMessage;} public TextView getTxvName() {return txvName;} public void changeTxvMessageVisibilityState(){ //Do the stuff } } V7
  55. 55. 60 Le LinearLayoutManager public RecyclerView.LayoutManager getLayoutManager() { return new LinearLayoutManager(getContext()); } V7
  56. 56. 61 Le StaggeredLayoutManager public RecyclerView.LayoutManager getLayoutManager() { StaggeredGridLayoutManager stagLayoutManager=new StaggeredGridLayoutManager(2,GridLayoutManager.VERTICAL); stagLayoutManager.setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS); return stagLayoutManager; } V7
  57. 57. 62 Le GridLayoutManager public RecyclerView.LayoutManager getLayoutManager() { GridLayoutManager gridLayoutManager=new GridLayoutManager(getContext(),2,GridLayoutManager.VERTICAL,false); //define specific span of specific cells according to a rule gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { @Override public int getSpanSize(int arg0) { return (arg0 % 3) == 0 ? 2 : 1; } }); return gridLayoutManager; } V7
  58. 58. 63 V7
  59. 59. 64 dependencies { ... compile 'com.android.support:design:23.0.1' V7
  60. 60. 65 <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".CoordinatorLayout"> The parent Layout of all yours Layouts: The CoordinatorLayout V7
  61. 61. V7 66 <android.support.design.widget.CoordinatorLayout > <android.support.design.widget.AppBarLayout ... android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"> <android.support.v7.widget.Toolbar ... app:layout_scrollFlags="scroll|enterAlways"/> <android.support.design.widget.TabLayout ... android:fillViewport="true"/> </android.support.design.widget.AppBarLayout> <android.support.v4.view.ViewPager //Your content ... app:layout_behavior="@string/appbar_scrolling_view_behavior" /> </android.support.design.widget.CoordinatorLayout >
  62. 62. V7 67 <android.support.design.widget.AppBarLayout ... > <android.support.design.widget.CollapsingToolbarLayout android:id="@+id/collapsing_toolbar" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_scrollFlags="scroll|exitUntilCollapsed" android:fitsSystemWindows="true" app:contentScrim="?attr/colorPrimary" app:expandedTitleMarginStart="48dp" app:expandedTitleMarginEnd="64dp"> <ImageView ... android:fitsSystemWindows="true" app:layout_collapseMode="parallax" /> <android.support.v7.widget.Toolbar ... app:layout_scrollFlags="scroll|enterAlways"/> <android.support.design.widget.TabLayout ... android:fillViewport="true"/> </android.support.design.widget.CollapsingToolbarLayout> </android.support.design.widget.AppBarLayout>
  63. 63. V7 68 <android.support.design.widget.AppBarLayout...> <android.support.design.widget.CollapsingToolbarLayout...> <ImageView.../> <android.support.design.widget.TabLayout .../> <android.support.v7.widget.Toolbar.../> </android.support.design.widget.CollapsingToolbarLayout> </android.support.design.widget.AppBarLayout> Set the title of the ActionBar on the CollapsingToolbarLayout not on the ToolBar!
  64. 64. V7 69 <android.support.design.widget.AppBarLayout...> <android.support.design.widget.CollapsingToolbarLayout...> <ImageView.../> <android.support.v7.widget.Toolbar.../> <android.support.design.widget.TabLayout .../> </android.support.design.widget.CollapsingToolbarLayout> </android.support.design.widget.AppBarLayout> s w it c h
  65. 65. V7 71 <android.support.design.widget.AppBarLayout ... > <android.support.design.widget.CollapsingToolbarLayout ... > <ImageView ... /> <android.support.v7.widget.Toolbar ... /> </android.support.design.widget.CollapsingToolbarLayout> <android.support.design.widget.TabLayout /> </android.support.design.widget.AppBarLayout> collapsingToolbar.setContentScrimResource(R.drawable.cardview_background_toolbar);
  66. 66. 73 V13
  67. 67. Demonstration ! V13
  68. 68. 75 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
  69. 69. 76 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(); } V13
  70. 70. 77 public class MainActivity extends ActionBarActivity { @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); if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.HONEYCOMB){ viewPager.setPageTransformer(true, new PageTransformer(this)); } V13
  71. 71. 78 public class MyPageTransformer implements ViewPager.PageTransformer{ RecyclerView myRecyclerView; public void transformPage(View view, float position) { //Only the main layout is passed here/ myRecyclerView= (RecyclerView) view.findViewById(R.id.my_recycler_view); if (position < -1) { // [-Infinity,-1)This page is way off-screen to the left. view.setAlpha(0); } else if (position < 1) { //in the visible range [-1,1] myRecyclerView.setAlpha(1-Math.abs(position)); view.setAlpha(1); if (position < 0) {//coming from left myRecyclerView.setRotationX((position * 360)); } else {//coming from right myRecyclerView.setRotationX(-1*position *360); } } else { // (1,+Infinity] // This page is way off-screen to the right. view.setAlpha(0); } }} V13
  72. 72. First: Simplifyyour layout !!! if not enoughyoucan also: User LayerType Hardware accelerated btnDoNotPress.setLayerType(View.LAYER_TYPE_HARDWARE,null); new Animator.AnimatorListener() { public void onAnimationEnd(Animator animation) { btnDoNotPress.setLayerType(View.LAYER_TYPE_NONE, null); } V1
  73. 73. Use Interface andFactory /** * The animation */ MainActivityAnimMother anim; //the factory for the animations (you can create a Class to do that if you want) : if(isPostLollipop){ anim=new MainActivityAnimLLP(); }else if(postICS){ anim=new MainActivityAnimICS(); }else{ anim=new MainActivityAnimGinger(); } V1 MainActivity MainActivity MainActivityAnimGinger MainActivityAnimICS MainActivityAnimLLP MainActivity MotherAnim MainActivityAnimIntf Animation code Animation attributes Animation methods declaration v21
  74. 74. #android2ee mathias.seguy@android2ee.com www.android2ee.com
  75. 75. Code: https://github.com/MathiasSeguy-Android2EE Android2EE @android2ee Thank you! MathiasSeguy Slides: http://fr.slideshare.net/Android2EE

×