Android

[Android] Fragment 생성 방법 정리 / newInstance()

도우 2024. 3. 2. 16:23
반응형

이 글에서는 프래그먼트의 효율적인 생성 방법에 대해 이야기해보겠습니다.

 

출처 : https://velog.io/@dabin/%EC%95%88%EB%93%9C%EB%A1%9C%EC%9D%B4%EB%93%9C%ED%94%84%EB%9E%98%EA%B7%B8%EB%A8%BC%ED%8A%B81

 

1. 직접 생성자 호출

MyFragment fragment = new MyFragment();

Fragment의 인스턴스를 직접 생성하기 위해 기본 생성자를 호출한다.

가장 기본적이고 간단한 방법이지만, 안드로이드 시스템이 Fragment를 재생성할 때 모든 데이터를 잃어버린다.

 

2. newInstance() : 정적 팩토리 메소드

public static MyFragment newInstance(String param1) {
    MyFragment fragment = new MyFragment(); // Fragment 인스턴스 생성
    Bundle args = new Bundle(); 
    args.putString("param1", param1); // 필요한 데이터를 Bundle 객체에 담기
    fragment.setArguments(args);
    return fragment;
}

Fragment 내에 newInstance() 정적 메소드를 정의하고, 이 메소드를 통해 Fragment의 인스턴스를 생성한다. 
이후 필요한 데이터를 Bundle 객체에 담아 setArguments() 메소드를 통해 Fragment에 전달한다.

Bundle을 사용한 newInstance() 방법은 Fragment를 다룰 때 권장되는 패턴 중 하나인데,
이러한 이유는 Fragment의 존재 이유가 재사용성에 있기 때문이다.

프래그먼트는 독립적으로 존재할 수 없고 항상 Activity, 다른 프래그먼트 내에서 호스팅 되어야 하며 
생명 주기에 직접적인 영향을 받는다.

이 방법은 Fragment가 생성되고, 파기되고, 재생성되는 과정에서 매우 뛰어난 강점이 있다.

  • 상태 복원
    Fragment가 시스템에 의해 재생성되더라도 getArguments()를 통해 이전에 저장된 상태를 복원할 수 있다.
    ex) 회전 구성 변경 후에도 데이터를 유지할 수 있다.

  • 타입 안정성
    newInstance() 메소드에 매개변수를 명시적으로 정의함으로써, 올바른 타입의 데이터가 전달되도록 강제한다.
    이것은 타입 오류를 줄이고 코드의 안정성이 올라간다.
  • 분리된 초기화 로직
    Fragment의 생성과 초기화 로직을 분리함으로써, 프래그먼트의 재사용성과 유지보수성이 향상된다.


따라서 , Fragment에 초기 데이터를 전달하거나 상태를 유지하는 경우, newInstance() 방법이 권장된다.

 

 

3. Fragment XML 태그 사용

<fragment
    android:id="@+id/example_fragment"
    android:name="com.example.MyFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

UI 구성의 일부로 Fragment를 정적으로 포함시킬 때 적합하다. 이 방법은 Fragment가 레이아웃에 고정되어 있어야 하며, 동적으로 교체되거나 제거될 필요가 없는 경우에 사용된다.

 

 

4. FragmentManager와 FragmentTransaction 사용

FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.fragment_container, new MyFragment());
fragmentTransaction.commit();

코드에서 Fragment를 동적으로 추가, 제거 또는 교체하기 위해 FragmentManager와 FragmentTransaction을 사용한다.

이 방법은 런타임에 Fragment를 동적으로 조작해야 하는 경우에 적합하다. 
예를 들면, 사용자 상호 작용에 따라 Fragment를 교체하거나, 여러 Fragment 중 하나를 동적으로 표시해야할 때 사용된다.

 

 

 

5. Fragment 팩토리 사용 ( Android X 이후 )

class MyFragmentFactory extends FragmentFactory {
    @NonNull
    @Override
    public Fragment instantiate(@NonNull ClassLoader classLoader, @NonNull String className) {
        return new MyFragment(myParam);
    }
}

FragmentFactory를 사용하여 Fragment의 생성 방식을 커스텀한다. 이를 통해 생성자에 파라미터를 전달하는 등 보다 유연한 인스턴스화가 가능해진다.

Fragment에 파라미터를 전달하거나, 특정 의존성을 주입해야할 때 유용하며, 특정 요구 사항에 따라 맞춰서 작성해야한다.

 

 

6. 클래스 참조를 통한 최신 방식 ( Jetpack 관련 )

public class ExampleActivity extends AppCompatActivity {
    public ExampleActivity() {
        super(R.layout.example_activity); 
        // AppCompatActivity 생성자에 액티비티의 기본 레이아웃 설정
        // setContentView 대체
    }
    @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();
        }
    }
}

FragmentTransaction에 Fragment 클래스를 직접 전달하는 방식

Android Jetpack 일부로 제공되는 Fragment API의 새로운 기능을 활용한 것이다.

개발자가 Fragment의 인스턴스를 수동으로 생성하고 초기화 하는 대신에 시스템에 클래스 정보를 제공하고 시스템이 해당 Fragment의 인스턴스를 자동으로 생성하게끔 한다.

 

 

<정리>

현재 Android 개발에서는 (6) 클래스 참조를 통한 최신 방식newInstance() 방법이 가장 권장된다고 한다.

클래스 참조를 통한 최신 방식은 Jetpack 라이브러리와의 호환성을 고려할때 특히 유용하고
Fragment의 인스턴스화 과정을 시스템에 맡기므로, 개발자는 Fragment 관리에 더 집중할 수 있다.

newInstance() 방식은 타입 안정성과 데이터 유지 측면에서 여전히 강력하다.
특히 초기화 데이터를 Fragment에 전달해야 하거나, 상태 복원이 중요한 경우 이 방법을 사용하는 것이 좋다.

반응형