2016-07-26 3 views
15

Я пытаюсь добавить переход общего элемента в свое приложение.Переход общего элемента: активность во фрагмент, вложенный в другую активность

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

Это прекрасно работает, если общий вид размещается непосредственно в макете целевой деятельности. Работает сглаженно для анимации ввода/выхода. Но когда я пытаюсь добиться аналогичного эффекта в пределах фрагмент который находится в вложенным в целевом действии этого подхода не работает. Смешно, что анимация ввода не отображается, но анимация выхода работает нормально.

Другая еще более сложная иерархия представлений заключается в том, что если целевой просмотр (ImageView) размещен в представлении пейджера, который размещается в макете кадра целевой активности.

У кого-то была такая же проблема?

Edit: Моего нажмите слушатель код

public class OnClickPicture extends OnClickBase { 
    private ObjectPicture object; 

    public OnClickPicture(Activity_Parent activity, ObjectPicture object) { 
    super(activity); 
    this.object = object; 
    } 

    public void onClick(View v) { 

    picasso.load(object.getFullUrl()).fetch(); 
    Intent intent = new Intent(activity, ActivityPicture.class); 
    intent.putExtra("picture_object", helper.gson.toJson(object)); 

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && v != null) { 
     Pair<View, String> p1 = Pair.create(v, "image"); 
     ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(activity, p1); 
     activity.startActivity(intent, options.toBundle()); 
    } else { 
     activity.startActivity(intent); 
    } 

    } 

} 

ответ

21

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

В вашем случае это не происходит, потому что, поскольку stated in the docs, все FragmentTransaction.commit() - это работа по расписанию. Это происходит не сразу. Поэтому, когда среда создает свою активность, она не может найти представление, которое вы хотите оживить. Вот почему вы не видите анимацию записи, но вы видите анимацию выхода. Вид есть, когда вы покидаете действие.

Решение достаточно простое. В первую очередь вы можете попробовать FragmentManager.executePendingTransactions(). Этого может быть недостаточно. Рамка переходов имеет другое решение:

В onCreate of Activity postponeEnterTransition(). Это говорит платформе ждать, пока вы скажете, что ее безопасно создать анимацию. Это означает, что вам нужно сказать, что его сейф (через звонок startPostponedEnterTransition()) в какой-то момент. В вашем случае это, вероятно, будет в Fragments onCreateView.

Вот пример того, как это может выглядеть следующим образом:

активность B

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    // etc 
    postponeEnterTransition(); 
} 

Фрагмент B

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
    View sharedView = root.findViewById(R.id.shared_view); 
    sharedview.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { 
     @Override 
     public boolean onPreDraw() { 
      sharedview.getViewTreeObserver().removeOnPreDrawListener(this); 
      getActivity().startPostponedEnterTransition(); 
      return true; 
     } 
    }); 
} 

Благодаря Алекс Локвуд за его detailed blog posts about the Transitions framework.

+0

Вы также можете достичь этого, не добавляя OnPreDrawObserver. Просто переопределите onViewCreated в вашем фрагменте и вызовите startPostponedEnterTransition() там – Daveloper87

+0

Идеальное и чистое объяснение. благодаря – GvSharma

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