
fragment to fragment
A 에서 B 로 이동한다고 하면
fragment_a.xml
효과를 적용시킬 view에 transitionName 을 지정한다.
<ImageView
android:id="@+id/first_logo_iv"
android:layout_width="100dp"
android:layout_height="100dp"
android:src="@drawable/img_gromit"
android:transitionName="moveTransition"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.315" />
fragment_b.xml
마찬가지로 똑같은 이름을 지정해준다.
이름은 고유해야한다.
<ImageView
android:id="@+id/second_logo_iv"
android:layout_width="300dp"
android:layout_height="300dp"
android:src="@drawable/img_gromit"
android:transitionName="moveTransition"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
transistion.xml을 준비해야한다.
res에 transistion 디렉토리를 생성한다.
그리고 xml을 생성한다.
transition_move.xml
<?xml version="1.0" encoding="utf-8"?>
<transitionSet>
<changeBounds/>
</transitionSet>
AFragment.java
효과를 적용시킬 view와 view의 transistionName 을 addSharedElement의 인자로 넘겨준다.
FragmentNavigator.Extras extras = new FragmentNavigator.Extras.Builder()
.addSharedElement(binding.firstLogoIv, binding.firstLogoIv.getTransitionName())
.build();
Navigation.findNavController(inflateView).navigate(
R.id.action_homeFragment_to_homeSubFragment,
null,
null,
extras);
이때 실제로 코드를 적용하면 extras에 빨간 밑줄이 생기고
타입이 안 맞다고 뭐라하는데 그냥 실행해도 된다.
공식문서를 찾아봤는데 결국 같은 타입이였다구...
BFragment.java
setSharedElementEnterTransition(TransitionInflater.from(mContext).inflateTransition(R.transition.transition_move));
효과를 적용하면 다음과 같다.
RecyclerView to fragment
리사이클러뷰에서 다음과 같이 효과를 적용하고 싶다면..!
adapter.java
onBindViewHolder()에서 transitionName 을 다음과 같이 지정한다.
위에서 말했듯 이름은 고유해야하기 때문에..!!
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
if (holder instanceof ItemViewHolder){
((ItemViewHolder) holder).binding.itemPostImg.setTransitionName("name" + position);
...
}
}
그리고 화면 이동할 때 위에서 했던 것 처럼 인자로 넣어주면 된다.
다만 좀 다른 것은 해당 transitionName도 넘겨주어야한다는것!
공유하려는 대상 간의 이름이 같아야하기 때문
MainFragmentDirections.ActionMainFragmentToSubFragment action
= MainFragmentDirections.actionMainFragmentToSubFragment(binding.itemPostImg.getTransitionName());
action.setPostId(post.getId());
FragmentNavigator.Extras extras = new FragmentNavigator.Extras.Builder()
.addSharedElement(binding.itemPostImg, binding.itemPostImg.getTransitionName())
.build();
Navigation.findNavController(binding.getRoot()).navigate(action, extras);
다음 화면에서 이름을 지정해주고 transition 또한 지정해주면 된다.
String transitionName = SubFragmentArgs.fromBundle(getArguments()).getTransitionName();
binding.subPostImg.setTransitionName(transitionName);
setSharedElementEnterTransition(TransitionInflater.from(mContext).inflateTransition(R.transition.change_bounds));
흠 그런데 위의 것보다 효과가 마음에 들지 않는다..
화면 전환에 대해 좀 더 공부해야할 것 같다.
References
아래 글을 참고하여 작성 되었습니다.
https://yoon-dailylife.tistory.com/74
https://stackoverflow.com/questions/42408748/shared-transition-doesnt-work-recyclerview-to-fragment