RIEN😚
이상한 나라의 개발자
RIEN😚
전체 방문자
오늘
어제
  • 분류 전체보기 (125)
    • Algorithm (68)
      • 알고리즘 (0)
      • Baekjoon (8)
      • 프로그래머스 (55)
      • HackerRank (5)
    • Android (30)
      • Project (1)
      • Error (2)
      • Studio (1)
      • Android (26)
    • Kotlin (6)
    • CS (4)
      • 네트워크 (2)
      • 데이터베이스 (2)
    • Front End (5)
      • React (1)
      • VUE (3)
      • Project (0)
      • 기타 (1)
    • 기록 (11)
      • 회고록 (6)
      • TIL (5)

블로그 메뉴

  • Github🔥
  • 포트폴리오🌹

공지사항

인기 글

티스토리

250x250
반응형
hELLO · Designed By 정상우.
RIEN😚

이상한 나라의 개발자

Android/Android

[Android/Fragments] 1. Fragments란?

2022. 7. 10. 14:03
728x90
반응형

📌Android 기본기 파헤치기 - 1

 

이번에 공부도 해볼겸 Jetpack Navigation을 사용하지 않고!

Fragment만으로 화면 전환을 하는 어플리케이션을 개발해보았습니다.🤗

 

이 때 보았던 Fragments와 관련된 공식 문서 내용을 정리해보고자 합니다.

(틀린 내용이 있다면 꼭! 댓글 남겨주세요.😌)

 

1. Fragments란?

fragment는 재사용이 가능한 UI component입니다.

 

fragment는

- 별도의 layout을 정의하고 관리할 수 있습니다.

- activity와 다른 자신만의 lifecycle을 가지고 있습니다.

- 개별적으로 사용자와 상호작용할 수 있습니다.

🌹 하지만 fragment는 Activity와 같이 혼자서 존재할 수는 없고
반드시 하나의 Activity 또는 다른 fragment 위에서만 사용할 수 있습니다.

또한 fragment의 view 계층은 host view 계층에 속하게 됩니다.

 

2. Modularity(모듈화)

fragment를 대표하는 특징에는 Modularity(모듈화)와 Reusability(재사용성)가 있습니다.

 

Activity에는 navigation drawer처럼 UI 전체에 결처 공통적으로 사용되는 global elements들을 관리하고, fragments에는 단일 화면이나 화면의 일부를 정의하고 관리하는데 적합합니다.

예를 들어, navigation tab에 따라 다른 화면을 보여주어야 하는 앱을 생각해보겠습니다.

이를 Activity로 구현하고자 한다면 어떻게 구현할 수 있을까요?

navigation tab을 누를 때마다 다른 Activity를 호출해서 구현할 수 있을까요? 🧐

 

이렇듯 Runtime 시에 동적으로 화면의 일부분을 전환해야 할 때 Activity는 적합하지 않습니다.🥲

 

이럴 때 사용할 수 있는 것이 바로 fragment입니다!

navigation tab을 클릭할 때마다 위의 그림에서 Fragment UI 부분을 적절한 fragment로 교체해준다면,

Runtime시에 하나의 Activity에서도 동적으로 화면을 전환할 수 있습니다. 😊👍🏻

 

즉!🔥

Activity에서는 navigation에 따른 적절한 fragment를 생성하는 기능만을 담당하고,

생성된 fragment에서는 각각의 화면에 맞는 layout을 서로 독립적으로 생성하고 관리할 수 있습니다.

🌹 Activity의 lifecycle 상태가 STARTED이거나 그 보다 더 높은 상태에서도, fragment를 추가/교체/제거 하면서 동적으로 화면을 구성할 수 있습니다.

또한, fragment 변화를 activity에 의해 관리되는 backstack에 저장해두었다가, 뒤로 이동할 수도 있습니다.

 

3. fragment 생성하는 방법

(1) fragment class 생성하기

먼저 fragment 객체를 위한 class를 정의하기 위해서는

1. AndroidX의 Fragment class를 상속

2. Activity의 생명주기 콜백 메서드를 override하는 것처럼 fragment의 메서드 중 필요한 메서드들을 override

 

👇🏻 fragment의 layout을 정의하는 방법 중, 아래 코드와 같이 Fragment의 기본 상속자로 사용할 layout resource를

전달하여, layout을 생성할 수도 있습니다.

class ExampleFragment: Fragment(R.layout.fragment_example)

 

Fragment 라이브러리는 특정 용도로 사용되는 fragment base class도 제공해줍니다.🤗

📌 DialogFragment

이름 그대로 dialog를 생성하는 Fragment입니다.

🌹 이 방법으로 dialog를 생성하는 것이 Activity에서 dialog helper method를 이용해 dialog를 생성하는 것보다 권장되는 방법입니다.

 

📌 PreferenceFragmentCompat

android의 Preference 객체의 계층 구조를 리스트로 보여주는 Fragment입니다.

주로 setting screen을 만들 때 사용됩니다.😊

 

(2) Activity에서 Fragment 추가하기

Activity에서 Fragment를 사용하기 위해서는 AndroidX의 FragmentActivity를 상속받아야 하.지.만!😳

FragmentActivity는 AppComaptActivity의 base class 이므로, AppCompatActivity를 상속받고 있다면 Fragment를 사용할 수 있습니다.👍🏻

 

Activity의 view 계층에 Fragment를 추가하는 방법은 2가지가 있습니다.

- activty layout file에 fragment 정의하기

- activity layout file에는 fragment container를 정의하고 코드 내에서 추가해주기

 

두가지 방법 모두 layout file 내 Fragment가 위치할 자리에 FragmentContainerView를 추가해주어야 합니다.

🌹 fragment container로는 FrameLayout과 같은 view group보다는 FragmentContainerView를 권장하고 있습니다!
👉🏻 다른 view group에서는 제공되지 않는 fragment를 위한 여러 기능을 별도로 제공하기 때문입니다.🔥

 

그럼 2가지 방법을 하나씩 알아보도록 하겠습니다.😆

📌 2-1. XML에 fragment 정의하기
<!-- res/layout/example_activity.xml -->
<androidx.fragment.app.FragmentContainerView
	android:id="@+id/fragment_container_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:name="com.example.ExampleFragment" />

여기서 중요한 것이 바로 android:name 속성입니다. 이 속성에 Fragment 인스턴스의 클래스 이름을 전달해줍니다.

Activity의 layout 객체가 생성될 때, android:name 속성으로 전달한 특정 fragment 또한 인스턴스화 됩니다.

 

이렇게 인스턴스화 된 fragment에서는 onInflate() 메서드가 호출되고,

FragmentManager에 이 fragment를 새로 추가하기 위해 FragmentTransaction이 생성됩니다.

 

📌 2-2. 코드에서 fragment 정의하기

2-1과 마찬가지로 XML에 FragmentContainerView를 추가해주지만, android:name 속성은 정의하지 않습니다.

<!-- res/layout/example_activity.xml -->
<androidx.fragment.app.FragmentContainerView
	android:id="@+id/fragment_container_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

대신 Activity 내에서 FragmentManager를 이용해서 FragmentTransaction을 생성합니다.

🌹 fragment transaction: fragment를 추가/제거/교체하는 작업의 단위

 

위와 같이 XML에 FragmentContainerView를 추가했다면,

Activity의 onCreate() 메서드에서 FragmentTransaction.add()를 통해 fragment를 초기화해줄 수 있습니다.

- fragment container의 ViewGroup ID

- 추가하고 싶은 fragment의 class

을 전달해주고 commit 해주면 끝입니다! 🤗

class ExampleActivity: AppCompatActivity(R.layout.example_activity) {
	override fun onCreate(savedInstanceState: Bundle?) {
    	super.onCreate(savedInstanceState)
        
        if (savedInstanceState == null) {
        	supportFragmentManager.commit {
            	setReorderingAllowed(true)
                add<ExampleFragment>(R.id.fragment_container_view)
            }
        }
    }
}
🌹 새로운 fragment를 추가할 때 성능을 위해 setReorderingAllowed(true)를 추가하는 것을 권장합니다.

++ supportFragmentManager.commit{} 메서드를 사용하기 위해서는 아래와 같은 dependency 추가가 필요합니다.🥲

implementation "androidx.fragment:fragment-ktx:1.5.0"

 

 

위의 코드를 보면 savedInstanceState가 null일 때만 fragment transaction을 생성하는 것을 볼 수 있습니다.

이는 Activity가 처음 생성될 때 한번만 fragment가 추가되는 것을 보장하기 위해서 입니다.

 

👇🏻🔥 중요!!

🌹 fragment는 자동적으로 savedInstanceState에 저장되기 때문에, Activity가 재생성될 때 다시 추가해줄 필요가 없습니다.

 

만약 Fragment 생성 시 전달해야 하는 초기 데이터가 있다면, FragmentTransaction.add() 메서드에서 아래와 같이 매개변수로 전달할 수 있습니다.

class ExampleActivity: AppCompatActivity(R.layout.example_activity) {
	override fun onCreate(savedInstanceState: Bundle?) {
    	super.onCreate(savedInstanceState)
        
        if (savedInstanceState == null) {
        	val bundle = bundleOf("some_int" to 0)
        	supportFragmentManager.commit {
            	setReorderingAllowed(true)
                add<ExampleFragment>(R.id.fragment_container_view, args = bundle)
            }
        }
    }
}

이렇게 전달된 Bundle 매개변수는 fragment 내에서 requireArguments()를 이용해 접근할 수 있습니다.

class ExampleFragment: Fragment(R.layout.example_fragment) {
	override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    	val someInt = requireArguments().getInt("some_int")
        //
    }
}

 


휴. 이제야 Fragment 기초를 다 끝냈습니다.ㅎㅎ

다음은 Fragment Manager와 Transaction에 대해 공부해보겠습니다.🤗

반응형

'Android > Android' 카테고리의 다른 글

[Android:Codelab] Testing Basic-1  (0) 2023.01.20
[Android/Fragment] 1.1 Fragment 추가 예제 코드 까보기  (0) 2022.07.11
[Android/Fragments] 1. Fragment Manager  (0) 2022.07.11
[Jetpack Compose Codelab-1] Jetpack Compose 기본  (0) 2022.06.01
[Android] RecyclerView 무한스크롤 구현하기  (0) 2022.05.15
    'Android/Android' 카테고리의 다른 글
    • [Android/Fragment] 1.1 Fragment 추가 예제 코드 까보기
    • [Android/Fragments] 1. Fragment Manager
    • [Jetpack Compose Codelab-1] Jetpack Compose 기본
    • [Android] RecyclerView 무한스크롤 구현하기
    RIEN😚
    RIEN😚
    안드로이드 / 코틀린 독학으로 취업하자!

    티스토리툴바