【问题标题】:Why does my Android transition ignore the TransitionListener?为什么我的 Android 过渡忽略了 TransitionListener?
【发布时间】:2015-12-28 17:57:54
【问题描述】:

我正在尝试通过在更新显示之前调用TransitionManager.beginDelayedTransition(viewGroup, new AutoTransition()) 来平滑更新显示。但我发现有时我更新显示速度很快,Android 会感到困惑。

所以我在AutoTransition 中添加了TransitionListener,其中transitionEnd() 回调,表示转换已完成,此时我将动画设置为屏幕的新状态。但我发现通常这甚至没有被调用。

是否有某种方法可以在 a) 过渡结束或 b) 过渡从一开始就没有被调用时回调回调?


更多信息:

我正在使用 Xamarin.Android。我有一段看起来像这样的代码,它启动了转换:

if (animated && viewGroup != null && Utils.Api19PlusKitkat) {
    App.Log("** Beginning animation.");
    var transition = new AutoTransition();
    transition.AddListener(new TransitionListener(this));
    TransitionManager.BeginDelayedTransition(viewGroup, transition);
}

TransitionListener 非常简单:

public class TransitionListener : Java.Lang.Object, Transition.ITransitionListener {
    readonly TreeNode owner;

    public TransitionListener(TreeNode owner)
    {
        this.owner = owner;
    }

    public void OnTransitionEnd(Transition transition)
    {
        App.Log("**** TransitionListener: Transition End.");
        owner.FinishTransition();
    }

    public void OnTransitionCancel(Transition transition) {}
    public void OnTransitionPause(Transition transition) {}
    public void OnTransitionResume(Transition transition) {}
    public void OnTransitionStart(Transition transition) {
        App.Log("**** TransitionListener: Transition Start.");
    }
}

当我查看我的应用程序日志时,我看到了一堆“开始动画”的案例,但非常罕见的“过渡开始”或“过渡结束”案例(目前我没有看到任何实例,但有时我已经看到它发生在日志中)。

【问题讨论】:

    标签: android xamarin.android android-transitions


    【解决方案1】:

    更新2:

    我想,我现在明白了。经过 2 天无果而终的尝试,我设法重现了这个问题。

    TransitionManager.beginDelayedTransition()只有会在屏幕上有要更新的内容时触发。

    例如,如果您将 OnClick 中的 setOnClickListenerTransitionManager.beginDelayedTransition() 与没有选择器的自定义背景按钮(android:background="#000",而不是默认选择器)一起使用 - 什么都不会发生,Transition 将无法启动完全没有(正如你在你的案例中看到的那样)。同时,如果您将相同的OnClickListener 分配给默认样式按钮(即选择器作为背景) - Transition 立即启动。

    同样,如果您在调用 TransitionManager.beginDelayedTransition() 后进行一些 UI 更改:

    public void changeScene(View v){
        AutoTransition autoTransition = new AutoTransition();
        autoTransition.setDuration(3000);
        autoTransition.addListener(new Transition.TransitionListener() {
            @Override
            public void onTransitionStart(Transition transition) {
                Toast.makeText(MainActivity.this, "start", Toast.LENGTH_SHORT).show();
            }
    
            @Override
            public void onTransitionEnd(Transition transition) {
                Toast.makeText(MainActivity.this, "end", Toast.LENGTH_SHORT).show();
            }
    
            @Override
            public void onTransitionCancel(Transition transition) {}
    
            @Override
            public void onTransitionPause(Transition transition) {}
    
            @Override
            public void onTransitionResume(Transition transition) {}
        });
    
        TransitionManager.beginDelayedTransition(container, autoTransition);
        findViewById(R.id.btn1).setVisibility(
                (findViewById(R.id.btn1).getVisibility()) == View.VISIBLE?
                         View.INVISIBLE : View.VISIBLE);
    }
    

    这将使代码 sn-p 可以正常工作:

    但是一旦你删除了可见性的设置器,Transition 就会添加到TransitionManagerbacklog 中并且不会被执行(方法的名称说 - 它可能是 延迟的 em>)。它只会在下一次 UI 更改期间执行:

    在此示例中,我删除了setVisibility() - 您可以看到结果:“动画”(在我的情况下只是 Toasts)仅在我单击带有 Selector 作为背景的按钮后才开始(即 UI-change发生)。

    因此修复将是 - “确保在您调用 TransitionManager.beginDelayedTransition() 之后有一些 UI 更改”

    希望对你有帮助

    附:不过有点奇怪,写在TransitionManager.beginDelayedTransition() 之后的TransitionManager.go() 不起作用。我在这里找到的唯一解决方法是将其放在 onTransitionEnd 中以进行延迟转换。

    更新1:

    首先想到的是它可能与 Xamarin 有关。然后我发现了两个在 Xamarin.Android 中使用BeginDelayedTransition 的示例:xamarin/monodroid-samplesgaruma/Moyeu。 要检查您的问题是否与 Xamarin.Android 有关 - 我建议调试这 2 个项目以查看 TransitionListener 是否触发转换事件。

    两个示例都使用TransitionManager.beginDelayedTransition() 和一个参数(viewGroup)。检查TransitionManagersource code 显示,1 参数方法正在调用beginDelayedTransition(sceneRoot, null);

    public static void beginDelayedTransition(final ViewGroup sceneRoot) {
        beginDelayedTransition(sceneRoot, null);
    }
    

    null 替换为sDefaultTransition:

    private static Transition sDefaultTransition = new AutoTransition();
    ....
    public static void More ...beginDelayedTransition(final ViewGroup sceneRoot, Transition transition) {
        if (!sPendingTransitions.contains(sceneRoot) && sceneRoot.isLaidOut()) {
            if (Transition.DBG) {
                Log.d(LOG_TAG, "beginDelayedTransition: root, transition = " +
                        sceneRoot + ", " + transition);
            }
            sPendingTransitions.add(sceneRoot);
            if (transition == null) {
                transition = sDefaultTransition;
            }
            final Transition transitionClone = transition.clone();
            sceneChangeSetup(sceneRoot, transitionClone);
            Scene.setCurrentScene(sceneRoot, null);
            sceneChangeRunTransition(sceneRoot, transitionClone);
        }
    }
    

    所以要调试它,您必须获取默认的 TransactionManager.getDefaultTransition() 并将您的 TransitionListener 添加到其中。

    如果它有效 - 那么我们将不得不在您的代码中找到问题。如果它不起作用 - 好吧。然后,大概,我们发现了一个系统错误,我们可以提交。

    【讨论】:

    • 我在帖子中添加了更多详细信息。不确定它是否非常有用。 :)
    • @AnthonyMills 我将继续担任 Obvious 队长,但我发现了两个在 Xamarin.Android 中使用 BeginDelayedTransition 的示例:xamarin/monodroid-samplesgaruma/Moyeu 所以,我假设它 应该 在 Xamarin 项目中工作。您能否在您的设备上调试这些示例并查看它们的动画侦听器是否被触发?
    • (你需要做TransactionManager.getDefaultTransition()并添加你的TransitionListener,因为这两个例子都使用TransitionManager.BeginDelayedTransition()和默认AutoTransition作为第二个参数 - 见源代码TransitionManager: grepcode.com/file/repo1.maven.org/maven2/org.robolectric/…) 通过这样做,我们将确定这是框架错误还是您的应用程序有问题,因此我们将消除一半的假设:-)
    • @AnthonyMills 我相信,我终于设法重现了这个问题并找到了解决方法。你能检查一下,是否有帮助?
    • 这是一项令人印象深刻的工作,绝对值得赏金。非常感谢!因此,唯一的方法是确保某些事情发生了变化。我必须考虑什么最适合我的系统。
    【解决方案2】:

    我终于找到了问题的答案。

    我在FrameLayout 上打电话给TransitionManager.beginDelayedTransition,当时我没有孩子,然后我添加了一个孩子。

    这不会导致转换发生,也不会调用回调。

    我现在在调用之前检查我正在调用beginDelayedTransitionViewGroup 是否有孩子;如果没有,我不会费心尝试为它制作动画。

    【讨论】:

      猜你喜欢
      • 2013-09-30
      • 2016-06-20
      • 1970-01-01
      • 1970-01-01
      • 2023-04-05
      • 1970-01-01
      • 2011-12-31
      • 2018-03-12
      • 1970-01-01
      相关资源
      最近更新 更多