使用FLAG_ACTIVITY_REORDER_TO_FRONT时,overridePendingTransition不起作用

时间:2011-01-08 11:02:13

标签: android android-intent transition flags

我在堆栈中有两个活动,为了显示它们我使用FLAG_ACTIVITY_REORDER_TO_FRONT。到目前为止,当我想使用overridePendingTransition为活动带来动画时,问题就出现了。

Intent i = new Intent(ActivityA.this, ActivityB.class);
i.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); 
ActivityA.this.startActivity(i);
overridePendingTransition(R.anim.transition_to_right, R.anim.transition_to_left);

但是,如果没有将标志添加到意图(删除第2行),则不会显示转换,那么就没有问题。

是否可以通过动画将活动带到前面?

非常感谢!

8 个答案:

答案 0 :(得分:37)

实际上,使用REORDER_TO_FRONT时的正确解决方案是在要打开的活动的onNewIntent()方法中调用overridePendingTransition。

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
}

替换你的过渡。

如果您需要有选择地替换转换,您可以在意图中添加额外的内容,并在onNewIntent()中进行检查以确定要执行的操作。

如果您不知道将要打开的转换(例如,如果您没有明确指定它),那么这是不合适的,但是否则是正确的解决方案。

答案 1 :(得分:34)

我遇到了同样的问题。诀窍是覆盖onResume()回调中的转换。

@Override
public void onResume() {
    super.onResume();
    overridePendingTransition(R.anim.transition_to_right, R.anim.transition_to_left);
}

答案 2 :(得分:4)

对我来说,解决方案是确保它在UI线程中运行

runOnUiThread(new Runnable() {
            public void run() {
                startActivity(new Intent(ActivityOne.this, ActivityTwo.class));
                overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
            }
        });

        finish();

答案 3 :(得分:2)

调用

overridePendingTransition(R.anim.transition_to_right, R.anim.transition_to_left);

完成后();结束活动对我有用。

finish();
overridePendingTransition(R.anim.transition_to_right, R.anim.transition_to_left);

这比调用onResume更好,因为它使活动更加独立于进入和退出动画:


完成发件人活动后致电:

活动A ---输入转换1(在A上)--->活动B ---进入转换2(在B上)--->活动C

活动A< ---退出转换1(在B上)---活动B< ---退出转换2(在C上)---活动C

活动A ---输入转换1(在A上)--->活动C ---输入过渡3(在C上)--->活动B

活动A< ---退出转换3(在C上)---活动C< ---退出转换2(在B上)---活动B



调用onResume接收器活动:

活动A ---输入转换1(在B上)--->活动B ---进入转换2(在C上)--->活动C

活动A< ---进入转换1(在A上)---活动B< ---进入转换2(在B上)---活动C

活动A ---输入转换3(在C上)--->活动C ---进入过渡2(在B上)--->活动B

活动A< ---输入转换1(在A上)---活动C< ---进入转换3(在C上)---活动B

这里onResume动画总是必须是相同的,无论它是哪个发送者活动,而是第一种方法,你可以轻松地自定义动画。

答案 4 :(得分:2)

我遇到了同样的问题。 我建议你查看你的AndroidManifest.xml以确保ActivityA和ActivityB都没有设置 Theme.Translucent.NoTitleBar ,这个主题包含“android:windowIsTranslucent”= true导致问题。

希望这对你有所帮助。

答案 5 :(得分:1)

我的同事遇到了这个问题,他设法通过添加最小的SDK属性(5及以上)来解决它。

因为从api 5开始就可以使用这个功能,所以强制使用更高的sdk级别对我们起了作用。

答案 6 :(得分:0)

如何在第二个活动的onCreate()或onStart()中创建动画。

答案 7 :(得分:-2)

我做了类似的事情,我做了如下:

private Stack<String> stack;
ViewAnimator mViewAnimator;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mViewAnimator = new ViewAnimator(this);
    if (stack == null) stack = new Stack<String>();
    push("FirstStackActivity", new Intent(this, FirstStackActivity.class));
}

@Override
public void finishFromChild(Activity child) {
    pop();
}

@Override
public void onBackPressed() {
    pop();
}

public void push(String id, Intent intent) {
    Window window = getLocalActivityManager().startActivity(id, intent);
    if (window != null) {
        stack.push(id);
        View view = window.getDecorView();
        mViewAnimator.setInAnimation(AnimationUtils.loadAnimation(this, R.anim.push_left_in));
        mViewAnimator.setOutAnimation(AnimationUtils.loadAnimation(this, R.anim.push_left_out));            
        mViewAnimator.addView(view);
        mViewAnimator.showNext();
        setContentView(mViewAnimator);
    }
}

public void pop() {
    if (stack.size() == 1) finish();
    if (stack.size() > 0) {
        LocalActivityManager manager = getLocalActivityManager();   
        Intent lastIntent = manager.getActivity(stack.peek()).getIntent();
        Window newWindow = manager.startActivity(stack.peek(), lastIntent);
        View view = newWindow.getDecorView();
        mViewAnimator.setInAnimation(AnimationUtils.loadAnimation(this, R.anim.push_right_in));
        mViewAnimator.setOutAnimation(AnimationUtils.loadAnimation(this, R.anim.push_right_out));
        mViewAnimator.showPrevious();
        mViewAnimator.removeView(view);
    }
    destroy(stack.pop());
}


/**
 * BugFix official
 * @param id
 * @return
 */
public boolean destroy(String id) {
    final LocalActivityManager activityManager = getLocalActivityManager();
    if (activityManager != null) {
        activityManager.destroyActivity(id, false);
        try {
            final Field mActivitiesField = LocalActivityManager.class.getDeclaredField("mActivities");
            if (mActivitiesField != null) {
                mActivitiesField.setAccessible(true);
                @SuppressWarnings("unchecked")
                final Map<String, Object> mActivities = (Map<String, Object>) mActivitiesField.get(activityManager);
                if (mActivities != null) {
                    mActivities.remove(id);
                }
                final Field mActivityArrayField = LocalActivityManager.class.getDeclaredField("mActivityArray");
                if (mActivityArrayField != null) {
                    mActivityArrayField.setAccessible(true);
                    @SuppressWarnings("unchecked")
                    final ArrayList<Object> mActivityArray = (ArrayList<Object>) mActivityArrayField.get(activityManager);
                    if (mActivityArray != null) {
                        for (Object record : mActivityArray) {
                            final Field idField = record.getClass().getDeclaredField("id");
                            if (idField != null) {
                                idField.setAccessible(true);
                                final String _id = (String) idField.get(record);
                                if (id.equals(_id)) {
                                    mActivityArray.remove(record);
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return true;
    }
    return false;
}