본문 바로가기
개발/Android

[Android] Fragment 간 이동 시 애니메이션 넣기

by 준그래머 2023. 11. 30.
반응형

Fragment 이동 시 애니메이션 넣기

구현하려는 시나리오

메인 Fragment는 그대로 있고 새로 들어올 검색 Fragment만 올라오고 내려가는 방식의 애니메이션을 구현하려고 한다.

 

 

애니메이션 xml 구현

anim_slide_up.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <objectAnimator
        android:propertyName = "y"
        android:valueType = "floatType"
        android:valueFrom = "1880"
        android:valueTo = "0"
        android:duration = "200"/>
</set>

위로 올라가는 애니메이션

 

anim_slide_down.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <objectAnimator
        android:propertyName = "y"
        android:valueType = "floatType"
        android:valueFrom = "0"
        android:valueTo = "1880"
        android:duration = "200"/>
</set>

아래로 내려가는 애니메이션

 

anim_no.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <objectAnimator
        android:propertyName = "y"
        android:valueType = "floatType"
        android:valueFrom = "0"
        android:valueTo = "0"
        android:duration = "200"/>
</set>

화면을 움직이지 않게 할 애니메이션. 여기서 duration을 같게 해주지 않으면 제대로 애니메이션이 동작하지 않는 경우를 발견했기 때문에 웬만하면 같은 시간으로 맞춰주자.

 

 

Layout 구현

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <androidx.appcompat.widget.Toolbar
        android:id="@+id/tb"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/gray_F3"
        app:contentInsetStart="0dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        >

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center">
            <Button
                android:id="@+id/btn_trans"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="전환"/>

        </LinearLayout>
    </androidx.appcompat.widget.Toolbar>


    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/fragment_container_view"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/tb" />

</androidx.constraintlayout.widget.ConstraintLayout>

툴바를 두고 아래 FragmentContainerView를 구현해 준다.

 

 

class 코드 구현

이동할 때 커스텀한 애니메이션을 넣어 주고 add 해 준다.

public class MainActivity extends AppCompatActivity {
    private final String TAG = "MainActivity";

    boolean isSearching = false;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        Button btn = findViewById(R.id.btn_trans);
        getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container_view, new BlankFragment1()).commit();

        btn.setOnClickListener(v->{
            isSearching = !isSearching;
            FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
            transaction.setCustomAnimations(R.anim.anim_slide_up, R.anim.anim_no, R.anim.anim_no,R.anim.anim_slide_down);
            if(isSearching) transaction.add(R.id.fragment_container_view, new BlankFragment2());
            else transaction.add(R.id.fragment_container_view, new BlankFragment1());
            transaction.addToBackStack(null);
            transaction.commit();
        });

   }

    @Override
    public void onBackPressed() {
        if(isSearching){
            isSearching = false;
        }
        super.onBackPressed();
    }
}

replace 한 경우 back 했을 때, 기존 fragment가 다시 onCreateView 된다. 하지만 다시 뷰를 만들고 싶지 않아 add를 넣었다.

 

 

setCustomAnimations 파라미터 위치

FragmentTransaction에 구현된 setCustomAnimations 함수

@NonNull
public FragmentTransaction setCustomAnimations(@AnimatorRes @AnimRes int enter,
        @AnimatorRes @AnimRes int exit, @AnimatorRes @AnimRes int popEnter,
        @AnimatorRes @AnimRes int popExit) {
    mEnterAnim = enter;
    mExitAnim = exit;
    mPopEnterAnim = popEnter;
    mPopExitAnim = popExit;
    return this;
}
  • enter는 새로 생성된 Fragment가 들어올 때 사용될 애니메이션
  • exit는 기존에 존재하는 Fragment가 사라질 때 사용될 애니메이션
  • popEnter는 이전에 존재한 Fragment가 들어올 때 사용될 애니메이션
  • popExit는 새로 생성된 Fragment가 사라질 때 사용될 애니메이션

애니메이션 위치가 헷갈릴 수 있지만 몇 번 구현해 보면 대충 감이 잡힐 것 같다.

반응형