为什么我的Android过渡会忽略TransitionListener?
作者:互联网
我正在尝试通过更新显示之前调用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.");
}
}
当我查看应用程序日志时,会看到很多“开始动画”的案例,但很少见到“过渡开始”或“过渡结束”的情况(目前我没有看到任何实例,但有时我已经看到它发生了在日志中).
解决方法:
Upd2:
我想,我现在明白了.经过2天没有结果的尝试,我设法解决了这个问题.
仅当屏幕上有要更新的内容时,TransitionManager.beginDelayedTransition()才会触发某些内容.
例如,如果您将OnClick中的带有TransitionManager.beginDelayedTransition()的setOnClickListener设置为具有不带选择器的自定义背景的按钮(android:background =“#000”,而不是默认选择器),则什么都不会发生,则过渡将不会开始(如您所见).同时,如果您将相同的OnClickListener分配给默认样式的按钮(即以选择器为背景)-过渡将立即开始.
同样,如果在调用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);
}
该代码段将正常工作,因为它应该:
但是,一旦删除了“可见性”设置器,Transition就会添加到TransitionManager的待办事项列表中,并且不会执行(方法名称显示-可能会延迟).并且仅在下一次UI更改期间执行:
在此示例中,我删除了setVisibility()-您可以看到结果:仅在单击以Selector为背景的按钮(即发生UI更改)后,“动画”(在我的情况下仅为Toasts)才开始.
因此,解决方法将是-“确保在调用TransitionManager.beginDelayedTransition()之后有一些UI更改”.
希望对您有帮助
附言但是,在TransitionManager.beginDelayedTransition()之后编写的TransitionManager.go()无法正常工作,这有点奇怪.我在这里找到的唯一解决方法是将其放在onTransitionEnd内以进行延迟的转换.
Upd1:
首先想到的是它可能与Xamarin有关.然后我发现了两个在Xamarin.Android中使用BeginDelayedTransition的示例:xamarin/monodroid-samples和garuma/Moyeu.
要检查您的问题是否与Xamarin.Android有关-我建议调试这两个项目,以查看TransitionListener是否触发Transition-events.
这两个示例都使用带有一个参数(viewGroup)的TransitionManager.beginDelayedTransition().检查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()并将其添加到其中.
如果有效,那么我们将不得不在您的代码中查找问题.如果它不起作用-很好.那么,大概是我们发现了一个系统错误,可以将其归档.
标签:xamarin-android,android-transitions,android 来源: https://codeday.me/bug/20191119/2034640.html