Android Fragment 알아보자

bang·2022년 2월 26일
1

Fragment

목록 보기
1/2
post-thumbnail

Fragment의 Design 철학

Android가 프래그먼트를 처음 도입한 것은 Android 3.0(API 레벨 11)부터입니다. 기본적으로 태블릿과 같은 큰 화면에서 보다 역동적이고 유연한 UI 디자인을 지원하는 것이 목적이었습니다.

예를 들어 뉴스 애플리케이션이라면 A프래그먼트는 왼쪽에 기사 목록을 표시하고, B프래그먼트는 오른쪽에 기사 내용을 표시할 수 있습니다. 화면이 큰 태블릿에서는 하나의 Activity에서 목록과 내용을 한번에 나타낼수 있고, 반면 모바일 기기에서는 A, B 프래그먼트를 각각의 Activity에 나타낼 수 있습니다.


Fragment란?

Fragment는 앱 UI의 재사용 가능한 부분을 나타냅니다. Fragment는 자체 레이아웃을 정의 및 관리하고, 자체 수명 주기를 가지며, 자체 입력 이벤트를 처리할 수 있다. Fragment는 단독으로 존재할 수 없으며 Activity나 다른 Fragment에 의해 호스팅되어야 합니다. Fragment의 보기 계층은 호스트의 보기 계층 구조의 일부가 되거나 호스트에 연결됩니다.

여기서 중요한 키워드는 재사용 , 자체 수명 주기 , 단독으로 존재 불가

Fragment는 Android Jetpack 라이브러리의 Navigation, BottomNavigationView 및 ViewPager2와 함께 작동하도록 설계되었습니다.


Fragment 만들기


  • gradle 설정
	dependencies {
	    def fragment_version = "1.4.1"
	
	    // Java language implementation
	    implementation "androidx.fragment:fragment:$fragment_version"
	    // Kotlin
	    implementation "androidx.fragment:fragment-ktx:$fragment_version"
	}

  • Fragment 클래스 만들기
	public Fragment() {
        initLifecycle();
    }
    
    @ContentView
    public Fragment(@LayoutRes int contentLayoutId) {
        this();
        mContentLayoutId = contentLayoutId;
    }

          Fragment 생성자는 위처럼 2가지가 있습니다.


	class AFragment: Fragment() { }
    class AFragment: Fragment(R.layout.fr_a) { }

상속으로 간단하게 프래그먼트를 만들 수 있고, 두번째 생성자 레이아웃 id로 생성하면
onCreateView를 override 하지 않아도 UI를 구성할 수 있습니다.


Activity에 추가하기

 앞서 소개했듯이 Fragmnet는 단독으로 존재할 수 없습니다. 따라서 Fragment는 FragmentActivity 에 포함되어 있어야 합니다. 기본적으로 프로젝트 생성시 AppCompatActivity로 생성 되어 있고 AppCompatActivity는 FragmentActivity는 상속하고 있어서 바로 사용할 수 있습니다.

 AppCompatActivity는 결국 Activity를 상속하고 있고 하위 버전과 호환을 위한 클래스 입니다.
AppCompatActivity에 관한 내용은 여기 를 읽어보셔도 좋을것 같습니다.

Activity xml에 FragmentContainerView를 추가해 줍니다.

<androidx.fragment.app.FragmentContainerView
   	 android:id="@+id/fragment_container_view"
   	 android:name="com.example.test.AFragment"
   	 android:tag="AFragment"
   	 android:layout_width="match_parent"
   	 android:layout_height="match_parent" />

  • FragmentContainerView

     기존에 FrameLayout에 동적으로 프래그먼트를 생성하는 방식에서 FragmentContainerView가 새롭게 도입되었습니다. FragmentContainerView는 FrameLayout을 상속하고 있고, 프래그먼트에 대한 z-ordering 처리가 개선되었다는 것입니다.
     예를 들어 두 프래그먼트 간의 exit 및 enter 전환이 서로 겹치지 않음을 의미합니다. 대신 이 FragmentContainerView는 종료 애니메이션을 먼저 시작한 다음 시작 애니메이션을 시작합니다.
    https://youtu.be/RS1IACnZLy4?t=548

  • 주의점
    name 속성에 Fragment를 넣고 id 속성을 추가하지 않으면
    🔴 FragmentContainerView must have an android:id to add Fragment...
    프래그먼트를 추가하기 위해 id속성이 있어야한다고 오류가 나기때문에
    name을 사용할때 android:id 속성 필수 입니다!

Programmatically 방식으로 추가하기

  • 위처럼 FragmentContainerView의 name에 프래그먼트를 명시적으로 지정해서 추가할 수 있지만 프로그래밍 방식으로 동적으로 추가하는 방법도 있습니다.
  • FragmentContainerView은 그대로 사용하고 name 속성을 제거해 줍니다.
class ExampleActivity : AppCompatActivity(R.layout.example_activity) {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        if (savedInstanceState == null) {
            supportFragmentManager.commit {
                setReorderingAllowed(true)
                add<AFragment>(R.id.fragment_container_view)
            }
        }
    }
}
  • Activity의 onCreate에서 중요! savedInstanceState가 null일때 FragmentManager를 가져와 FragmentTransaction의 add로 container id에 프래그먼트를 추가할 수 있습니다.

  • 왜 savedInstanceState가 null일때라는 조건문 안에서 프래그먼트를 추가해줘야 할까❓

    • Activity가 시스템에 의해 또는 화면 회전으로 Actity가 재생성 될때 savedInstanceState가 not null이기 때문에 자칫 프래그먼트가 중복 생성이 되기때문입니다.

    • Activity의 Lifecycle 생명주기에서 onPause() -> onStop() -> onSavedInstanceState() 순서로 호출되고, 다른 Activity로 이동하거나, 백그라운드로 화면 이동, 화면 회전 등이 일어날때 onSavedInstanceState()가 호출되고, 사용자가 명시적으로 뒤로가기 또는 finish() 함수로 Activity를 종료했을때는 호출 되지 않습니다. Activity Lifecycle


onSavedInstanceState() 언제 사용할까❓

간단하고 가벼운 UI 상태 저장 ( 화면이 재생성 될때 보고있던 화면의 데이터를 그대로 유지하기위해 )
onSavedInstanceState()가 데이터를 디스크에 직렬화하기 때문에 저장용량 및 속도에 의해 제한됩니다. 직렬화될 객체가 복잡하면 직렬화 시 많은 메모리가 소비될 수 있습니다. 직렬화 프로세스는 구성 변경 시 기본 스레드에서 발생하기 때문에 직렬화가 장기적으로 실행되면 프레임 하락 및 시각적인 끊김 현상이 발생할 수 있습니다.
비트맵과 같은 대량의 데이터, 또는 길이가 긴 직렬화나 역직렬화가 필요한 복잡한 데이터 구조를 저장하는 데 onSavedInstanceState()를 사용해서는 안 됩니다. 대신 기본 유형 및 String 같은 단순하고 작은 객체만 저장해야 합니다.
예를 들면 텍스트필드 값, 체크박스 상태, 리스트 스크롤 위치 등등..
Save UI states


참고 사이트

0개의 댓글