Подтвердить что ты не робот

OverridePendingTransition не работает, когда используется FLAG_ACTIVITY_REORDER_TO_FRONT

У меня есть два действия в стеке, чтобы показать их, я использую 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), тогда нет проблем.

Можно ли перенести активность на передний план с помощью анимации?

Спасибо большое!

4b9b3361

Ответ 1

Я столкнулся с этой проблемой. Хитрость заключается в переопределении перехода в обратном вызове onResume().

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

Ответ 2

На самом деле правильным решением при использовании REORDER_TO_FRONT является вызов overridePendingTransition в методе onNewIntent() активности, которую вы собираетесь открывать.

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

замените ваши переходы.

Если вам нужно выборочно заменить переход, вы можете добавить дополнительный в своем намерении и проверить его в onNewIntent(), чтобы решить, что делать.

Это не подходит, если вы не знаете, какой переход будет открыт (если вы не укажете его явно, например), но в остальном это правильное решение.

Ответ 3

Вызов

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

для меня решение заключалось в том, чтобы убедиться, что он работает в потоке пользовательского интерфейса

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();

Ответ 5

Мой коллега столкнулся с этой проблемой, и ему удалось решить эту проблему, добавив к нему минимальный атрибут SDK (5 и более).

так как эта функция была доступна с api 5, принудительное использование более высокого уровня sdk помогло нам.

Ответ 6

Как насчет создания анимации в onCreate() или onStart() второго действия.

Ответ 7

У меня такая же проблема. Я предлагаю вам проверить AndroidManifest.xml, чтобы убедиться, что у ActivityA и ActivityB нет набора Theme.Translucent.NoTitleBar, эта тема содержит "android: windowIsTranslucent" = true, что вызывает проблему.

Надеюсь, что это поможет вам.

Ответ 8

Я сделал что-то подобное, и я сделал следующее:

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;
}