Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.

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

1 371 vues

Publié le

This is the slide of the conference gave at the DroidCon Greece 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
  • Soyez le premier à commenter

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

  1. 1. 10-12 September 2015 droidcon Greece Thessaloniki
  2. 2. Animate me ! #AnimateMe by(Mathias Seguy== Android2EE){ French AndroidTrainer}
  3. 3. Animateme ! If you don't do it for me, do it for chet !
  4. 4. Demonstration ! The tutorial
  5. 5. Animation is life Animationis comprehension Animation is engagements Animation is delightedyour UX Animationis necessary Animation is simple Why Animation ?
  6. 6. Animations framework goals
  7. 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. 8. Because we wantyou to animate your application ! Animations frameworks's goals?
  9. 9. Animations Elementary Principles
  10. 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. 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. 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. 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. 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. 15. Make movement real : Interpolators are simple
  16. 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. 17. It can be straight Interpolartor V1 t1 t0 v0 v1 from to linear
  18. 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. 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. 20. Drawables are your best friends
  21. 21. 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
  22. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 32. And here it is !!! https://github.com/bonnyfone/vectalign AnimatedVectorDrawable: constrained V21
  33. 33. Others best friends Animations is simple
  34. 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. 35. myView.animate().rotation(360); is equivalent to ObjectAnimator.ofFloat(myView, "rotation", 0f, 360f).start(); ViewPropertyAnimator is based on ObjectAnimator V13
  36. 36. Makes animations simple,magic and generic ObjectAnimator Demystify V13
  37. 37. First extends what youwant (Objector View or what ever) public class BlueDot extends View { ObjectAnimator Demistify V13
  38. 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. 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. 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. 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. 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. 43. Another old trick :PageTransformer
  44. 44. 4 Animation: ViewPager V13
  45. 45. Demonstration ! View Pager
  46. 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. 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. 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. 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. 50. Animation: ViewFlipper 5 Also works with views You don't need fragments. V13
  51. 51. Brand new simplifications
  52. 52. Demonstration ! Sceneand transition
  53. 53. 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
  54. 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); }
  55. 55. Demonstration ! Activities transitions
  56. 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. 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. 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. 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. 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--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. 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. 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. 63. Tips
  64. 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. 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. 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. 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. 68. Invalidate and dirtyArea or layoutRequest Redraw V1
  69. 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) };}
  70. 70. Question ? #android2ee mathias.seguy@android2ee.com www.android2ee.com
  71. 71. Code: https://github.com/MathiasSeguy-Android2EEAndroid2EE @android2ee Thank you! droidcon Greece Thessaloniki MathiasSeguy Slides: http://fr.slideshare.net/Android2EE

×