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

FragmentTransaction.replace() Переход с постепенным переходом показывает фрагмент "призрак"

Вы можете загрузить весь мой проект, чтобы попробовать и отладить. Вот репо всего моего кода: https://bitbucket.org/lexic92/studio48/


У меня есть "призрачный фрагмент", появляющийся при переходе, когда я пытаюсь заменить пустой фрагмент на пустой фрагмент.

Как воссоздать проблему: У меня есть ящик для навигации, и когда я нажимаю на элемент, он открывает фрагмент, заполняющий весь экран.

Ящик навигации:

  • Кнопка 1 - фрагмент с текстом
  • Кнопка 2 - Фрагмент пустой =

    • Когда я открываю приложение, он начинается с фрагмента с текстом. Затем я открываю навигационный ящик и нажимаю кнопку 2. Переход плохой и превращается в пустой экран в течение секунды секунды, а затем переключается обратно на затухающий текст, пока он не станет пустым экраном.

    • Если я открою навигационный ящик и снова нажму кнопку 2, он исчезнет из полного текста на пустой экран. Таким образом, за одну сплит-секунду, он показывает фрагмент с текстом, когда он не должен.. Я пропустил мое приложение в режиме отладки, шаг за шагом, чтобы замедлить его и убедиться, что это поведение на самом деле произошло.

    • Если я открою навигационный ящик и снова нажмем кнопку 2 в третий раз, он правильно не отображает анимации, потому что он исчезает на том же экране.

Кто-нибудь знает, почему это происходит? Считаете ли вы, что это имеет какое-либо отношение к навигационному ящику?

Вот репо всего моего кода: https://bitbucket.org/lexic92/studio48/

Вот некоторые фрагменты кода:

SongDetailActivity.java:

      @Override
      public void onNavigationDrawerItemSelected(int position) {
        // update the main content by replacing fragments
        FragmentManager fragmentManager = getSupportFragmentManager();

        //OPEN THE BLANK SCREEN
        if(position == 1) {
            fragmentManager.beginTransaction()
                    //.setCustomAnimations(R.anim.fade_in, R.anim.fade_out)
                    .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
                    .replace(R.id.songlist_detail_container, PlaceholderFragment.newInstance(position + 1, mSongId))
                    .commit();
        }
        //OPEN THE SCREEN WITH TEXT
        else {
            SongDetailFragment sdf = new SongDetailFragment();
            Bundle args = new Bundle();
            args.putString(SongDetailFragment.ARG_ITEM_ID, mSongId);
            sdf.setArguments(args);
            fragmentManager.beginTransaction()
                    //.setCustomAnimations(R.anim.fade_in, R.anim.fade_out)
                    .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
                    .replace(R.id.songlist_detail_container, sdf)
                    .commit();
        }
    }

Такая же проблема возникает, когда я комментирую две строки, которые говорят ".setTransition", и не комментируют две строки, которые говорят ".setCustomAnimations". Вот пользовательские анимации:

Рез/аним/fade_out.xml:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
           android:duration="@android:integer/config_mediumAnimTime" />
</set>

Рез /Anim/fade _in.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
           android:duration="@android:integer/config_mediumAnimTime" />
</set>

Как я могу заставить его перейти плавно без появления "призрачного" фрагмента?

Спекуляции. Я запускаю с android.support.v7.app.ActionBarActivity, minSdkVersion == 15 и targetSdkVersion == 21, на физическом устройстве Google Nexus 5 (не эмуляторе).

Мои предположения о ответе:

Этот веб-сайт, похоже, дает мне подсказку: http://gotoanswer.com/?q=Android+Animation+within+a+Fragment+not+working

Лично для меня это ошибка с zPosition для фрагмента анимации.

То, что вы видите, это новый фрагмент, "появляющийся", потому что новый фрагмент прикреплен под текущей.

Итак, при попытке анимировать фрагмент "Над вершиной" существующего фрагмент, кажется, что ничего не происходит, тогда новый 'Появляется'.

Я пробовал много работы, играя с zPosition (влияет только на окна не макеты, поэтому никакого эффекта на фрагменты), onAnimationCreate() приведение корневой компоновки вперед или даже при запуске анимации и stop... кажется, ничего не делает.

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

Возможно, вам придется играть..add(Fragment), ожидая добавления, затем вызовите .remove(Fragment), удалив старый фрагмент, таким образом, новый фрагмент физически помещается поверх существующего фрагмента.

Я заметил, что этот код вызывается при создании SongDetailActivity.java, даже если я не нажимаю на ящик навигации:

//OPEN THE SCREEN WITH TEXT
            else {
                SongDetailFragment sdf = new SongDetailFragment();
                Bundle args = new Bundle();
                args.putString(SongDetailFragment.ARG_ITEM_ID, mSongId);
                sdf.setArguments(args);
                fragmentManager.beginTransaction()
                        //.setCustomAnimations(R.anim.fade_in, R.anim.fade_out)
                        .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
                        .replace(R.id.songlist_detail_container, sdf)
                        .commit();
            }

Может быть, текущий фрагмент исчезает в этом "базовом" фрагменте, как предлагает цитата, перед тем, как затухать в новом фрагменте?

Что я закончил делать

Примечание. Я не ставил это как ответ, потому что он не дает технически ответа на мой вопрос, но это лучшее решение для резервного копирования, которое я могу придумать.

Я попробовал посмотреть, была ли проблема решена, когда анимации не было. "Фрагмент-призрак" не появился, но я заметил, что потребовалось несколько секунд, чтобы загрузить фрагмент, который выглядел резким и уродливым. Я хотел иметь гладкое гладкое приложение, и если он не был гладким, когда не было анимации, то, вероятно, он будет безнадежным, даже если бы я исправил ошибку фрагмента призрака. Я узнал, что фрагменты просто искажены (см. здесь).

Я решил скрыть и показать взгляды. Вот мой новый код:

SongDetailActivity.java

//---------- NAVIGATION DRAWER -------------
    @Override
    public void onNavigationDrawerItemSelected(int position) {

        //HOME
        if (position == 0) {

        }
        //LYRICS
        else if(position == 1) {
            findViewById(R.id.lyrics).setVisibility(View.VISIBLE);
            findViewById(R.id.info).setVisibility(View.INVISIBLE);

        }
        //INFO
        else if(position == 2) {
            findViewById(R.id.info).setVisibility(View.VISIBLE);
            findViewById(R.id.lyrics).setVisibility(View.INVISIBLE);
        }
    }

Я также скопировал и вставил макеты для 2 фрагментов (пустого и одного с большим количеством текста) в тот же макет, что и дети родителя FrameLayout:

fragment_songlist_detail.xml:

<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_height="match_parent"
    android:background="#f8bbd0"
    android:layout_width="match_parent"
    >
    <LinearLayout
        android:id="@+id/lyrics"
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        xmlns:android="http://schemas.android.com/apk/res/android">
    ...
    </LinearLayout>
    <LinearLayout
        android:id="@+id/info"
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        xmlns:android="http://schemas.android.com/apk/res/android">
    ...
    </LinearLayout>
</FrameLayout>

Он отлично работает, но я просто не знаю, как заставить его исчезать и исчезать. Но это вопрос для отдельного вопроса о переполнении стека. Если кто-то решает загадку фрагмента призрак, мне очень интересно узнать ответ. Но я решил, что не собираюсь тратить время на то, чтобы понять это сейчас, особенно когда переходы фрагментов оказались в прошлом ошибками (например, article).

4b9b3361

Ответ 1

сделайте это для всех ваших вызовов транзакций

fragmentManager.beginTransaction().setTransition(FragmentTransaction.
                            TRANSIT_FRAGMENT_FADE).remove(current_fragment).commit();
fragmentManager.beginTransaction().add(R.id.songlist_detail_container, PlaceholderFragment.
                           newInstance(position + 1, mSongId)).commit();

Посмотрите, помогает ли это. Идея состоит в том, чтобы сначала зафиксировать удаление после фиксации добавления. вы также можете выбрать FragmentManager.hide(Fragment);