【问题标题】:Android animation only works if I reschedule it from the UI thread to the UI thread仅当我将其从 UI 线程重新调度到 UI 线程时,Android 动画才有效
【发布时间】:2019-01-09 17:10:13
【问题描述】:

我执行了一个网络调用,其中我

.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())

然后我将结果传递给io.reactivex.function.Consumer,它会尝试为视图设置动画。

当我在本地同步加载数据时,这些动画可以工作,但是当我引入这个服务器调用时就坏了。

现在,当我为视图设置动画时,它根本不会更改任何属性,而是立即调用动画完成侦听器。

我用Looper.getMainLooper().isCurrentThread()验证了我在主线程上

然而,我能够让动画再次工作的唯一方法是将其包裹在 AndroidSchedulers.mainThread().scheduleDirect(() -> {})

正如这段代码所示,实际上不应该改变任何东西

 final Thread before = Thread.currentThread();
 AndroidSchedulers.mainThread().scheduleDirect(() -> {
     boolean nothingChanged = before == Thread.currentThread();
     //nothingChanged is true
 });

为什么我必须将动画重新安排到它已经运行的线程上才能让它工作?

编辑:不涉及 RxJava,甚至发生了更奇怪的事情。 我剪掉了 RxJava,即使我将动画代码放在 onNavigationItemSelected() 中,问题仍然存在,当用户单击某些东西时,它由 android 调用,所以它肯定在正确的线程中。

我的动画是这样的。

alertBanner.clearAnimation();
alertBanner.animate()
        .alpha(0)
        .translationY(alertBanner.getHeight())
        .setDuration(500)
        .setListener(new AnimatorListenerBuilder().setOnAnimationEnd(animator -> {
            alertBanner.setVisibility(GONE);
        }))
        .start();

AnimatorListenerBuilder 只是一个实用类,它封装了 AnimatorListener 并让您只定义您想要的回调。它适用于我的应用中的所有其他动画,并且在几个月内没有更改。

【问题讨论】:

    标签: java android rx-java rx-java2 rx-android


    【解决方案1】:

    我想通了。这是一个竞争条件。

    当用户点击按钮时,发生了两件事: 创建了一个新片段,并开始了动画。 然而,片段有一个回调,onAttach(),除其他外,它会在我试图动画化的视图上调用.clearAnimation()

    通过将动画重新安排回主线程,我确保它发生在片段回调之后。

    我通过去掉片段中的回调来解决这个问题,并将该逻辑与启动动画的逻辑放在同一个位置,让我可以控制执行顺序。

    【讨论】:

      猜你喜欢
      • 2012-11-24
      • 2012-06-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多