Android view.animate() 在第一次执行后工作不同且错误

标签 android animation

我已经实现了一个横幅,只要用户失去连接就会弹出。重新连接后,另一个横幅会显示几秒钟然后消失。

布局是一个 RelativeLayout,其中灰色 TextView 用于警告*,绿色 TextView 用于重新连接消息。

Example of both banners

如果我只是更改它们的 Visibility.GONE 和 Visibility.VISIBLE,一切正常。

但我想做得更漂亮,所以我添加了一些动画。我在这里遇到了一个奇怪的问题。 在第一次执行中,一切都按预期工作。以下执行不正确。

我想在重新连接发生时同时为两个 TextView 设置动画。所以灰色的 textview 淡出,而绿色的 textview 淡入(同时)。这只在第一次执行时像那样工作。下一次它按顺序执行:首先灰色 TextView 淡出,然后绿色 TextView 淡入。我不想按顺序执行。

我上传了一个视频到Youtube(30s),大家可以看看效果。首先工作,然后不工作。观看这个比阅读我的描述更容易:https://youtu.be/rD1ZNzKen0U

Crossfade 方法是所有魔法发生的地方。如您所见,view.animate() 在两个线程中被调用。最初我实现了完全相同的代码,但没有线程,因为 animate() 方法应该是异步的。但是我对这个问题很生气,所以我试着这样做。我还尝试在设置每个动画之前执行 view.clearAnimations() 。但是什么都没有。

private void crossfade() {
    final int animationDuration = 600;

    // Set the view to 0% opacity but visible, so that it is visible (but fully transparent) during the animation.
    bannerNetworkConnected.setAlpha(0f);
    bannerNetworkConnected.setVisibility(View.VISIBLE);

    bannerNetworkDisconnected.animate()
            .alpha(0f)
            .setDuration(animationDuration)
            .setListener(null);

    bannerNetworkConnected.animate()
            .alpha(1f)
            .setDuration(animationDuration)
            //  .setListener(null);
            .setListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    dissapearFadding();
                }
            });

    flipper.stopFlipping();
}

关闭重新连接的横幅的方法:

private void dissapearFadding() {
    bannerNetworkConnected.animate()
            .alpha(0f)
            .setDuration(300)
            .setStartDelay(1500)
            .setListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    bannerNetworkDisconnected.setVisibility(View.GONE);
                    container.setVisibility(View.GONE);
                    bannerNetworkConnected.setVisibility(View.GONE);
                }
            });
}

网络切换接收器:

public void networkStateChange(boolean connected) {
    Log.i(MainActivity.TAG, "MainActivity.networkStateChange() " + connected);
    //bannerNetworkDisconnected.setVisibility(connected ? View.GONE : View.VISIBLE);

    if (bannerNetworkDisconnected != null && bannerNetworkConnected != null) {
        bannerNetworkDisconnected.clearAnimation();
        bannerNetworkConnected.clearAnimation();

        if (!connected) {
            appearFromTop();
        } else if (connected && bannerNetworkDisconnected.getVisibility() == View.VISIBLE) {
            crossfade();
        } else {
            container.setVisibility(View.GONE);
            bannerNetworkConnected.setVisibility(View.GONE);
            bannerNetworkDisconnected.setVisibility(View.GONE);
            flipper.stopFlipping();
        }
    }
}

横幅 XML:

    <RelativeLayout
    android:id="@+id/banner_network_container"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:visibility="gone">

    <TextView
        android:id="@+id/banner_network_disconnected"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="No connection. Retrying..."
        android:textColor="#F0F0F0"
        android:visibility="gone"/>

    <TextView
        android:id="@+id/banner_network_connected"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#44bb44"
        android:text="Reconnected!"
        android:textColor="#F0F0F0"
        android:visibility="gone"/>
</RelativeLayout>

我已经创建了一个新项目并为此复制了所有代码,但问题仍然存在。如果你想在这里检查整个类,你在 github 上有整个项目: https://github.com/rolgalan/NetworkBanner

对于这方面的任何帮助,我真的很感激,因为我现在花了太多时间来解决这个问题,而且我快疯了。这真的很奇怪,因为它实际上执行了两个动画……但是一个接一个地执行,而不是像第一次执行时那样并行执行。

*实际上,警告横幅比简单的 TextView (LinearLayout) 稍微复杂一些,因为我想要“重试...”文本的闪烁效果。但我们不应该关心这个。

最佳答案

(对我来说)这很有趣,因为我刚刚在几分钟前回答了另一个与您的问题完全相同的问题:

请从这里阅读我的回答: Why does running a second viewpropertyanimation on a view break the animation listeners?

所以根据我在那里的解释,修复很简单:

  • 添加.setStartDelay(0)
  • crossFade() -> bannerNetworkConnected.animate()

因此它会重置延迟并且它们可以一起运行。

关于Android view.animate() 在第一次执行后工作不同且错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40308914/

相关文章:

c - OpenGL 初学者和 2D 动画项目?

java - 从其他 Activity 触发异步任务?

javascript - jQuery animate "complete"回调触发太快

android - 如何获取要重命名的 ScrollView 标题的 ID(应用栏中的标题)

Android - 从 flavor 中删除 Activity

jquery - 如何为动画汉堡包图标使用 Font Awesome Bars

javascript - 在元素之间移动鼠标太快时出现 jQuery 悬停问题

android - 在 TextView 中动态加载 AnimationDrawable

android - 如何通过在 viewpager 上用手指滑动来禁用分页但允许 onClickListener

android - 如何使用 IP 地址确定 Android 中设备的位置