我试图在更新显示之前通过调用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);
}
这将代码片段工作,因为它应该:
但是,一旦移除setter以获得可见性,transition就会添加到
TransitionManager.beginDelayedTransition()
的backlog中,并且不会执行(方法的名称是-它可能会被延迟)。它将仅在下一次用户界面更改期间执行:在本例中,我删除了
TransitionManager
-并且您可以看到结果:“animation”(在我的例子中只是toasts)仅在我用选择器作为背景单击按钮后才开始(即发生ui更改)。所以修复方法将是“确保在您调用
setVisibility()
之后有一些ui更改”。希望能帮上忙
不过,有点奇怪,在
TransitionManager.beginDelayedTransition()
之后写的TransitionManager.go()
行不通。我在这里找到的唯一解决办法是把它放在TransitionManager.beginDelayedTransition()
中,用于延迟的转换。UPD1:
最初的想法是它可能与Xamarin有关。然后我发现了两个在xamarin.android中使用
onTransitionEnd
的例子:xamarin/monodroid-samples和garuma/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()
添加到其中。如果成功的话-那么我们必须在你的代码中找到问题所在。如果它不起作用-好吧…然后,大概,我们发现了一个系统错误,我们可以归档。