如何知道一项活动是不是在没有过渡的情况下开始?
Posted
技术标签:
【中文标题】如何知道一项活动是不是在没有过渡的情况下开始?【英文标题】:How can one know if an activity is started without a transition?如何知道一项活动是否在没有过渡的情况下开始? 【发布时间】:2016-06-04 10:35:19 【问题描述】:我有一个用例,我主要通过转换启动一个活动,但从导航抽屉打开它时不是这种情况。
为了保持过渡平稳,我有一个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()
?
我确定Activity
、Window
、Transition
或者我忽略的某个地方一定有一个简单的方法。我不想中继调用 Activity 来设置一些包来告知动画是否正在显示。
【问题讨论】:
我会假设它的逻辑和你一样(if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) doSomeUiUpdating(); ... .) 在代码之前你必须开始一个活动 并且在 API 19 (KITKAT) 中添加了转换,因此您需要在此之前检查不是 LOLLIPOP -- youtube.com/watch?v=K3yMV5am-Xo 问题是 - 正如我在第一行中所说的那样 - 活动(即使在 Lollipop+ 上)最常从过渡开始,而不是当用户从导航开始活动时抽屉。 不确定你的意思,但你可以等一会,直到导航抽屉关闭,如果这是一个问题,然后再做一些事情 -- developer.android.com/intl/ru/reference/android/support/v4/… 从导航抽屉打开活动时,我没有共享元素(ImageView)来为下一个活动设置动画。 (从其他地方开始活动时,我有共享元素。) 【参考方案1】:您可以尝试onTransitionStart
of TransitionListener
设置一些布尔值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();
【讨论】:
不错且简单的解决方案。 :) 但这不会产生一个可能的问题——因为回调意味着异步执行,难道即使动画即将到来,onStart 会在 onTransitionStarted 被调用之前被调用吗? 事实上,我只是对其进行了测试,正如我所说的那样——在我的例子中,onStart 总是在任何回调之前被调用,所以 isAnimationStarted 在那里总是假的。因此,这种方法当然无助于确定活动是否在有/没有过渡的情况下启动。 您找到正确的方法了吗?正如@NeverwinterMoon 的评论所说,这并不能完全解决问题。【参考方案2】:由于您要启动 Activity
,因此您将使用 Intent
启动它。您可以向Intent
s 添加额外内容,并在被调用的Activity
的onCreate()
中检查它们。
假设我们有 2 个活动 – ActivityA
和 ActivityB
。
现在,假设ActivityA
是调用Activity
,而ActivityB
是调用Activity
。
在ActivityA
中,假设您编写了一些代码来以ActivityB
开头SharedElementTransition
。
@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
extra。我传递了一个 Boolean
值为 true 的值,因为我打算使用 SharedElementTransition
启动 Activity。
现在在ActivityB
的onCreate()
方法中,您可以只检查传递给Intent
的布尔值。如果你传递了 false,那么你可以添加一个条件语句并在那里执行你的 UI 更新。我在下面给了你一个小sn-p来帮助你开始:
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
这样做的好处是,您可以完全控制内容转换和共享元素转换的播放方式。
【讨论】:
以上是关于如何知道一项活动是不是在没有过渡的情况下开始?的主要内容,如果未能解决你的问题,请参考以下文章