I got it!
Short answer: eliminate one of the two animations. When going from main to secondary activity, use only a fade-in. When going from secondary to main activity, use only a fade-out. Details and explanation follow.
There are several ways to combine two colors with alpha values. The process is called "alpha compositing". One naive way of doing the combination, which is not the one commonly used, is:
(a) C = C1*alpha1 + C2*alpha2
If that combination method were applied, using two linear interpolators for alpha1
and alpha2
would give a constant color wherever both C1
and C2
are equal to a "background" color Cbg
. Specifically, if alpha1 = t
(where t
represents time), alpha2 = 1-t
and C1 = C2 = Cbg
, the combination (a) gives C = Cbg*t + Cbg*(1-t) = Cbg
. That is, the composite color C
equals Cbg
irrespective of t
, as desired.
However, it appears that the combination which Android is applying is the so-called "over" operator:
(b) C = C1*alpha1 + C2*alpha2*(1-alpha1)
where it is considered that the pixel with color C1
is over that with C2
. With the combination method (b), in order to get a constant color C
for pixels with C1 = C2 = Cbg
it is sufficient that alpha2 = 1
, because then C = Cbg*alpha1 + Cbg*1*(1-alpha1) = Cbg
.
So the interpolator should be any (linear or otherwise) for the activity which is over and 1
(no animation) for the activity that is under.
Since I wasn't sure how Android decides which activity is over and which is under, I did some experimentation and found that:
When the main activity creates the secondary activity, the adequate procedure is to use a fade-in interpolator for the secondary activity.
When the secondary activity goes back to the main activity, the adequate procedure is to set a fade-out interpolator for the secondary activity.
So it looks like Android is considering that the secondary activity is over the main one. This makes sense, since the secondary was created by the main one.
- Since the main activity doesn't have to use any animation, according to the documentation it should be sufficient to set its animation to
0
, that is, useoverridePendingTransition(R.anim.fadein, 0)
. However, I have found that this only works sometimes. To get it working, I need to define a "fake" fade which goes from alpha 1.0 to alpha 1.0 (so that it actually does nothing) and useoverridePendingTransition(R.anim.fadein, R.anim.fakefade)
.
As for the need of a fake animation instead of a 0
animation, I don't have an explanation.
I wish the Android documentation was clearer on this. It would have saved me quite some time.