I have some thoughts about animations from XML and dynamic values on attributes.
When animating activities, you are limited to animations defined in XML, either by specifying them in the theme or by using the Activity.overridePendingAnimations(int, int). There is no way of having any dynamic values in an animation defined in XML. For example it is not possible to define an animation in XML that animates an activity from a certain point on the screen depending on the current state of an activity (if you don't want one XML file for every possibly coordinate on the screen). A real example would be if you have a grid of images and you want to launch an image viewer activity that scales up from the image you just pressed.
I have been looking into different possible solutions to this problem and would appreciate some input.
1) XML variable substitution at parse time.
In the XML file you can add a variable name as a value to an attribute, which the parser will recognize and look up when parsing the XML file. Maybe have an overridePendingTransition(...) that takes a Bundle together with the resources and uses that bundle when looking up the variables. The XML file could for example contain something like this:
<translate android:fromXDelta="${fromX}" android:toXDelta="0" android:duration="1000" />
Where "${fromX}" will be recognized and the value of "fromX" will be fetched from the Bundle.
I have not yet tried this solution because I think it will have quite big impact on how the XML files are preprocessed and validated and I have no idea where to begin. But I think the solution itself is not that bad. The syntax in the XML maybe need to change, don't know what the rules of XML says.
2) XML attribute filter
When the XML file is parsed in AnimationUtils, Animation classes are created with an AttributeSet that points to the current tag in the XML file. Since AttributeSet is just an interface it is possible to crate a class that implements AttributeSet by wrapping another AttributeSet for all attributes except the once we want to replace. Which attributes to replace could be controlled by a Bundle supplied in the overridePendingTransition(...) call. Unfortunately, the AttributeSet used to create the animation is cast to a Parser further down in Resource.java, which puts an end to this solution..
3) Overriding attributes in Animation
Similar to (2), we want to replace attributes in Animations but right after the animations have been created. If the Animation class would have a setAttributes(AttributeSet) method, it would be possible to override the values that was just set in the constructor coming from XML. We also need a class implementing AttributeSet and Parcelable holding a Bundle that we can send along with the overridePendingTransition(...) call. Depending on where to do the actual call to animation.setAttributes(...), the animation class might need an findById(id) method for nestled animations (that is if it's not done in AnimationUtils while parsing..). The findById() call could also be interesting to use within Activities when dealing with animations with dynamic values to avoid having to create the whole animation in code just because one attribute can change. Although, I'm not sure this is the right way to go.
4) overridePendingTransition(...) that takes Animation objects
By making the Animation class parcelable, it's possible to create another version of overridePendingTransition(...) that takes Animation objects. Then it is possible to create your own set of animations with the right values and send it over to the WindowManagerService. However, this means that all Interpolator classes also needs to be parcelable and a whole bunch of other classes. Also, the AnimationListeners will not work across the process boundaries, which might be ok but still a little confusing.
5) The compositing way
Maybe it is time to expose some more powerful mechanism for doing animations where activities can plug into the SurfaceFlinger and take care of the compositing of one or several windows. And then have the full freedom of drawing them in any way it wants, possibly by using OpenGL. This is just an ideas from the top of my head and not really thought through. I have however looked into the SurfaceFlinger and played around with it just to verify that it is possible to render windows in 3D space using OpenGL. And as far as I can tell that worked quite well, but I guess exposing that to java code running in other processes is a different story. This is not even a direct solution to my problem but maybe something to dream about.
Any feedback would be greatly appreciated.
Thanks
Andreas Brännvall
UI Developer
Sony Ericsson
The postings on this site are my own and don't necessarily represent Sony Ericsson's positions, strategies or opinions.
An alternative solution might be to allow sending the whole resource
xml file and not just the resource id. This way the application can
generate the whole xml file and send it. This would improve
flexibility and wouldn't contain any extra risk.
/Pal