0

I am using RotateAnimation to animate pointing arrow that updates its position when of user updates destination point or current device position changes. I'm using interpolator.accelerate_decelerate to make animation look more smooth and "physical".

Everything goes fine until another update arrives when current animation is still processing, for example, when user changes destination while pointing arrow is still rotating. When such happens, the arrow makes a sharp bounce which looks ugly, and I'm trying to avoid this. I tried to implement a queue to make every next animation wait until previous ends and it looks nice, but behavior became quite illogical.

So my questions are following:

1) is there some way to make animated transitions more smooth in the cases when animations start one by one and overlap each other?

2) is there a way to stop animation that is currently processing and get intermediate position of an object?--if I decide to stop animation before its end and use current position as starting point for next animation.

Alex Salauyou
  • 14,185
  • 5
  • 45
  • 67
  • 1
    extend RotateAnimation and override its applyTransformation then after calling super.applyTransformation save Transformation matrix, this matrix is used for rotation – pskink Mar 29 '14 at 14:01
  • or just use this https://github.com/android/platform_frameworks_base/blob/master/core/java/android/view/animation/RotateAnimation.java in your project and save "degrees" in applyTransformation – pskink Mar 29 '14 at 14:17
  • @pskink thank you so much for giving me a starting point! Now I'm looking at the source code to discover how animations are performed in Android--to fine tune them for my needs (e. g. implement dumped oscillator equation to make my arrow move more 'physically') – Alex Salauyou Mar 29 '14 at 14:23
  • use custom Interpolator in that case – pskink Mar 29 '14 at 14:26
  • @pskink I tried custom interpolator, but it doesn't help in case of overlapping... if only I could rebuild transformation matrix every time animation looper access it, it would help, but it is quite hard to discover how to implement it. I will try – Alex Salauyou Mar 29 '14 at 14:33
  • every time the animation is drawn its applyTransformation is called, so save the current rotation there and use it when starting the new animation, this way you will have no jumps – pskink Mar 29 '14 at 14:52
  • @pskink Looking at the source code I discovered that every time a `ViewGroup` is going to redraw its invalidated chlidren (I suppose this happens on every cycle of some draw looper), it invokes `getTransformation` method of every child's animation object. There, all calculations are proceeded, so overriding this method I create a custom `Animation` object to implement any kind of realtime physical behavior. Thanks indeed! I would like to select your answer as the best, but in comments I cannot do this =( – Alex Salauyou Mar 29 '14 at 15:33
  • see http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.3_r1/android/view/animation/Animation.java, line 772 where time is interpolated by a Interpolator and the next line where applyTransformation is called, every Animation (RotateAnimation, ScaleAnimation, AlphaAnimation etc) overrides this method so your own should do it too – pskink Mar 29 '14 at 15:51
  • @pskink yep I saw this, but `applyTransformation` operates with abstract normalized time 0...1 and animation duration must be defined, but I want it to long as long as needed, for example, when the arrow is rotating by big angle, transition will take more time etc. Overriding `getTransformation` gives me possibility to work in real time coordinates. – Alex Salauyou Mar 29 '14 at 16:11
  • for that infinite Animation isnt it better to create a custom View instead of custom Animation? – pskink Mar 29 '14 at 16:20
  • @yes this is also a good idea. I believe I can easily implement it calling `invalidate` and `setRotation` every time Android calls `onDraw` of this view. – Alex Salauyou Mar 29 '14 at 16:30
  • if you choose a custom View with some Bitmap to draw there is a nice method Canvas.drawBitmap(Bitmap, Matrix, Paint), good luck – pskink Mar 29 '14 at 16:37

2 Answers2

1

ok so the easiest is to create a custom Animation similar to RotateAnimation and saving the current rotation angle in applyTransformation, this angle can be then used as a start angle for next Animation thus avoiding the "jumps"

pskink
  • 23,874
  • 6
  • 66
  • 77
0

A custom class extending ImageView that performs animation based on angular movement of dipole in magnetic field:

https://stackoverflow.com/a/22738030/3459206

Community
  • 1
  • 1
Alex Salauyou
  • 14,185
  • 5
  • 45
  • 67