Переходы общих элементов не работают в сочетании с CoordinatorLayout и CollapsingToolbarLayout

Главный экран моего приложения содержит изображения в виде сетки. Когда пользователь выбирает изображение, детальное действие запускается с использованием перехода общего элемента, который анимирует выбранное изображение сетки в парное изображение, расположенное в CardView в подробном действии.

После обновления моего XML-макета подробного представления для включения CoordinatorLayout вместе с CollapsingToolbarLayout переход общего элемента перемещает представление изображения в неправильное место в действии деталей (действие «ввод»). Фреймворк, кажется, принимает смещение всего AppBarLayout и внутреннего CollapsingToobarLayout и анимирует приблизительное положение, в котором было бы изображение, если бы над CardView, содержащим целевое представление изображения, не было CollapsingToolBarLayout.

Проблема может быть продублирована в примере приложения cheesesquare Криса Бэйнса, добавив ImageView (с именем перехода) к любому один из 3 CardView в файле activity_detail.xml:

<ImageView
 android:id="@+id/imageView"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:src="@mipmap/ic_launcher"
 android:transitionName="sharedImage" />

а затем настройте переход общего элемента в onBindViewHolder в CheeseListFragment.java следующим образом:

@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
        holder.mBoundString = mValues.get(position);
        holder.mTextView.setText(mValues.get(position));

        holder.mView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Context context = v.getContext();
                Intent intent = new Intent(context, CheeseDetailActivity.class);
                intent.putExtra(CheeseDetailActivity.EXTRA_NAME, holder.mBoundString);

                holder.mImageView.setTransitionName("sharedImage");                        
                ActivityOptionsCompat options = ActivityOptionsCompat.
                        makeSceneTransitionAnimation(
                                getActivity(v.getContext()),
                                            holder.mImageView,                     
                                            "sharedImage");
                ActivityCompat.StartActivity((MyActivity) context, intent, options.toBundle());
            }
        });

        Glide.with(holder.mImageView.getContext())
                .load(Cheeses.getRandomCheeseDrawable())
                .fitCenter()
                .into(holder.mImageView);
    }

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

Приветствуются любые мысли о возможных обходных решениях.


comment
Я нашел исправление этой проблемы, и оно есть в моем репозитории github.com/lawloretienne/SharedElementTransition   -  person toobsco42    schedule 02.05.2016


Ответы (2)


Ответ прост, макет cheesesquare activity_detail.xml вкратце выглядит так ...

<android.support.design.widget.CoordinatorLayout 
    android:fitsSystemWindows="true"
    ...>

    <android.support.design.widget.AppBarLayout
        android:fitsSystemWindows="true"
        ...>

        <android.support.design.widget.CollapsingToolbarLayout
            android:fitsSystemWindows="true"
            ...>

            <ImageView
                android:fitsSystemWindows="true"
                ... />

            <android.support.v7.widget.Toolbar
                ... />

        </android.support.design.widget.CollapsingToolbarLayout>

     </android.support.design.widget.AppBarLayout>

     <android.support.v4.widget.NestedScrollView
         app:layout_behaviour="@string/appbar_scrolling_view_behaviour"
         ...>

</android.support.design.widget.CoordinatorLayout>

Что не так с этим макетом, так это то, что свойство android: fitsSystemWindows необходимо распространить вниз по цепочке макета на ВСЕ контейнеры, а в опубликованном демонстрационном приложении это свойство отсутствует для NestedScrollView. Изменение NestedScrollView на

     <android.support.v4.widget.NestedScrollView
         app:layout_behaviour="@string/appbar_scrolling_view_behaviour"
         android:fitsSystemWindows="true"
         ...>

устраняет проблему. Вероятно, это следует изменить в демонстрационном коде Github.

person Monte Creasor    schedule 03.11.2015
comment
У меня все еще мерцает панель навигации и строка состояния, когда у меня есть макет, похожий на макет экрана подробностей Cheesesquare. Как исправить это для перехода к общим элементам? - person toobsco42; 27.04.2016
comment
Ответ можно найти в этом посте. stackoverflow.com/questions/26600263/ - person Monte Creasor; 30.04.2016

Решено!

Если кто-то сталкивается с этой ошибкой, когда они используют макет координатора, который состоит из общих элементов, которые во время перехода общего элемента от предыдущего действия к действию, содержащему макет координатора, неправильно размещаются во время анимации перехода. Это ошибка в версии библиотеки поддержки дизайна "com.android.support:design:22.2.0".

Решение:

Измените версию на "com.android.support:design:23.1.0" в build.gradle ( приложение)

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

person Udit Kapahi    schedule 18.12.2015
comment
Извините, Удит, но ваше решение не решает проблему. Я только что протестировал его с дизайном: 23.1.1, и он все еще отображается. Просто перейдите к параметрам разработчика вашего телефона и замедлите анимацию в 5 раз, и вы сможете увидеть деформацию. Мой тест был на Nexus 6 API 22 (эмулятор). Добавление атрибута fitSystemWindows в NestedScrollView устраняет проблему, как я уже упоминал ниже. - person Monte Creasor; 25.03.2016
comment
По-прежнему возникают проблемы с дизайном 23.3.0 :( какое-нибудь решение? - person Sdghasemi; 23.07.2016