FragmentContainerView 를 사용하여 프래그먼트를 생성시
onCreateView 가 불리지 않고 앱이 죽는다면? 앱을 실행하면 바로 죽는다.
처음에는 도대체 왜 죽는지 한참을 헤멨다.
XML에는 하기처럼 코드가 정의되어 있다.
프래그먼트를 프래그먼트 컨테이너 뷰를 이용해서 잘 불러오고 있다.
<androidx.fragment.app.FragmentContainerView
android:id="@+id/fragment_container_view"
android:name="bluemooninsea.soo.fragmentstudy.ColorFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:layout="@layout/fragment_color" />
그런데, 앱을 실행 하면 죽는다.
죽는 이유는 MainActivity 에서 하기처럼 프래그먼트 매니지를 통해서 프래그먼트의 로컬 함수를 직접 호출한다.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 메인액티비티와 프래그먼트의 연결 작업 시작
// 프래그먼트 컨트롤을 위해서 프래그먼트 매니저를 얻어온다
fragmentManager = getSupportFragmentManager();
// findFragmentById() 로 프래그먼트 를 가져옴.
ColorFragment colorFragment = (ColorFragment) fragmentManager.findFragmentById(R.id.fragment_container_view);
colorFragment.setColor(Color.RED);
}
문제는 해당 프래그먼트의 로컬 함수에 있다. textView 가 null point 라서 발생하는 문제이다.
public void setColor(int color){
textView.setBackgroundColor(color);
}
onCreateView 가 호출되면서 프래그먼트를 인플레이트를 해야하는데,
onCreateView 가 호출되지 않고 죽는 문제가 발생한다. 왜 이럴까?
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.d("TEST" , "TEST = onCreateView");
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_color, container, false);
textView = view.findViewById(R.id.text);
return view;
}
프래그먼트를 프래그먼트 컨테이너 뷰를 이용해서 호출하면, fragment 내부의 onInflate() 함수를 호출한다.
참고로, 프래그먼트 를 바로 사용한 경우에는 onInflate() 를 호출하지 않고 해당 MainActivity 코드에서도 죽지 않는다.
<androidx.fragment.app.FragmentContainerView
android:id="@+id/fragment_container_view"
android:name="bluemooninsea.soo.fragmentstudy.ColorFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:layout="@layout/fragment_color" />
그럼, MainActivity 를 하기처럼 바꾸자.
OnCreate 에서는 직접적으로 프래그먼트의 내부 함수 콜을 부르지 않는다.
FragmentManager fragmentManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 메인액티비티와 프래그먼트의 연결 작업 시작
// 프래그먼트 컨트롤을 위해서 프래그먼트 매니저를 얻어온다
fragmentManager = getSupportFragmentManager();
// findFragmentById() 로 프래그먼트 를 가져옴.
//ColorFragment colorFragment = (ColorFragment) fragmentManager.findFragmentById(R.id.fragment_container_view);
// colorFragment.setColor(Color.RED);
}
별도의 함수를 생성해서 버튼 이벤트에 따른 프래그먼트 내부함수를 콜한다.
이렇게 구현하면 FragmentContainerView 코드가 정상적으로 동작한다.
public void changeRed(View view) {
// findFragmentById() 로 프래그먼트 를 가져옴.
ColorFragment colorFragment = (ColorFragment) fragmentManager.findFragmentById(R.id.fragment_container_view);
colorFragment.setColor(Color.RED);
}
정리해보면, Activity 와 프래그먼트의 실행 라이프사이클에 답이있다.
액티비티의 oncreate()가 실행되는 시점에 프래그먼트의 onCreateView()난 아직 실행전이라는 이야기다.
FragmentContainerView 를 사용하면 프래그먼트 클래스에서 onCrateView()를 호출전 onInflate() 콜백 함수 의 한단계가 더 진행되기에 인플레이트 되지 않은 프래그먼트의 직접적인 접근이 문제가 되는 것이다.
한참을 헤메다가 스스로 어렵게 수정해 보았다.
편하게 이야기 하자면 삽질 ^^; 스스로 공부하고 생각한 점을 남긴다.
'앱 만들기 > 안드로이드 study' 카테고리의 다른 글
구글콘솔 앱 출시 안되게 설정하는 방법 (3) | 2023.07.21 |
---|---|
안드로이드 Color 값 세팅하는 방법 (4) | 2022.08.15 |
안드로이드 스튜디오 주석 단축키 (6) | 2022.08.12 |
안드로이드 백키 재정의 하기 (2) | 2022.08.08 |
안드로이드 스튜디오 상속관계(계층 뷰) 보기 (2) | 2022.07.29 |
댓글