5~6월은 안드로이드 ‘기초’에 대해서 알아보았습니다.
안드로이드 프래그먼트(Fragment)
- 5~6월은 안드로이드의
프래그먼트를 사용해서 가볍게 토이 프로그램을 만들어보는 것을 스터디하고, 몇가지 기초적인 사항을 기록으로 남겨봅니다. - 스터디를 하면서 배웠거나 알아봤던 내용을 기록으로 남기지 않아서 많은 내용은 없지만 필요한 몇가지 내용을 정리하였습니다.
이런게 있구나...하고 가볍게 읽어보시길 권해드립니다.
액티비티
- 액티비티는 사용자와의 인터페이스를 구성하지만 그 자체는 출력 기능이 없어 직접적으로 보이지 않으며, 사용자 눈에 실제로 보이는 것인 뷰이며 그래서 액티비티는 반드시 내부에 뷰나 뷰그룹을 가져야 함 1
- 화면의 기본 단위가 되고 가장 많이 쓰이는 컴포넌트이고 독립적인 화면이라면 액티비티를 고려하고, 종속적인 화면이라면 다른 컴포넌트를 사용 3
setContentView()를 반드시 호출해야 하는 것이 아님 해당 사항에 대한 내용은 레퍼런스 3을 참고할 것
액티비티 생명주기
- 다른 액티비티가 일부만 가리면
onPuse(), 전체를 가리면onSteop()을 호출하며, 종료시 전자의 경우onResume을 후자의 경우onRestart와onStart()를 호출- 해당 내용의 세부적인 사항은 레퍼런스 3을 참고
- 우선순위가 더 높은 앱이 메모리가 필요하다면 앱은 언제든 종료될 수 있기 때문에
onStop(),onDestroy()메서드를 반드시 실행된다는 보장은 없음 - 시스템에 의해서도 액티비티가 제거될 수 있기 떄문에 태스크의 목록이 유지된다고 가정하면 안 됨
액티비티 시작
- 액티비티끼리 서로 호출하려면 통신을 위한 장치가 필요한데 이 장치가 바로
인텐트(Intent)임 1Intent에 관한 세부적인 내용은 레퍼런스 1을 참고
startActivity()는Context메서드이기 때문에 어디서든 호출 가능하지만,startActivityForResult()는Activity의 메서드임3
주의사항
onCreate()에서 생성했다면onDestroy()에서 제거,onResume()에서 생성했다면onPause()에서 제거onCreate(),onStart(),onResume()에서는super.onXXX가 먼저 실행되고, 나머지는 나중에 실행됨
구성변경
- 구성(Configuration)은 컴포넌트에서 어떤 리소스를 사용할지 결정하는 조건, 이 조건 항목은 프레임워크에 결정되어 있음
- 구성이 변경되어 액티비티를 재시작하면 하나의 인스턴스를 가지고 새로 초기화해서 재사용하는 것이 아니고,
onDestroy()까지 실행하고 새인스턴스가onCreate()부터 실행 - 구성이 변경되어 재시작되어도 사용자 경험상 기존에 보던 화면을 유지하기 위해서
onRestoreInstanceState()나onSaveinstanceState()를 사용하면 됨onSaveInstanceState()메서더는targetSdkVersion에 따라 호출되는 시점이 다름
프래그먼트
<< 폰 >> << 태블릿 >>
-------------- -------------- ---------------------------
| | | | | | |
| | | | | | |
| | | | | | |
| 리스트 | --> | 디테일 | , | 리스트 | 디테일 |
| | | | | | |
| | | | | | |
| | | | | | |
-------------- -------------- ---------------------------
프래그먼트의 필요성
- 태블릿은 핸드셋에 비해서 화면이 훨씬 넓어 화면에 더(핸드폰에 비해서) 많은 정보를 한눈에 볼 수 있기 있음
- 액티비티는 화면 하나를 정적으로 정의하면 더 이상 분할하기 어려기 때문에 태블릿 전용으로 만들지 않으면 대화면의 이점을 누리지 못함
- 액티비티보다 더 작은 화면 단위를 정의한 것이 프래그먼트, 프래그먼트를 조합하여 완성된 화면을 표현 액티비티에 비해 실행 중에도 추가, 제거, 교체 가능하여 동적이고 유연한 화면을 만들 수 있지만, 혼자서는 독립적으로 실행할 수 없음
프래그먼트의 주요 특징
- 액티비티를 분할하여 화면의 한 부분을 정의
- 자신만의 레이아웃, 독작, 생명주기를 가지는 독립적인 모듈
- 여러 액티비티에서 재사용 가능
- 실행 중에 추가, 제거, 대체 가능하며 잠시 숨길 수도 있음
프래그먼트 생성
- 프래그먼트는
XML레이아웃 파일의 저장형태로 추가될 수 있으며, 클래스 내부에서 직접 코드로 정의해서 사용할 수 있음 - 프래그먼트를 사용하는 레이아웃의 경우
android.support.v7.app.AppCompatActivity와android.support.v4.app.Fragment를 사용해야 하며onCreateView()를 오버라이딩 해야함 XML레이아웃 파일에 포함시킬 때는<fragment>요소를 사용해서 액티비티 레이아웃에 포함
프래그먼트 생명주기
- 많은 콜백 중에서
onCreate(),onCrateView(),onPause()콜백은 거의 필수적으로 구현해야 하며 나머지는 필요할 때만 구현하면 됨
-----------------
|프래그먼트 추가|
-----------------
|
--------v--------
| onAttach |
-----------------
|
--------v-------- ----------------- -----------------
| onCreate | <-- | onDestroyView | --> | onDestroy |
----------------- --------^-------- -----------------
| | |
--------v-------- ----------------- --------v--------
| onCreateView | | onStop | | onDetach |
----------------- --------^-------- -----------------
| | |
--------v-------- ----------------- --------v--------
| onStart | | onPause | |프래그먼트 파괴|
----------------- --------^-------- -----------------
| |
--------v-------- -----------------
| onResume | |프래그먼트 실행|
----------------- -----------------
프래그먼트 초기화
void onAttach(Activity activity)- 프래그먼트가 처음 부착될 때 호출
- 인수로 전달되는
activity는 프래그먼트가 배치되는 호스트 액티비티- 프래그먼트는 홀로 사용될 수 없고 항상 액티비티에 종속적으로 사용해야 함
void onCreate(Bundle savedlnstanceState)- 프래그먼트가 생성될 때 호출
- 이 단계에서는 호스트 액티비티도 아직 초기화중인 상태이며 따라서 액티비티의 컨트롤을 안전하게 참조할 수 없기 때문에 완전히 초기화된 시점이 필요하면
onActivityCreated콜백을 사용해야 함 savedlnstanceState는 프래그먼트가 재생성될 때의 이전 상태이며 이 값을 참조하여 이전 상태로 복구
View onCreateView(Layoutlnflater inflater, ViewGroup container, Bundle savedlnstanceState)- 프래그먼트 UI를 처음 그릴 때 호출되며 이 단계에서 프래그먼트는 자신의 레이아웃을 생성한 후 최상단(root) 뷰를 반환
inflater가 인수로 전달되기 때문에inflater를 따로 생성하지 않아도 됨inflate메서드의 마지막 인수는 false여야 하고, 이 값을 true로 지정하면 전개된 뷰를 container에 부착해도 별다른 이상은 없으며 에러도 발생하지 않지만 이중으로 부착되어 자원만 낭비되므로 시스템에 맡겨두면 됨
container는 프래그먼트가 배치될 액티비티의 최상단 뷰이며 이 위치에 프래그먼트가 생성 및 배치됨
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_layout, container, false);
}
void onActivityCreated(Bundle savedlnstanceState)- 액티비티가 완전히 초기화되고 프래그먼트의 레이아웃도 완성되었을 때 호출
- 이 메서드에서 뷰의 상태를 복구하는 등의 동작을 안전하게 수행할 수 있으며 액티비티의 다른 위젯을 참조하거나 조작할 수 있음
프래그먼트 시작
프래그먼트 초기화의 메서드를 차례대로 실행 한 후 onStart와 onResume가 연이어 호출됨
void onPause()- 프래그먼트가 정지될 때 호출됨
void onSavelnstanceState(Bundle outState)onPause와 함께 호출되며 이 메서드에서 임시 정보를 저장함onState에 정보를 저장하면 프래그먼트가 재생성 될 때 다시 전달됨
프래그먼트 관리자
- 프래그먼트와 관련된 편집 작업은 프래그먼트 관리자를 사용하며 이 객체는 아래 두 메서드로 구현
FragmentManager Activity.getFragmentManager()FragmentManager Fragment.getFragmentManager()
- 액티비티와 프래그먼트에 같은 이름의 메서드가 제공되므로 언제든지 관리자 객체를 얻을 수 있음
Fragment findFragmentByld(int id)Fragment findFragmentByTag(String tag)
- 프래그먼트는 다음 3가지 방식으로 지칭
- id : 프래그먼트를 배치할 때 지정한
android:id속성의 정수값을 사용 - 부모의 id : 실행 중에 생성한 프래그먼트는 고유한
id가 없기 때문에 부모의id를 통해 프래그먼트를 찾음 - 문자열 형태의 태그 : 실행 중의 프래그먼트를 생성할 때 고유한 이름의 태그를 붙일 수 있으며, UI가 없는 프래그먼트의 겨우 XML 문서에서
android:tag속성으로 태그명을 부여함
- id : 프래그먼트를 배치할 때 지정한
실행 중 프래그먼트 추가, 제거 교체
FragmentTransaction beginTransaction()- 동시에 여러 동작을 처리해야 하며 프래그먼트의 부피가 크면 상당한 시간이 걸릴 수 있음
- 뿐만 아니라 각 동작마다 화면을 갱신하면 화면 깜박거림이 발생하기 떄문에 전체 편집 동작을 한 묶음으로 처리하기 위해 트랜잭션으로 처리함
- 프래그먼트 관련 처리를 모아 두었다가 한꺼번에 처리하기 위해 트랜잭션으로 묶는 것 뿐임
FragmentTransaction add(int containerViewld , Fragment fragment [, String tag]),FragmentTransaction add(Fragment fragment , String tag)- 프래그먼트 추가를 위한 메서드
containerViewld는 프래그먼트가 추가될 부모 View의idfragment는 추가할 프래그먼트 객체이며,tag인수로 이름을 지정
FragmentTransaction remove(Fragment fragment)- 프래그먼트가 화면에서 사라짐
FragmentTransaction replace(int containerViewld, Fragment fragment [, String tag])- 프래그먼트를 다른 프래그먼트로 대체
FragmentTransaction show(Fragment fragment), *FragmentTransaction hide(Fragment fragment)- 프래그먼트를 숨기거나 화면에 보일 수 있음
int commit()- 스레드가 한가할 때 처리하도록 스케줄링을 함
- 이 메서드를 호출하지 안흐면 트랜잭션 편집은 모두 취소
- 김상형, “안드로이드 프로그래밍 정복 Vol.2 – 6.X 마시멜로와 안드로이드 스튜디오를 기반으로 다시 집필한, 전면개정판,” 한빛미디어, 2016 (많은 분들이 참고하시는 교재이긴 하지만, 몇가지 변경사항이 반영되지 못한 부분이 존재하기 때문에 권하고 싶지 않음) ↩
- 닐 스미스, 심재철, “실무에 바로 적용하는 안드로이드 프로그래밍,” 제이펍, 2016 (부산에서 스터디를 하면서 가장 많은 도움이 되었음. 작은 프로젝트를 기반으로 진행되기 때문에 안드로이드 초심자분들에게 좋은 책) ↩
- 노재춘, “안드로이드 프로그래밍 Next Step,” 인사이트, 2017 (글을 작성하면서 참고한 책 중에서 가장 알찬 지식을 전해주는 책, 강추!) ↩
Array