본문 바로가기
Development/Android

[Android] Android Fragment의 생성 실전 구현 방법

by 은스타 2019. 9. 6.
반응형
Android Fragment 생성 실전 구현 방법

Android Fragment 생성 실전 구현 방법

Android Fragment는 Activity 내에서 재사용 가능한 UI 모듈로, 다양한 화면 크기와 레이아웃에 유연하게 대응할 수 있습니다. Fragment를 효과적으로 생성하고 관리하는 것은 모던 Android 앱 개발의 필수 기술입니다. 이번 글에서는 Fragment 클래스 생성부터 XML을 통한 Activity 연결까지 실전에서 바로 활용할 수 있는 구현 방법을 상세히 알아보겠습니다.
목차
1. Fragment 클래스 생성 기본 구조
2. Fragment 생명주기 콜백 이해하기
3. XML로 Fragment를 Activity에 추가하는 방법
4. FragmentActivity와 AppCompatActivity 비교
5. Fragment 런타임 제어 시 주의사항

#1. Fragment 클래스 생성 기본 구조
1) Fragment 클래스 구현의 핵심
Fragment를 생성하려면 Fragment 클래스를 상속받은 후, Activity와 마찬가지로 주요 생명주기 메서드를 재정의하여 앱 로직을 구현합니다.
(1) Activity와의 주요 차이점
Fragment 생성 시 Activity와의 가장 큰 차이점은 레이아웃 정의에 onCreateView() 콜백을 사용해야 한다는 점입니다. 사실 Fragment 실행에 필요한 가장 중요한 콜백이 바로 onCreateView()입니다.
(2) 기본 Fragment 클래스 구조
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup

// Fragment 클래스를 상속받아 구현
class ArticleFragment : Fragment() {

// Fragment의 UI를 생성하는 필수 메서드
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// 레이아웃 XML 파일을 inflate하여 뷰 객체 생성
return inflater.inflate(
R.layout.article_view,
container,
false
)
}
}
. . . . .
2) onCreateView() 메서드 파라미터 상세 분석
파라미터 타입 설명
inflater LayoutInflater XML 레이아웃 파일을 View 객체로 변환하는 도구
container ViewGroup? Fragment의 UI가 삽입될 부모 뷰 그룹 (nullable)
savedInstanceState Bundle? 이전 상태 복원을 위한 데이터 번들 (nullable)
(1) inflate() 메서드의 세 번째 파라미터
inflate() 메서드의 세 번째 파라미터는 attachToRoot로, 일반적으로 false로 설정해야 합니다. Fragment의 뷰는 Fragment 매니저가 자동으로 부모 컨테이너에 연결하기 때문입니다.

#2. Fragment 생명주기 콜백 이해하기
1) Activity와 Fragment 생명주기 연동
Activity와 마찬가지로 Fragment는 Activity의 생명주기에 따라 자동으로 상태가 변경됩니다. Activity가 생명주기 상태 간에 전환될 때 Fragment도 함께 전환됩니다.
(1) 생명주기 콜백 연동 예시
Activity의 onPause() 메서드가 호출되면, Activity 내 모든 Fragment도 onPause() 호출을 받게 됩니다. 이러한 연동은 시스템에서 자동으로 처리합니다.
class ArticleFragment : Fragment() {

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.article_view, container, false)
}

// Activity의 onCreate() 호출 후 실행
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Fragment 초기화 로직
}

// 뷰가 완전히 생성된 후 실행
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// UI 요소 초기화 및 이벤트 리스너 설정
}

// Activity의 onPause()와 함께 호출
override fun onPause() {
super.onPause()
// 진행 중인 작업 일시 중지
}

// 뷰가 제거될 때 호출
override fun onDestroyView() {
super.onDestroyView()
// 뷰 관련 리소스 해제
}
}
. . . . .
2) 주요 Fragment 생명주기 단계
콜백 메서드 호출 시점 주요 용도
onCreate() Fragment가 생성될 때 초기 설정, 데이터 복원
onCreateView() Fragment의 UI를 그릴 때 레이아웃 inflate, 뷰 객체 생성
onViewCreated() 뷰가 생성된 직후 UI 요소 초기화, 리스너 설정
onStart() Fragment가 사용자에게 보이기 시작 UI 업데이트 시작
onResume() Fragment가 상호작용 가능한 상태 애니메이션 시작, 포커스 처리
onPause() Fragment가 포커스를 잃을 때 진행 중인 작업 일시 중지
onDestroyView() Fragment의 뷰가 제거될 때 뷰 관련 리소스 정리
onDestroy() Fragment가 완전히 소멸될 때 최종 리소스 해제
Fragment 생명주기와 콜백 메서드에 대한 더 자세한 내용은 Android 공식 Fragments 개발자 가이드를 참조하세요.

#3. XML로 Fragment를 Activity에 추가하는 방법
1) Fragment의 모듈화 특성
Fragment는 재사용 가능한 모듈식 UI 구성 요소이지만, Fragment 클래스의 각 인스턴스는 반드시 상위 FragmentActivity와 연결되어야 합니다.
(1) XML을 통한 Fragment 연결
Activity 레이아웃 XML 파일 안에 각각의 Fragment를 정의하여 연결을 설정할 수 있습니다. 이는 정적인 Fragment 배치에 적합한 방법입니다.
. . . . .
2) 대형 화면을 위한 멀티 Fragment 레이아웃
다음은 기기 화면을 "large"로 간주할 때, 두 개의 Fragment를 Activity에 추가하는 레이아웃 파일의 예시입니다.
(1) 레이아웃 XML 구성 (res/layout-large/news_articles.xml)
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">

<!-- 헤드라인을 표시하는 Fragment (가중치 1) -->
<fragment
android:name="com.example.android.fragments.HeadlinesFragment"
android:id="@+id/headlines_fragment"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent" />

<!-- 기사 본문을 표시하는 Fragment (가중치 2) -->
<fragment
android:name="com.example.android.fragments.ArticleFragment"
android:id="@+id/article_fragment"
android:layout_weight="2"
android:layout_width="0dp"
android:layout_height="match_parent" />

</LinearLayout>
(2) XML Fragment 태그 속성 설명
android:name: Fragment 클래스의 완전한 패키지 경로를 지정
android:id: Fragment를 식별하기 위한 고유 ID
android:layout_weight: 화면 공간 배분 비율 설정
android:layout_width="0dp": weight 사용 시 필수 설정
. . . . .
3) Activity에서 레이아웃 적용
XML로 정의한 Fragment 레이아웃을 Activity에 적용하는 코드는 매우 간단합니다.
import android.os.Bundle
import androidx.fragment.app.FragmentActivity

class MainActivity : FragmentActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

// Fragment가 포함된 레이아웃 설정
setContentView(R.layout.news_articles)

// Fragment는 XML에서 자동으로 인스턴스화됨
// 별도의 Fragment 추가 코드가 필요 없음
}
}

#4. FragmentActivity와 AppCompatActivity 비교
1) FragmentActivity의 역할과 특징
FragmentActivity는 AndroidX 지원 라이브러리에서 제공하는 특수한 Activity로, 모든 Android 버전에서 Fragment를 일관되게 사용할 수 있도록 합니다.
(1) FragmentActivity 사용 시나리오
과거 API 레벨 11보다 낮은 시스템 버전에서 Fragment를 처리하기 위해 사용되었습니다. 현재는 대부분의 앱이 최소 API 레벨을 21 이상으로 설정하므로 일반 Activity도 Fragment를 지원합니다.
. . . . .
2) AppCompatActivity 권장 사항
실무에서는 AppCompatActivity를 사용하는 것이 권장됩니다. AppCompatActivity는 FragmentActivity의 하위 클래스이며, Material Design과 최신 UI 기능을 지원합니다.
(1) v7 appcompat library 활용
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity

// AppCompatActivity는 FragmentActivity의 하위 클래스
class MainActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.news_articles)

// ActionBar/ToolBar 설정 가능
supportActionBar?.title = "뉴스 기사"
}
}
(2) Activity 클래스 선택 가이드
클래스 특징 권장 사용 시나리오
Activity 기본 Activity 클래스 Fragment를 사용하지 않는 단순 화면
FragmentActivity Fragment 지원 기본 클래스 Fragment만 필요한 경우 (드물게 사용)
AppCompatActivity Material Design 및 하위 호환성 제공 대부분의 실무 프로젝트 (가장 권장)

#5. Fragment 런타임 제어 시 주의사항
1) XML Fragment의 제약사항
레이아웃 XML 파일에서 Fragment를 정의하면 런타임에 Fragment를 삭제할 수 없습니다. 이는 XML로 정의된 Fragment의 가장 큰 제약입니다.
(1) 정적 vs 동적 Fragment 추가 방식 비교
구분 XML 정적 추가 코드 동적 추가
추가 방법 레이아웃 XML에 <fragment> 태그 FragmentTransaction API 사용
런타임 제거 불가능 가능
런타임 교체 불가능 가능
적합한 용도 항상 고정된 UI 구조 사용자 상호작용에 따라 변경되는 UI
. . . . .
2) 동적 Fragment 관리 접근법
사용자 상호작용 중 Fragment를 추가 및 삭제하려면, Activity를 처음 시작할 때 코드로 Fragment를 추가해야 합니다.
(1) 동적 Fragment 추가 예시
class MainActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

// 최초 실행 시에만 Fragment 추가
if (savedInstanceState == null) {
val fragment = HeadlinesFragment()

supportFragmentManager.beginTransaction()
.add(R.id.fragment_container, fragment)
.commit()
}
}

// Fragment 교체 메서드
fun replaceFragment(newFragment: Fragment) {
supportFragmentManager.beginTransaction()
.replace(R.id.fragment_container, newFragment)
.addToBackStack(null)
.commit()
}
}
(2) Fragment 컨테이너 레이아웃 (res/layout/activity_main.xml)
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
동적으로 추가된 Fragment는 FragmentTransaction을 통해 추가, 제거, 교체가 모두 가능하며, Back Stack 관리도 지원합니다.
. . . . .
3) Fragment 추가 방식 선택 가이드
XML 정적 추가: 항상 표시되어야 하는 고정 UI 구조
코드 동적 추가: 사용자 액션에 따라 변경되는 UI
혼합 방식: 기본 Fragment는 XML로, 추가 Fragment는 코드로 관리

마무리
Android Fragment 생성은 Fragment 클래스 상속과 onCreateView() 메서드 구현이라는 간단한 구조로 시작되지만, Activity와의 생명주기 연동, XML/코드를 통한 추가 방식, 런타임 제어 가능성 등 다양한 요소를 고려해야 합니다.
XML을 통한 정적 추가는 간편하지만 런타임 제어가 불가능하므로, 동적인 UI가 필요한 경우 코드를 통한 Fragment 관리를 선택해야 합니다. 실무에서는 AppCompatActivity를 기본으로 사용하며, Fragment의 생명주기를 정확히 이해하여 메모리 누수와 성능 저하를 방지하는 것이 중요합니다.
Fragment는 현대 Android 앱 개발의 핵심 컴포넌트입니다. 재사용 가능한 모듈화된 UI 구조를 통해 다양한 화면 크기와 방향에 유연하게 대응할 수 있으며, Navigation Component와 결합하면 더욱 강력한 화면 전환 시스템을 구축할 수 있습니다.
긴 글 읽어주셔서 감사합니다.

끝.
반응형