如何判断一个活动是否在没有转换的情况下启动?

20

我有一个应用场景,其中我通常会通过转换开始活动,但从导航抽屉中打开时情况并非如此。

为了保持转换平滑,我使用Transition.TransitionListener,当转换完成时,我会触发一些UI更新。

所以我的代码类似于:

public class SomeActivity extends Activity {

    public void onCreate(Bundle savedInstanceState){ 
        // ...
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
            Transition sharedElementEnterTransition = getWindow().getSharedElementEnterTransition();
            sharedElementEnterTransition.addListener(new Transition.TransitionListener() {
                // ...
                @Override
                public void onTransitionEnd(Transition transition) {
                    doSomeUiUpdating();
                }
            });
        } else { // Pre-Lollipop
            doSomeUiUpdating();
        }
    }
}

如果使用动画启动Activity,这个方法很有效,但如何知道Activity是没有转换效果而启动的,以便我可以调用doSomeUiUpdating()

我相信在ActivityWindowTransition或其他地方肯定有一个简单的方法,但我可能已经忽略了它。我不想依赖于调用Activity来设置一些指示是否显示动画的捆绑包。


我会假设你的逻辑与你所拥有的相同(如果(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP){ doSomeUiUpdating(); .... }),在你的代码之前,你必须启动一个活动。 - Tasos
API 19(KITKAT)中添加了转换,因此您需要在LOLLIPOP之前进行检查-- https://www.youtube.com/watch?v=K3yMV5am-Xo - Tasos
问题在于 - 正如我在第一行中所说 - 在Lollipop+上,活动通常是通过转换启动的,但当用户从导航抽屉中启动活动时,不会发生这种情况。 - Roy Solberg
只是一个虚拟的想法:也许你可以依赖于TransitiongetTargets()方法(sharedElementEnterTransition.getTargets().isEmpty()),看它是否为空?无论如何它都不是null,而TargetViews的数量可能是解决方案。 - Konstantin Loginov
@RoyS 对不起,显然我没有阅读你帖子中的最后一句话。请原谅 :) - Lev
显示剩余8条评论
2个回答

4
自从您启动了一个Activity,就需要使用Intent来启动它。您可以向Intent添加额外的内容,并在被调用的ActivityonCreate()中检查它们。
假设我们有两个活动 - ActivityAActivityB。 现在,假设ActivityA是调用的ActivityActivityB是被调用的Activity
ActivityA中,假设您编写了一些代码以使用SharedElementTransition启动ActivityB
@Override
public void onClick(View v) {
    Intent startActivityBIntent = new Intent(getContext(), ActivityB.class);
    startActivityBIntent.putExtra("IS_SHARED_ELEMENT_TRANSITION_ENABLED", true);
    ActivityOptionsCompat activityOptionsCompat = ActivityOptionsCompat.makeSceneTransitionAnimation(getActivity(), view, ViewCompat.getTransitionName(view));
    startActivity(startActivityBIntent, activityOptionsCompat);
}

现在,如果您注意到上面的内容,我已经使用putExtra()方法传递了一个Intent额外的参数。我传递了一个布尔值为true,因为我打算使用SharedElementTransition启动Activity。
现在,在ActivityBonCreate()方法中,您只需要检查传递给Intent的布尔值即可。如果您传递了false,则可以添加一个条件语句并在那里执行UI更新。我在下面给出了一个小片段来帮助您入门:
private static final String isSharedElementTransitionEnabled = "IS_SHARED_ELEMENT_TRANSITION_ENABLED";    

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_b);

    // If you are postponing your SharedElementTransition, don't forget to call postponeEnterTransition() and override onPreDraw()

    if (!getIntent().getExtras().getBoolean(isSharedElementTransitionEnabled)) {
        //Do your UI updation here
    }
}

这种方式的好处在于,您可以完全控制内容和共享元素的过渡效果。

4
你可以尝试使用TransitionListeneronTransitionStart方法来设置一个布尔值isAnimationStarted
public class SomeActivity extends Activity {

    private boolean isAnimationStarted = false;

    public void onCreate(Bundle savedInstanceState) { 
        // ...
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
            Transition sharedElementEnterTransition = getWindow().getSharedElementEnterTransition();
            sharedElementEnterTransition.addListener(new Transition.TransitionListener() {
                // ...
                @Override
                public void onTransitionEnd(Transition transition) {
                    doSomeUiUpdating();
                }

                @Override
                public void onTransitionStarted(Transition transition) {
                    isAnimationStarted = true;
                }
            });
        }
    }

    public void onStart() {
        if (!isAnimationStarted) {
            doSomeUiUpdating();
        }
    }

}

不错的简单解决方案。 :) - Roy Solberg
但是这样不会产生一个潜在的问题吗?因为回调函数意味着异步执行,即使动画即将开始,onStart也可能在onTransitionStarted之前被调用。 - NeverwinterMoon
3
事实上,我刚刚测试了一下,结果完全和我说的一样——在我的情况下,onStart总是在任何回调之前调用,因此isAnimationStarted总是在那里为false。因此,这种方法肯定不能帮助确定活动是否带有/不带有转换启动。 - NeverwinterMoon
你找到正确的方法了吗?正如@NeverwinterMoon的评论所说,这并没有完全解决问题。 - Eduardo Pinheiro

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接