Android view.animate()在首次执行后会出现不同的错误 [英] Android view.animate() works different and wrong after first execution

查看:132
本文介绍了Android view.animate()在首次执行后会出现不同的错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我实施了一条横幅,该横幅会在用户断开连接时弹出。重新连接时,另一个横幅会显示几秒钟,然后消失。

I've implemented a banner which pops out whenever the user losts connection. When is reconnected, another banner shows up for some seconds and disappears.

布局是一个RelativeLayout,带有灰色的TextView作为警告*,绿色的TextView用于重新连接。消息。

The layout is a RelativeLayout with a grey TextView for the warning*, and a green TextView for the reconnection message.

如果我只是更改Visibility.GONE

If I just change Visibility.GONE and Visibility.VISIBLE on them, everything works fine.

但是我想做得更好,所以我添加了一些动画。我在这里遇到一个奇怪的问题。 在第一次执行时,一切都会按预期进行。以下执行无法正常工作。

But I wanted to do it fancier, so I added some animations. And I'm having a weird problem here. In first execution everything works as expected. Following executions don't work right.

我想在重新连接发生时同时为两个文本视图设置动画。因此,灰色的textview淡出,而绿色的textview淡入(同时)。这仅在第一次执行时才起作用。下次它会安全地执行:首先,灰色的textview淡出,然后,绿色的textview淡入。我不希望它保密。

I want to animate both textviews at the same time when reconnection happens. So the grey textview fades out, while the green textview fades in (both at the same time). This works like that only on first execution. Next times it executes secuentially: first the grey textview fades out, and after that, green textview fades in. And I don't want it secuentially.

我已经上传了向Youtube发送视频(30秒),以便您看到效果。首先工作,然后不行。观看此内容比阅读我的描述要容易得多: https://youtu.be/rD1ZNzKen0U

I've uploaded a video to Youtube (30s) so you can see the effect. First working, and then not. It's easier to watch this than to read my description: https://youtu.be/rD1ZNzKen0U

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

Crossfade method is where all the magic happens. As you see, the view.animate() is called inside two threads. Initially I implemented exactly the same code, but without threads, because the animate() method should be asynchronous. But I'm getting nuts with this problem, so I tried do it like this. I've also tried to execute view.clearAnimations() before setting each animation. But nothing.

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();
}

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

Method for dismissing the reconnected banner:

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

I've created a new project and copied all the code for this, and the problem still there. If you want to inspect the whole classes here, you have the whole project on github: https://github.com/rolgalan/NetworkBanner

我真的很感谢任何帮助,因为我花了很多时间来解决这个问题,变得疯狂。这真的很奇怪,因为它实际上执行了两个动画……但是一个接一个地执行,而不是像第一次执行那样并行执行它们。

I really would appreciate any help on this, because I've spent too much hours now to fix this and I'm getting crazy. It's really weird because it actually executes both animations... but one after the other instead of doing them in parallel like in the first execution.

*实际上警告标语是比起简单的TextView(LinearLayout),它有点复杂,因为我想要一个重试...文本的闪烁效果。

*Actually the warning banner is a bit more complex than a simple TextView (LinearLayout) since I wanted a blink effect for "retrying..." text. But we shouldn't care about this.

推荐答案

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

It's pretty funny (for me) because I literally just answered a few minutes ago another question which is exactly the same problem as yours:

请从此处阅读我的答案:
为什么在视图上运行第二个视图属性动画会破坏动画侦听器? / a>

Please read my answer from here: Why does running a second viewpropertyanimation on a view break the animation listeners?

因此,根据我在此处所做的解释,修复很容易:

so from what I explained there, the fix is easy:


  • .setStartDelay(0)

  • 添加到 crossFade()-> bannerNetworkConnected.animate()

  • add .setStartDelay(0)
  • to crossFade() -> bannerNetworkConnected.animate()

因此它重置了延迟,它们可以一起运行。

so it resets the delay and they can run together.

这篇关于Android view.animate()在首次执行后会出现不同的错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆