【问题标题】:Fade-in / fade-out with constant background color across animation以恒定背景颜色淡入/淡出动画
【发布时间】:2013-08-16 16:40:28
【问题描述】:

我正在 Android 中的两个活动之间制作淡入/淡出动画。这两项活动都有白色背景(全息灯主题)。我在淡入的活动中将alpha 从 0 更改为 1,在淡出的活动中从 1 更改为 0。

我的问题是 整个动画中感知到的背景颜色不是恒定的,我觉得这很烦人。也就是说,背景在动画期间变暗然后变亮。所以在动画的中间,背景不会是白色的,而是中间的灰色。

我想使用两个插值器,这样两者的组合效果会产生恒定的背景颜色。我认为linear 插值器可以解决问题,因为它们使两个 alpha 的总和保持不变。但它不起作用:背景颜色在动画期间发生变化。标准的acceleratedecelerate 也没有我想要的行为。

所以,我的问题是:是否有任何已知的插值器(可能是 acceleratedecelerate,具有一定的速率)在淡入/淡出动画中提供恒定的背景颜色?

【问题讨论】:

  • 您所描述的只是动画的工作原理。听起来你想要的只是动画一个,然后在动画完成后显示另一个。您可能需要编写自定义动画(在 XML 中)才能做到这一点。
  • 如果我只动画一个(淡出),背景颜色将不可避免地从白色(alpha 1)变为黑色(alpha 0)。不是我想要的。
  • 所以如果我理解正确 - 你想要一个恒定的背景颜色。那你为什么要为任何东西制作动画?看来您应该只在所需的时间间隔内显示具有所需颜色的叠加层。
  • 我制作动画是因为这些活动中有更多的东西,而不仅仅是背景。我希望这两个活动的观点从第一个活动的观点“融化”到第二个活动的观点;但背景不变

标签: android android-animation alpha


【解决方案1】:

从 cmets 看来,您想为活动中的视图设置动画,而不是活动本身。您可以使用droidQuery 库来执行此操作。只需将其设置为您的 onPause() 方法:

@Override
public void onPause() {
    //here, substitute mainView with the id of your background
    $.with(this, R.id.mainView).selectChildren().selectAll().animate("{ alpha : 0.0f }", 400, $.Easing.LINEAR, $.noop());
    super.onPause();
}

这将选择作为背景子级的所有视图,并使用 ObjectAnimator、线性插值和 400 毫秒持续时间将其 alpha 值设置为 0。

您还需要覆盖onResume()

@Override
public void onResume() {
    //here, substitute mainView with the id of your background
    $.with(this, R.id.mainView).selectChildren().selectAll().animate("{ alpha : 1.0f }", 400, $.Easing.LINEAR, $.noop());
    super.onResume();
}

这正好相反 - 从 0 alpha 到 1 的动画。

【讨论】:

  • 感谢您的回答。采用这种方式,两个activity的淡入淡出会同时进行吗?
  • @LuisMendo 我不确定,因为这些是视图动画,而不是活动过渡动画,但是加上活动动画(overridePendingTransition),这应该提供非常接近你的效果想要。
  • 我明白了。有兴趣的请看我自己的回答。通过使用 一个 alpha 动画而不是两个来实现所需的效果。
【解决方案2】:

我明白了!

简答:消除两个动画之一。从主要活动转到次要活动时,仅使用淡入。从次要活动转到主要活动时,仅使用淡出。详细信息和解释如下。

有几种方法可以将两种颜色与 alpha 值结合起来。该过程称为“alpha compositing”。 不是常用的一种简单的组合方式是:

(a) C = C1*alpha1 + C2*alpha2

如果应用该组合方法,则在C1C2 都等于“背景”颜色Cbg 的情况下,对alpha1alpha2 使用两个线性插值器将给出恒定颜色。具体来说,如果alpha1 = t(其中t代表时间)、alpha2 = 1-tC1 = C2 = Cbg,则组合(a)给出C = Cbg*t + Cbg*(1-t) = Cbg。也就是说,合成颜色C 等于Cbg,而与t 无关。

但是,Android 应用的组合似乎是所谓的“over”运算符:

(b) C = C1*alpha1 + C2*alpha2*(1-alpha1)

认为颜色为C1 的像素超过C2 的像素。使用组合方法 (b),为了获得具有 C1 = C2 = Cbg 的像素的恒定颜色 Calpha2 = 1 就足够了,因为那时 C = Cbg*alpha1 + Cbg*1*(1-alpha1) = Cbg

因此,对于 over 的活动,插值器应该是 any(线性或其他),对于 的活动应该是 1(无动画)在下。

由于我不确定 Android 如何决定哪个活动结束和哪个活动结束,所以我做了一些实验并发现:

  • 当主要活动创建次要活动时,适当的过程是为次要活动使用淡入插值器。

  • 当次要活动回到主要活动时,适当的过程是为次要活动设置淡出插值器。

所以看起来 Android 正在考虑 次要活动超过主要活动。这是有道理的,因为辅助是由主创建的。

  • 由于主Activity不必使用任何动画,根据documentation,将其动画设置为0就足够了,即使用overridePendingTransition(R.anim.fadein, 0)。但是,我发现这只有时有效。为了让它工作,我需要定义一个从 alpha 1.0 到 alpha 1.0 的“假”淡入淡出(这样它实际上什么都不做)并使用overridePendingTransition(R.anim.fadein, R.anim.fakefade)

至于需要假动画而不是0动画,我没有解释。

我希望 Android 文档对此更清楚。这会为我节省不少时间。

【讨论】:

    猜你喜欢
    • 2012-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-01
    • 2021-07-06
    • 2015-10-15
    • 1970-01-01
    • 2010-11-01
    相关资源
    最近更新 更多