2

Я пытаюсь сделать переход на общий элемент Android 5.0 в ситуации «Мастер-деталь» из ListView. Я отправляю изображение.Слишком долгое изменение перехода в Android Lollipop

Я столкнулся с переходом на переход ввода, где изображение не перемещается вообще, пока активная активность переходит. После загрузки детали Detail изображение начинается в левом верхнем углу экрана и оживляет его окончательное местоположение. Возвратный переход работает отлично - изображение оживляет от его детализации до правильной позиции в Master.

Вот как это выглядит: https://www.youtube.com/watch?v=AzyA8i27qWc

Я настроил разрешения правильно, я считаю, и указанный переход:

<item name="android:windowContentTransitions">true</item>   
<item name="android:windowAllowEnterTransitionOverlap">true</item> 
<item name="android:windowAllowReturnTransitionOverlap">true</item> 

<!-- specify shared element transitions --> 
<item name="android:windowSharedElementEnterTransition"> 
    @transition/change_image_transform</item> 
<item name="android:windowSharedElementExitTransition"> 
    @transition/change_image_transform</item> 

Этот переход определяется как:

<transitionSet xmlns:android="http://schemas.android.com/apk/res/android"> 
    <changeImageTransform/> 
    <changeBounds/> 
    <changeTransform/> 
</transitionSet> 

Я дал двум представлениям тот же уникальный атрибут transitionName, что и их позиция в списке.

Я использую makeSceneTransitionAnimation сделать анимацию:

View photo = (View) adapter.getView(position, null, listView).findViewById(R.id.photo); 
    View navigationBar = findViewById(android.R.id.navigationBarBackground); 

    ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(this, 
      Pair.create(photo, photo.getTransitionName()), 
      Pair.create(navigationBar, Window.NAVIGATION_BAR_BACKGROUND_TRANSITION_NAME)); 

    Bundle extras = new Bundle(); 
    Patient selectedPatient = patientList.get(position); 
    extras.putParcelable("patient", selectedPatient); 
    extras.putInt("position", position); 

    Intent intent = new Intent(PatientListActivity.this, PatientActivity_.class); 
    intent.putExtras(extras); 

    startActivity(intent, options.toBundle()); 

(я также с указанием как разделяемая Панель навигации, чтобы избежать его выведения, который работает отлично)

Я не понимаю почему обратный переход работает нормально, но переход ввода не делает. Я видел другие вопросы, когда решение заключалось в том, чтобы задержать переход ввода, который я пытался сделать, но проблема остается. Вот что я добавил к OnCreate в моей Detail деятельности:

super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_patient); 

    patient = getIntent().getExtras().getParcelable("patient"); 
    patient = app.getPatientByName(patient.getName()); 

    patientPhotoView.setImageDrawable(patient.getPhoto()); 

    /* Set up transition functionality */ 
    position = getIntent().getExtras().getInt("position"); 
    patientPhotoView.setTransitionName("patientPhoto" + position); 
    patientNameView.setTransitionName("patientName" + position); 

    postponeEnterTransition(); 
    final ViewTreeObserver observer = getWindow().getDecorView().getViewTreeObserver(); 
    observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { 
     @Override 
     public boolean onPreDraw() { 
      final ViewTreeObserver observer = getWindow().getDecorView().getViewTreeObserver(); 
      observer.removeOnPreDrawListener(this); 
      startPostponedEnterTransition(); 
      return true; 
     } 
    }); 

В моей Detail деятельности, нет transitionName элемента, но я устанавливаю его в коде. Соответствующая часть входящей деятельности (Деталь):

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:app="http://schemas.android.com/apk/res-auto" 
android:id="@+id/drawer_layout" 
xmlns:tools="http://schemas.android.com/tools" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
tools:context=".PatientActivity"> 
    <LinearLayout 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:orientation="vertical"> 
     <RelativeLayout 
      android:layout_width="match_parent" 
      android:layout_height="200dip" 
      android:orientation="vertical" 
      android:id="@+id/patient_top_layout"> 
      <ImageView 
       android:id="@+id/patientPhoto" 
       android:layout_width="92dip" 
       android:layout_height="92dip" 
       android:layout_below="@+id/connectionBar" 
       android:layout_marginRight="12dip" 
       android:layout_marginTop="12dip" 
       android:contentDescription="Patient photo" 
       android:src="@drawable/ic_profile_default" /> 
     </RelativeLayout> 
    </LinearLayout> 
</RelativeLayout 

С радостью опубликуйте другой соответствующий код. Есть идеи?

решаемые

Пользователь Chris P на странице Android Development Google+ понял это для меня. В моей Мастер деятельности в методе OnClick, я имел:

View photo = (View) adapter.getView(position, null, listView).findViewById(R.id.photo); 

Решение было заменить эту строку с:

View photo = (View) listView.getChildAt(position).findViewById(R.id.photo); 

Я думаю, вызвав метод GetView адаптера был воссоздающий сам вид - Я предполагаю, что этот метод должен ТОЛЬКО быть вызван при первом создании списка.

+0

Есть ли разница, если вы измените '@ transition/change_image_transform' на' @ transition/change_image_transform'? Есть ли разница, если вы измените 'getWindow(). GetDecorView()' на объект shared image 'ImageView', который вы используете? –

+0

Я не понимаю вашего первого предложенного изменения. Я также добавил код change_image_transform к вопросу. Не было никакой разницы, когда я изменил 'getWindow(). GetDecorView()' на 'patientPhotoView' (после установки имени перехода и фотографии). –

+0

Ой, извините. У меня была опечатка. Есть ли разница, если вы меняете '@ transition/change_image_transform' на' @android: переход/перемещение'? –

ответ

2

Пытался оставить это в комментариях, но он был слишком длинным. Я опробовал ваш макет и не имел никаких проблем. Мне даже не нужен запрос postponeEnterTransition. Это делает вещи немного сложнее для отладки.

Способ перехода - это захват состояния вещей перед изменением, а затем после изменения, а затем оживление разницы. В Activity Transitions изменение «до» вытягивается из местоположения экрана и размера общего элемента в вызывающей активности.Затем он применяет эти границы к текущей иерархии представлений. Затем он запрашивает макет и фиксирует состояние «после».

Существует чувствительная точка между временем захвата состояния «до» и захватом состояния «после». Если изменения по какой-либо причине там, где значения будут записаны в состоянии after, это не просто ретрансляция состояния «раньше», переход будет отменен. Также возможно внести изменения в макет сразу после начала перехода.

Вы используете механизм загрузки с задержкой или вы действительно полностью загружаете пациента в вызов onCreate? Вы устанавливаете все окружающие ценности в то время? Я вижу, что у вас есть:

 <ImageView ... 
      android:layout_below="@+id/connectionBar" 
      ... /> 

Таким образом, вы можете получать ретранслятор после изменения соединения.

+0

Спасибо за этот ответ. Я думаю, что я попытаюсь отрезать разделы моего кода, пока не узнаю, что вызывает ретранслятор, если он есть. Я попытаюсь подробно изложить свои выводы здесь, чтобы помочь другим, как только я его разрешу. –

+0

Я воссоздал свое обстоятельство из голого проекта и все еще получаю сбой. Мне, должно быть, что-то не хватает - возможно, мой адаптер массива странный? Если проблема связана с ретрансляцией, у меня нет подсказки, где это произойдет, поскольку ничего не происходит. Вот он: https://github.com/clay-to-n/shared-element-transition-glitch –

+0

Решил проблему и добавил решение вопроса. Спасибо за помощь. –

Смежные вопросы