我尝试在更新显示之前调用TransitionManager.beginDelayedTransition(viewGroup, new AutoTransition())
来平滑更新显示。但我发现有时候我会快速更新显示屏并且Android会感到困惑。
所以我向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.");
}
}
当我查看我的应用程序日志时,我看到了一堆" Beginning animation"但非常罕见的过渡开始"或者"过渡结束" (目前我没有看到任何情况,但有时我会在日志中看到它。)
答案 0 :(得分:3)
<强> UPD2:强>
我想,我现在明白了。经过2天毫无结果的尝试,我成功地重新解决了这个问题。
当屏幕上有更新内容时, TransitionManager.beginDelayedTransition()
会启动 。
例如,如果setOnClickListener
TransitionManager.beginDelayedTransition()
位于OnClick
的自定义背景而非选择器(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);
}
这将使代码片段正常工作:
但是一旦删除了Visibility的setter,Transition就会添加到TransitionManager
的 backlog 并且没有执行(方法名称显示 - 它可能延迟)。它将仅在下一次UI更改期间执行:
在这个例子中,我删除了setVisibility()
- 你可以看到结果:“动画”(在我的情况下只是Toasts)只有在我点击按钮并选择Selector作为背景后才启动(即UI - 发生变化)。
因此修复将会是 - “确保在您致电TransitionManager.beginDelayedTransition()
”之后有一些用户界面更改。
我希望,这有帮助
P.S。但有点奇怪,在TransitionManager.go()
之后编写的TransitionManager.beginDelayedTransition()
将无效。我在这里找到的唯一解决方法是将其放在onTransitionEnd
内以进行延迟转换。
<强> Upd1:强>
首先想到的是它可能与Xamarin有关。然后我发现了两个在Xamarin.Android中使用BeginDelayedTransition
的示例:xamarin/monodroid-samples和garuma/Moyeu。
要检查你的问题是否与Xamarin.Android有关 - 我建议调试这两个项目,看看TransitionListener
是否会触发Transition-events。
两个示例都使用TransitionManager.beginDelayedTransition()
和一个参数(viewGroup)。检查TransitionManager
显示的source 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
添加到其中。
如果有效 - 那么我们必须在您的代码中找到问题。如果它不起作用 - 那么......大概,我们发现了一个系统错误,我们可以提交。
答案 1 :(得分:0)
我终于找到了问题的答案。
我在TransitionManager.beginDelayedTransition
打电话给FrameLayout
时我打电话时没有孩子,然后我又加了一个孩子。
这不会导致转换发生,也不会调用回调。
我现在在拨打电话之前检查ViewGroup
我打电话beginDelayedTransition
是否有孩子。如果它没有,我就不用费心去做动画了。