Correctly creating fragments

AdroidDev protip


Today’s #AndroidDev #protip from +Nick Butcher is about correctly creating fragments.

Fragment는 Application을 재사용 가능한 요소들로 분리하고, 유연한 레이아웃을 만들 수 있게 해줍니다. Fragment를 만들 때 캡슐화를 위해서 오버로드된 생성자를 통해 초기 데이터를 전달하도록 하고 싶을 것입니다. 하지만 이렇게 하는 것은 Activity의 라이프 사이클에 의해 Fragment의 instance들이 재생성될 때 문제를 일으키게 될 것입니다. Fragment의 javadoc 설명을 보면:

모든 Fragment는 Activity의 상태 복원시 instance를 만들 때 사용될 빈 생성자를 가지고 있어야한다. Fragment의 서브클래스는 파라미터를 가지는 생성자들을 가지지 않을 것을 강력하게 권고한다. 이 생성자는 Fragment instance가 다시 생성될 때 호출되지 않기 때문이다…”

흔히 newInstance라고 불리는 static 생성 메소드를 사용하여 Fragment 초기화시 필요한 데이터를 캡슐화 하는 패턴을 구현할 수 있다. 이 메소드는 Fragment를 생성하며 재생성시에도 유지되는 bundle 인수에 데이터를 숨긴다.

public static class MyFragment extends Fragment {
public MyFragment() { } // Required empty constructor
public static MyFragment newInstance(String foo, int bar) { MyFragment f = new MyFragment(); Bundle args = new Bundle(); args.putString(ARG_FOO, foo); args.putInt(ARG_BAR, bar); f.setArguments(args); return f;
}

이후에 이 데이터에 접근 할 수 있다.

@Override
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
Bundle args = getArguments();
if (args != null) { // Use initialisation data }
}

이 패턴은 Fragment가 초기화될 때 필요한 인수들을 캡슐화하며 라이프 사이클 메소드에서도 잘 동작한다.