profile image

L o a d i n g . . .

728x90
반응형

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://jtmuller5-98869.medium.com/fragment-transitions-with-shared-elements-using-android-navigation-7dcfe01aacd

    https://stackoverflow.com/questions/42408748/shared-transition-doesnt-work-recyclerview-to-fragment

    728x90
    반응형

    복사했습니다!