프래그먼트는 활동 내에서 사용자 인터페이스의 모듈식 부분을 말합니다. 프래그먼트는 자체 수명 주기가 있고 자체 입력 이벤트를 수신합니다. 개발자는 포함 중인 활동이 실행되는 동안에 프래그먼트를 추가하거나 삭제할 수 있습니다.
이 문서에서는 프래그먼트를 만들어 활동에 포함하는 방법을 설명합니다.
환경 설정
프래그먼트를 사용하려면 AndroidX 프래그먼트 라이브러리에 종속 항목이 필요합니다. 이 종속 항목을 포함하려면 Google Maven 저장소를 프로젝트의 settings.gradle
파일에 추가해야 합니다.
Groovy
dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { google() ... } }
Kotlin
dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { google() ... } }
AndroidX 프래그먼트 라이브러리를 프로젝트에 포함하려면 앱의 build.gradle
파일에 다음 종속 항목을 추가합니다.
Groovy
dependencies { def fragment_version = "1.8.5" // Java language implementation implementation "androidx.fragment:fragment:$fragment_version" // Kotlin implementation "androidx.fragment:fragment-ktx:$fragment_version" }
Kotlin
dependencies { val fragment_version = "1.8.5" // Java language implementation implementation("androidx.fragment:fragment:$fragment_version") // Kotlin implementation("androidx.fragment:fragment-ktx:$fragment_version") }
프래그먼트 클래스 만들기
프래그먼트를 생성하려면 AndroidX Fragment
클래스를 확장한 후 Activity
클래스를 생성하는 것과 유사한 방식으로 관련 메서드를 재정의하여 앱 로직을 삽입합니다. 자체 레이아웃을 정의하는 최소 프래그먼트를 만들려면 다음 예에서와 같이 프래그먼트의 레이아웃 리소스를 기본 생성자에 제공합니다.
Kotlin
class ExampleFragment : Fragment(R.layout.example_fragment)
자바
class ExampleFragment extends Fragment { public ExampleFragment() { super(R.layout.example_fragment); } }
프래그먼트 라이브러리는 좀더 특수한 프래그먼트 기본 클래스도 제공합니다.
DialogFragment
- 플로팅 대화상자를 표시합니다. 이 클래스를 사용하여 대화상자를 만드는 방법은
Activity
클래스에 대화상자 도우미 메서드를 사용하는 방법의 좋은 대안이 됩니다. 프래그먼트가 자동으로Dialog
의 생성 및 정리를 처리하기 때문입니다. 자세한 내용은DialogFragment
로 대화상자 표시를 참조하세요. PreferenceFragmentCompat
Preference
객체의 계층 구조를 목록으로 표시합니다.PreferenceFragmentCompat
을 사용하여 앱의 설정 화면을 만들 수 있습니다.
활동에 프래그먼트 추가
일반적으로, UI의 일부를 활동의 레이아웃에 영향을 미치게 하려면 Android FragmentActivity
내에 프래그먼트를 삽입해야 합니다. FragmentActivity
는 AppCompatActivity
의 기본 클래스입니다. 따라서 앱에 이전 버전과의 호환성을 제공하기 위해 이미 AppCompatActivity
를 서브클래스화했다면 활동 기반 클래스를 변경할 필요가 없습니다.
활동의 뷰 계층 구조에 프래그먼트를 추가하려면 활동의 레이아웃 파일에서 프래그먼트를 정의하거나, 활동의 레이아웃 파일에서 프래그먼트 컨테이너를 정의한 후 활동 내에서 프래그먼트를 프로그래매틱 방식으로 추가하면 됩니다. 이때 어느 경우든 활동의 뷰 계층 구조에 프래그먼트를 배치할 위치를 정의하는 FragmentContainerView
를 추가해야 합니다. 항상 FragmentContainerView
를 프래그먼트의 컨테이너로 사용하는 것이 좋습니다. FrameLayout
같은 다른 뷰 그룹에서 제공하지 않는 프래그먼트 관련 수정사항이 FragmentContainerView
에 포함되어 있기 때문입니다.
XML을 통해 프래그먼트 추가
프래그먼트를 활동 레이아웃의 XML에 선언적으로 추가하려면 FragmentContainerView
요소를 사용합니다.
다음은 단일 FragmentContainerView
를 포함하는 활동 레이아웃의 예입니다.
<!-- res/layout/example_activity.xml -->
<androidx.fragment.app.FragmentContainerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragment_container_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="com.example.ExampleFragment" />
android:name
속성은 인스턴스화할 Fragment
의 클래스 이름을 지정합니다. 활동 레이아웃이 확장되면 지정된 프래그먼트가 인스턴스화되고 onInflate()
가 새로 인스턴스화된 프래그먼트에 호출되며 FragmentTransaction
이 FragmentManager
에 프래그먼트를 추가하기 위해 생성됩니다.
프로그래매틱 방식으로 프래그먼트 추가
프로그래매틱 방식으로 활동의 레이아웃에 프래그먼트를 추가하려면, 다음 예에서와 같이 프래그먼트 컨테이너로 사용할 FragmentContainerView
를 레이아웃에 포함해야 합니다.
<!-- res/layout/example_activity.xml -->
<androidx.fragment.app.FragmentContainerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragment_container_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
XML 접근 방식과 달리 여기에서는 android:name
속성이 FragmentContainerView
에 사용되지 않으므로 특정 프래그먼트가 자동으로 인스턴스화되지 않습니다. 대신 프래그먼트를 인스턴스화하고 활동의 레이아웃에 추가하는 데 FragmentTransaction
이 사용됩니다.
활동이 실행되는 동안 프래그먼트 추가, 삭제, 교체와 같은 프래그먼트 트랜잭션을 수행할 수 있습니다. FragmentActivity
에서 FragmentManager
의 인스턴스(FragmentTransaction
을 만드는 데 사용할 수 있음)를 가져올 수 있습니다. 그런 다음 아래 예에 나와 있는 것처럼, FragmentTransaction.add()
를 사용하고 레이아웃에 있는 컨테이너의 ViewGroup
ID와 추가할 프래그먼트 클래스를 전달하여 활동의 onCreate()
메서드 내에서 프래그먼트를 인스턴스화한 다음 트랜잭션을 커밋할 수 있습니다.
Kotlin
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) } } } }
자바
public class ExampleActivity extends AppCompatActivity { public ExampleActivity() { super(R.layout.example_activity); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (savedInstanceState == null) { getSupportFragmentManager().beginTransaction() .setReorderingAllowed(true) .add(R.id.fragment_container_view, ExampleFragment.class, null) .commit(); } } }
이전 예에서는 프래그먼트 트랜잭션이 savedInstanceState
가 null
일 때만 생성되었습니다. 이는 활동이 처음 생성될 때 프래그먼트가 한 번만 추가되도록 하기 위함입니다. 구성이 변경되고 활동이 다시 생성되면 savedInstanceState
가 더 이상 null
이지 않습니다. 또한 프래그먼트가 savedInstanceState
에서 자동으로 복원되기 때문에 프래그먼트를 다시 추가할 필요가 없습니다.
프래그먼트에 초기 데이터가 일부 필요한 경우 다음과 같이 FragmentTransaction.add()
호출 시 Bundle
을 제공하여 인수를 프래그먼트에 전달하면 됩니다.
Kotlin
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) } } } }
자바
public class ExampleActivity extends AppCompatActivity { public ExampleActivity() { super(R.layout.example_activity); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (savedInstanceState == null) { Bundle bundle = new Bundle(); bundle.putInt("some_int", 0); getSupportFragmentManager().beginTransaction() .setReorderingAllowed(true) .add(R.id.fragment_container_view, ExampleFragment.class, bundle) .commit(); } } }
그러면 requireArguments()
을 호출하여 프래그먼트 내에서 인수 Bundle
을 가져올 수 있고, 적절한 Bundle
getter 메서드를 사용하여 인수를 각각 가져올 수 있습니다.
Kotlin
class ExampleFragment : Fragment(R.layout.example_fragment) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { val someInt = requireArguments().getInt("some_int") ... } }
자바
class ExampleFragment extends Fragment { public ExampleFragment() { super(R.layout.example_fragment); } @Override public void onViewCreated(@NonNull View view, Bundle savedInstanceState) { int someInt = requireArguments().getInt("some_int"); ... } }
참고 항목
프래그먼트 트랜잭션과 FragmentManager
는 프래그먼트 관리자 가이드에 자세히 설명되어 있습니다.