为什么我的Android过渡会忽略TransitionListener? [英] Why does my Android transition ignore the TransitionListener?

查看:80
本文介绍了为什么我的Android过渡会忽略TransitionListener?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to make a smoothly-updating display by calling TransitionManager.beginDelayedTransition(viewGroup, new AutoTransition()) before updating the display. But I found that sometimes I update the display rapidly and Android gets confused.

所以我在 AutoTransition 上添加了 TransitionListener ,其中 transitionEnd()回叫,说过渡完成,此时我要进行动画处理到屏幕的新状态.但是我发现通常甚至都没有这个名字.

So I added a TransitionListener to the AutoTransition where transitionEnd() calls back, saying the transition is complete, at which point I animate to the new state of the screen. But I find that usually this is not even called.

是否有某种方法可以使回调在a)转换结束或b)首先从不调用转换的时候回调?

Is there some way of having a callback called back either when a) a transition ends or b) a transition never gets called in the first place?

更多信息:

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

I'm using Xamarin.Android. I have a section of code that looks like this which initiates the transition:

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

TransitionListener很简单:

TransitionListener is pretty simple:

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.");
    }
}

当我查看应用程序日志时,看到了很多开始动画"案例,但很少见到过渡开始"或过渡结束"的情况(目前我没有看到任何实例,但有时我已经看到它在日志中发生了.)

When I look at my application log, I see a bunch of cases of "Beginning animation" but very rare cases of "Transition Start" or "Transition End" (currently I'm not seeing any instances but sometimes I've seen it happen in the log).

推荐答案

Upd2:

我想,我现在明白了.经过两天无果的尝试,我设法解决了这个问题.

I think, I got it now. After 2 days of fruitless attempts, I managed to repro the issue.

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

TransitionManager.beginDelayedTransition() will fire up something only when there's something to update on the screen.

例如,如果您将 setOnClickListener OnClick 中的 TransitionManager.beginDelayedTransition()一起使用到具有自定义背景且没有选择器的按钮(android:background =#000" ,而不是默认选择器)-什么也不会发生, Transition 根本不会启动(如您所见).同时,如果您将相同的 OnClickListener 分配给默认样式的按钮(即以选择器为背景)- Transition 将立即开始

For example, if you setOnClickListener with TransitionManager.beginDelayedTransition() in OnClick to the button with custom background without selector (android:background="#000", instead of the default selector) - nothing will happen, Transition won't start at all (as you see in your case). At the same time, if you assign same OnClickListenerto the default-styled button (i.e. with selector as a background) - Transition will start immediately.

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

Same, if you do some UI-changes after TransitionManager.beginDelayedTransition() being called:

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

此代码段将正常运行,

但是,一旦删除可见性的设置器,Transition就会添加到 TransitionManager backlog 中,并且不会执行(该方法的名称说-可能是 delayed ).而且只会在下一次UI更改期间执行:

But once you remove the setter for Visibility, Transition is adding to the backlog of the TransitionManager and not executed (the name of the method says - it might be delayed). And it will be executed only during next UI-change:

在此示例中,我删除了 setVisibility()-并且您可以看到结果:仅在单击Selector为背景(即发生UI更改).

In this example, I removed the the setVisibility() - and you can see the result: "animation" (in my case just Toasts) started only after I clicked on the button with Selector as a background (i.e. UI-change happens).

因此,解决方法将是-",请确保在调用 TransitionManager.beginDelayedTransition()后有一些UI更改.

So the fix is going to be - "make sure there's some UI change just after you call TransitionManager.beginDelayedTransition()".

我希望这会有所帮助

P.S.但是,在 TransitionManager.beginDelayedTransition()之后编写的 TransitionManager.go()无法正常工作,这有点奇怪.我在这里找到的唯一解决方法是将其放在 onTransitionEnd 中,以延迟转换.

P.S. It's kind of strange though, that TransitionManager.go(), written after TransitionManager.beginDelayedTransition(), won't work. The only workaround I found here is to put it inside onTransitionEnd for the delayed transition.

更新1:

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

First thought was that it might be related to Xamarin. Then I found two examples which are using BeginDelayedTransition in Xamarin.Android: xamarin/monodroid-samples and garuma/Moyeu. To check if your issue relates to Xamarin.Android or not - I suggest to debug these 2 projects to see if TransitionListener fires Transition-events.

两个示例都使用带有一个参数(viewGroup)的 TransitionManager.beginDelayedTransition().检查 TransitionManager 的rel ="nofollow noreferrer">源代码显示,1-参数方法正在调用 beginDelayedTransition(sceneRoot,null);

Both examples uses TransitionManager.beginDelayedTransition() with one parameter (viewGroup). Checking source code of TransitionManager shows, that 1-parameter method is is calling beginDelayedTransition(sceneRoot, null);

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

,并将null替换为 sDefaultTransition :

and null replaces by 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 中.

So to debug it, you'll have to get the default TransactionManager.getDefaultTransition() and add your TransitionListener into it.

如果有效,那么我们将不得不在您的代码中查找问题.如果它不起作用-很好.那么,大概是我们发现了一个系统错误,可以将其归档.

If it works - then we'll have to find the issue in your code. If it doesn't work - well.. Then, presumably, we found a system bug, which we can file.

这篇关于为什么我的Android过渡会忽略TransitionListener?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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