안드로이드 With Java #18 Fragment & 라이프사이클

Jake Seo·2020년 8월 11일
1

안드로이드 With Java

목록 보기
18/31
post-thumbnail

안드로이드 With Java #18 Fragment

Fragment 개념

Activity 내의 사용자 인터페이스의 일부를 나타낸다. Activity의 일부 구성 요소를 Fragment로 대체 가능하다. Activity 내부에서 보여줄 것이 많을 때 사용한다.

만들어놓은 Fragment를 여러 Activity에서 사용 가능하다. 그래서 반복적으로 여러 가지를 만들어야 하는 작업을 효율적으로 가능하다.

Fragment 특징

  • Activity 내에 포함되어 있어야 한다.
  • Activity 라이프 사이클에 직접적으로 영향을 받는다.
  • 모든 Fragment가 UI를 가지고 있어야 하는 것은 아니다.

Fragment 라이프 사이클

위와 같은 라이프사이클을 갖는다.

Activity 라이프 사이클 vs Fragment 라이프 사이클

Fragment 라이프사이클은 Activity 라이프사이클에 직접적으로 영향을 받는다.

Fragment에만 있는 라이프 사이클

  • onAttach
    • FragmentActivity와 연관되어 있었던 경우 호출된다. (Activity가 전달된다.)
  • onCreateView
    • Fragment가 자신의 사용자 인터페이스를 처음으로 그릴 때 호출된다.
  • onActivityCreated
    • ActivityonCreate()가 반환되면 호출된다.
  • onDestroyView
    • Fragment와 연관된 뷰 계층이 쩨거되는 중일 때 호출된다.
  • onDetach
    • FragmentActivity와 연결이 끊어지는 중일 때 호출된다.

Fragment 생성 방법

  • Fragment를 특정 뷰에 할당한다.
  • Fragment를 xml에 등록한다.

Fragment 관리 방법

  • FragmentManager를 통해 관리하다.
    • Fragment를 떼거나 붙이거나 할 수 있다.
    • 순서를 바꾸거나 Fragment를 찾는 작업도 가능하다.

Fragment 실습 (Java를 이용한 Fragment 등록)

MainActivityLayoutFragment가 들어갈 LinearLayout을 한개 더 넣고 거기에 새롭게 xml로 정의한 Fragment를 넣는 작업을 해보자.

activity_main.xml 수정하기

LinearLayout 내부에 LinearLayout을 넣어줬다. idcontainer로 지정해주었고, 크기는 match_parent인데 height100dp로 지정해주었다.

Fragment가 될 fragment_one.xml 생성하기

fragment의 영역을 확실히 알기 위해서 background속성만 주었다.

FragmentOne 클래스 생성하기

위와 같이 생성하면 되는데,

extends Fragment 부분이 Fragment 클래스를 상속받게 해주어 일반 클래스를 Fragment로 인식하게 해준다.

그리고 라이프사이클 중 onCreateView()를 오버라이드하여 내부에 xml로 정의해둔 Fragment가 그려지게 만들면 된다.

LayoutInflater가 xml을 그리는 역할을 한다.

공식문서의 Inflater 설명에는 간단하게 Layout xml 파일을 받아 View 클래스로 변환시켜준다고 나와있다.

View view = inflater.inflate(R.layout.fragment_one, container, false);

위와 같이 작성하고 view를 반환하면 된다.

MainActivity 클래스에 Fragment 영역 실제로 적용하기

Fragment의 영역을 적용하기 위해서는 FragmentManager를 먼저 생성해주어야 한다. FragmentManagergetSupportFragmentManager() 메소드를 통하여 불러올 수 있다.

그 다음에는 FragmentManager 클래스에서 제공하는 beginTransaction()메소드를 이용하여 FragmentTransaction 클래스의 인스턴스를 생성해준다.

FragmentTransaction 클래스의 add() 메소드를 통하여 지정된 영역에 Fragment 클래스를 넣어줄 수 있다. 단, add() 메소드는 작업을 추가하는 역할이고 실제 수행은 commit() 메소드를 수행해야 시작된다.

Fragment 실습2 (Java를 이용한 Fragment 교체)

이번에는 버튼을 눌렀을 때 Fragment를 교체하는 작업을 해보자.

교체할 Fragment의 Layout 생성하기

background에 이전과 다른 색을 줘서 변화했을 때 구분이 가게 만들었다.

FragmentTwo 클래스 생성하기

아까와 마찬가지로 Fragment 클래스를 상속시키고, inflater.inflate() 메소드를 이용하여 이전에 만든 Layout xml을 View로 만들어 반환했다.

MainActivity에 버튼 만들기

버튼을 누르면 교체되도록 하기 위해 버튼을 만들었다.

MainActivity 클래스에 로직 추가하기

findViewById() 메소드를 이용하여 onClickListener를 달아주고, 새로운 FragmentTransaction을 만들어주었다. FragmentTransaction은 한번 commit()하게되면 유통기한이 만료되기 때문에 새로 만들어주어야 한다.

Fragment 교체 시에 라이프 사이클 살펴보기

앱을 시작했을 때

MainActivityonStart시점에서 FragmentOne의 라이프사이클이 시작되고 FragmentOneonStart까지 마무리 했을 때, MainActivity의 라이프사이클도 다시 재개된다.

그리고 MainActivityonResume이 되면 FragmentOneonResume된다.

Fragment를 교체했을 때

FragmentTwoonAttach가 수행되면서 시작한다. FragmentTwoonCreate 이후에 사라질 FragmentOneonPause부터 onDetach까지 차례로 진행하며 사라진다.

그리고 이후에는 FragmentTwoonCreateView부터 onResume까지 수행하며 생성된다.

MainActivity의 라이프사이클은 관여하지 않는다.

Fragment 실습3 (xml을 이용한 Fragment 직접 등록)

activity_main.xml에 fragment 등록해보기

위와 같이 기존에 LinearLayout 이나 TextView를 추가하던 것처럼 그냥 xml에 추가하면 된다. 단, fragment 태그는 앞이 소문자임을 유의하자.

id속성은 fragment에 반드시 필요하다. name속성은 Fragment 클래스를 참조할지에 대한 내용이다.

name속성에 들어갈 Fragment가 반드시 필요하므로, Fragment를 xml에서 직접 추가하더라도 클래스를 만들고 Fragment 클래스를 상속하게 하고 onCreateView() 콜백 함수에서 LayoutInflater를 이용하여 View를 반환하는 작업까지는 다 해주어야 한다.

실행결과 두개의 Fragment가 잘 붙었다.

Fragment를 xml로 직접 붙이는 것과 Java로 붙이는 것의 결정

  • 기본적으로는 자유이나 동적으로 다루고 싶을 때는 Java로 붙이는 편이 좋다.

    • 단, 귀찮은 Transaction 등을 해야 한다.
  • Fragment를 한번 만들어놓고 여러 Activity에서 사용하고 싶을 때는 xml에 Fragment를 직접 등록하는 편이 좀 더 좋을 수 있다.

    • 귀찮은 Transaction 등은 없으나 정적이다.

Fragment에서 OnClickListener 등을 달아야 할 때?

onActivityCreated 라이프 사이클에서 수행하는 편이 좋다. 왜냐하면 이전 라이프사이클에서는 Activity의 존재 자체가 보장받지 못할 수 있다. 그렇게 되면 참조하려는 버튼과 같은 요소가 생성 전일 수 있기 때문에 onAcitivityCreated에서 하는 것이 좋다.

위와 같은 방식으로 하면 된다.

이 때 사용되는 View 클래스는 getView() 메소드로 얻어와도 무관하고, 다음과 같이 전역에서 미리 view 변수를 선언해두었다가 inflaterinflateView를 생성할 때 얻어와도 된다.

Fragment 실습4 (Activity에서 어떻게 Fragment로 값을 넘기는가?)

이전에 Activity에서 Intent를 이용해 값을 넘길 때는 putExtra() 메소드를 이용했었다. Fragment에서는 Bundle을 사용한다.

Bundle 인스턴스 생성하고 put 메소드를 통해 값 넣기

Bundle 인스턴스를 생성하고, put자료형 형태의 메소드를 이용하여 key, value 형식으로 값을 넣는다.

그리고 Fragment 객체에 setArguments() 메소드를 통하여 만든 bundle을 주입한다.

Fragment 클래스에서 꺼내서 확인하기

위와 같이 확인하면 된다.

Fragment에서 추가적인 로직을 수행할 때는 onActivityCreated() 에서 수행하는 것이 안전하다.

getArguments()Fragment에 전해진 Bundle을 받아올 수 있고 get자료형 메소드로 값을 가져올 수 있다.

로그 확인 결과 이상없이 잘 작동한다.

BUNDLE KEY의 디자인 패턴

일반적으로는 String 형태인 Key를 중구난방으로 설정하면 까먹거나 매번 찾게되므로 저렇게 선언해두는 경우가 많다.

다른 클래스에서 찾을 때도.

이렇게 작성하고 빨간줄이 나왔을 때 Alt+Enter를 이용하여 쉽게 찾을 수 있다.

profile
풀스택 웹개발자로 일하고 있는 Jake Seo입니다. 주로 Jake Seo라는 닉네임을 많이 씁니다. 프론트엔드: Javascript, React 백엔드: Spring Framework에 관심이 있습니다.

0개의 댓글