我试图在更新显示之前通过调用TransitionManager.beginDelayedTransition(viewGroup, new AutoTransition())来平滑地更新显示。但我发现有时我会快速更新显示器,而安卓会感到困惑。
所以我在TransitionListener中添加了一个AutoTransition,在这里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.");
    }
}

当我查看我的应用程序日志时,我看到了很多“开始动画”的情况,但很少有“过渡开始”或“过渡结束”的情况(目前我没有看到任何实例,但有时我在日志中看到它)。

最佳答案

UPD2:
我想,我现在明白了。经过两天毫无结果的尝试,我设法驳斥了这个问题。
TransitionManager.beginDelayedTransition()只有在屏幕上有要更新的内容时才会触发某些内容。
例如,如果您将setOnClickListener中的TransitionManager.beginDelayedTransition()指向没有选择器的自定义背景按钮(OnClick,而不是默认选择器),则不会发生任何事情,android:background="#000"根本不会启动(如您在案例中看到的那样)。同时,如果您将相同的Transition指定给默认样式的按钮(即使用选择器作为背景)-OnClickListener将立即启动。
同样,如果在调用Transition之后执行一些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);
}

这将代码片段工作,因为它应该:
android - 为什么我的Android转换会忽略TransitionListener?-LMLPHP
但是,一旦移除setter以获得可见性,transition就会添加到TransitionManager.beginDelayedTransition()的backlog中,并且不会执行(方法的名称是-它可能会被延迟)。它将仅在下一次用户界面更改期间执行:
android - 为什么我的Android转换会忽略TransitionListener?-LMLPHP
在本例中,我删除了TransitionManager-并且您可以看到结果:“animation”(在我的例子中只是toasts)仅在我用选择器作为背景单击按钮后才开始(即发生ui更改)。
所以修复方法将是“确保在您调用setVisibility()之后有一些ui更改”。
希望能帮上忙
不过,有点奇怪,在TransitionManager.beginDelayedTransition()之后写的TransitionManager.go()行不通。我在这里找到的唯一解决办法是把它放在TransitionManager.beginDelayedTransition()中,用于延迟的转换。
UPD1:
最初的想法是它可能与Xamarin有关。然后我发现了两个在xamarin.android中使用onTransitionEnd的例子:xamarin/monodroid-samplesgaruma/Moyeu
要检查您的问题是否与xamarin.android有关-我建议调试这两个项目,看看BeginDelayedTransition是否触发转换事件。
两个示例都使用TransitionListener和一个参数(viewgroup)。检查TransitionManager.beginDelayedTransition()source code表明,1参数方法正在调用TransitionManager
public static void beginDelayedTransition(final ViewGroup sceneRoot) {
    beginDelayedTransition(sceneRoot, null);
}

空替换为beginDelayedTransition(sceneRoot, null);
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);
    }
}

因此要调试它,您必须获得默认的sDefaultTransition并将您的TransactionManager.getDefaultTransition()添加到其中。
如果成功的话-那么我们必须在你的代码中找到问题所在。如果它不起作用-好吧…然后,大概,我们发现了一个系统错误,我们可以归档。

07-27 18:50