프래그먼트 만들기

프래그먼트는 활동 내에서 사용자 인터페이스의 모듈식 부분을 말합니다. 프래그먼트는 자체 수명 주기가 있고 자체 입력 이벤트를 수신합니다. 개발자는 포함 중인 활동이 실행되는 동안에 프래그먼트를 추가하거나 삭제할 수 있습니다.

이 문서에서는 프래그먼트를 만들어 활동에 포함하는 방법을 설명합니다.

환경 설정

프래그먼트를 사용하려면 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.6.2"

    // Java language implementation
    implementation "androidx.fragment:fragment:$fragment_version"
    // Kotlin
    implementation "androidx.fragment:fragment-ktx:$fragment_version"
}

Kotlin

dependencies {
    val fragment_version = "1.6.2"

    // 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 내에 프래그먼트를 삽입해야 합니다. FragmentActivityAppCompatActivity의 기본 클래스입니다. 따라서 앱에 이전 버전과의 호환성을 제공하기 위해 이미 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()가 새로 인스턴스화된 프래그먼트에 호출되며 FragmentTransactionFragmentManager에 프래그먼트를 추가하기 위해 생성됩니다.

프로그래매틱 방식으로 프래그먼트 추가

프로그래매틱 방식으로 활동의 레이아웃에 프래그먼트를 추가하려면, 다음 예에서와 같이 프래그먼트 컨테이너로 사용할 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();
        }
    }
}

이전 예에서는 프래그먼트 트랜잭션이 savedInstanceStatenull일 때만 생성되었습니다. 이는 활동이 처음 생성될 때 프래그먼트가 한 번만 추가되도록 하기 위함입니다. 구성이 변경되고 활동이 다시 생성되면 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프래그먼트 관리자 가이드에 자세히 설명되어 있습니다.