Google은 흑인 공동체를 위한 인종 간 평등을 진전시키기 위해 노력하고 있습니다. Google에서 어떤 노력을 하고 있는지 확인하세요.

유연한 UI 빌드

다양한 화면 크기를 지원하도록 애플리케이션을 디자인할 경우 프래그먼트를 다양한 레이아웃 구성에서 다시 사용하여 사용 가능한 화면 공간에 따라 사용자 환경을 최적화할 수 있습니다.

예를 들어 핸드셋 기기인 경우 단일 창 사용자 인터페이스에 프래그먼트를 한 번에 하나씩만 표시하는 것이 적합할 수 있습니다. 반대로, 화면 너비가 큰 태블릿에서는 프래그먼트를 나란히 설정하여 사용자에게 더 많은 정보를 표시할 수 있습니다.

그림 1. 서로 다른 화면 크기에서 같은 활동이 다른 구성으로 표시된 두 프래그먼트. 큰 화면에서는 두 프래그먼트를 모두 나란히 표시하지만, 핸드셋 기기에서는 프래그먼트가 한 번에 하나씩 표시되므로 사용자가 이동할 때 프래그먼트가 서로 교체되어야 합니다.

FragmentManager 클래스는 동적 경험을 연출하기 위해 런타임 시 활동에 프래그먼트를 추가, 삭제 및 교체할 수 있는 메서드를 제공합니다.

프래그먼트 구현에 관한 자세한 정보는 다음 리소스를 참조하세요.

런타임 시 활동에 프래그먼트 추가

<fragment> 요소를 사용하여 이전 과정에서 소개한 것처럼 레이아웃 파일에 활동의 프래그먼트를 정의하기보다는 활동의 런타임 중에 프래그먼트를 활동에 추가할 수 있습니다. 이 작업은 활동의 수명이 지속되는 동안 프래그먼트를 변경하려는 경우에 필요합니다.

프래그먼트 추가 또는 삭제와 같은 트랜잭션을 실행하려면 FragmentManager를 사용하여 FragmentTransaction을 생성해야 하며 이 클래스에서는 다른 프래그먼트 트랜잭션을 추가, 삭제, 교체 및 실행하는 API를 제공합니다.

활동에서 프래그먼트의 삭제와 교체를 허용한다면, 활동의 onCreate() 메서드를 실행하는 동안 초기 프래그먼트를 활동에 추가해야 합니다.

프래그먼트 작업 시, 특히 런타임에 프래그먼트를 추가할 때 유념해야 할 중요한 규칙은 프래그먼트를 삽입할 수 있는 View 컨테이너를 활동 레이아웃에서 포함해야 하는 것입니다.

이전 과정에 나와 있는 대로 프래그먼트를 한 번에 하나씩만 표시하는 레이아웃 대신 다음 레이아웃을 사용할 수 있습니다. 프래그먼트를 다른 프래그먼트와 교체하기 위해 활동의 레이아웃은 프래그먼트 컨테이너 역할을 하는 빈 FrameLayout을 포함합니다.

파일 이름이 이전 과정의 레이아웃 파일과 같지만, 레이아웃 디렉터리에 large 한정자가 없습니다. 따라서, 동시에 두 개의 프래그먼트를 화면에 맞출 수 없으므로 기기 화면이 대형보다 작을 때 이 레이아웃을 사용합니다.

res/layout/news_articles.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" />
    

활동에서 지원 라이브러리 API를 통해 getSupportFragmentManager()를 호출하여 FragmentManager를 가져옵니다. 그런 다음, beginTransaction()을 호출하여 FragmentTransaction을 생성하고 add()를 호출하여 프래그먼트를 추가합니다.

동일한 FragmentTransaction을 사용하여 활동의 여러 프래그먼트 트랜잭션을 실행할 수 있습니다. 변경할 준비가 되면 commit()을 호출해야 합니다.

다음은 이전 레이아웃에 프래그먼트를 추가하는 방법의 예입니다.

Kotlin

    import android.os.Bundle
    import android.support.v4.app.FragmentActivity

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

            // Check that the activity is using the layout version with
            // the fragment_container FrameLayout
            if (findViewById(R.id.fragment_container) != null) {

                // However, if we're being restored from a previous state,
                // then we don't need to do anything and should return or else
                // we could end up with overlapping fragments.
                if (savedInstanceState != null) {
                    return;
                }

                // Create a new Fragment to be placed in the activity layout
                val firstFragment = HeadlinesFragment()

                // In case this activity was started with special instructions from an
                // Intent, pass the Intent's extras to the fragment as arguments
                firstFragment.arguments = intent.extras

                // Add the fragment to the 'fragment_container' FrameLayout
                supportFragmentManager.beginTransaction()
                        .add(R.id.fragment_container, firstFragment).commit()
            }
        }
    }
    

자바

    import android.os.Bundle;
    import android.support.v4.app.FragmentActivity;

    public class MainActivity extends FragmentActivity {
        @Override
        public void onCreate(Bundle savedInstanceState?) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.news_articles);

            // Check that the activity is using the layout version with
            // the fragment_container FrameLayout
            if (findViewById(R.id.fragment_container) != null) {

                // However, if we're being restored from a previous state,
                // then we don't need to do anything and should return or else
                // we could end up with overlapping fragments.
                if (savedInstanceState != null) {
                    return;
                }

                // Create a new Fragment to be placed in the activity layout
                HeadlinesFragment firstFragment = new HeadlinesFragment();

                // In case this activity was started with special instructions from an
                // Intent, pass the Intent's extras to the fragment as arguments
                firstFragment.setArguments(getIntent().getExtras());

                // Add the fragment to the 'fragment_container' FrameLayout
                getSupportFragmentManager().beginTransaction()
                        .add(R.id.fragment_container, firstFragment).commit();
            }
        }
    }
    

프래그먼트를 <fragment> 요소로 활동 레이아웃에 정의하는 대신 런타임에 FrameLayout 컨테이너에 추가했으므로 활동에서 이 프래그먼트를 삭제하고 다른 프래그먼트로 교체할 수 있습니다.

한 프래그먼트를 다른 프래그먼트로 교체

프래그먼트 교체 절차는 프래그먼트 추가 절차와 비슷하지만, add() 대신 replace() 메서드를 사용해야 합니다.

프래그먼트 교체 또는 삭제와 같은 프래그먼트 트랜잭션을 실행할 때는 사용자가 뒤로 이동하여 변경을 '실행취소'하도록 허용하는 것이 적절한 경우가 많습니다. 프래그먼트 트랜잭션을 통해 사용자가 뒤로 이동할 수 있게 하려면, FragmentTransaction을 커밋하기 전에 addToBackStack()을 호출해야 합니다.

참고: 프래그먼트를 삭제 또는 교체하고 트랜잭션을 백 스택에 추가하면 삭제된 프래그먼트가 중지됩니다(폐기되지는 않음). 사용자가 뒤로 탐색하여 프래그먼트를 복원하는 경우 프래그먼트가 다시 시작됩니다. 트랜잭션을 백 스택에 추가하지 않으면 프래그먼트가 삭제되거나 교체될 때 폐기됩니다.

다른 프래그먼트와의 교체 예:

Kotlin

    // Create fragment and give it an argument specifying the article it should show
    val newFragment = ArticleFragment()
    Bundle args = Bundle()
    args.putInt(ArticleFragment.ARG_POSITION, position)
    newFragment.arguments = args

    val transaction = supportFragmentManager.beginTransaction().apply {
      // Replace whatever is in the fragment_container view with this fragment,
      // and add the transaction to the back stack so the user can navigate back
      replace(R.id.fragment_container, newFragment)
      addToBackStack(null)
    }

    // Commit the transaction
    transaction.commit();
    

자바

    // Create fragment and give it an argument specifying the article it should show
    ArticleFragment newFragment = new ArticleFragment();
    Bundle args = new Bundle();
    args.putInt(ArticleFragment.ARG_POSITION, position);
    newFragment.setArguments(args);

    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();

    // Replace whatever is in the fragment_container view with this fragment,
    // and add the transaction to the back stack so the user can navigate back
    transaction.replace(R.id.fragment_container, newFragment);
    transaction.addToBackStack(null);

    // Commit the transaction
    transaction.commit();
    

addToBackStack() 메서드는 트랜잭션의 고유한 이름을 지정하는 문자열 매개변수를 선택적으로 취합니다. FragmentManager.BackStackEntry API를 사용하여 고급 프래그먼트 작업을 실행하려는 경우 외에는 이름이 필요하지 않습니다.