https://survivalcoding.com/p/android_basic
위 서적을 참고하였습니다.
이번 포스트에선 Fragment에 대해 소개하겠습니다. 먼저 프래그먼트의 탄생 배경입니다. 옛날 스마트폰이 한창 개발되는 시기엔 복잡한 레이아웃이나 위젯이 많이 필요 없었습니다. 대표적인 이유가 화면이 작아 별로 배치할 것들이 많지 않았기 때문인데요, 근데 태블릿이 갑자기 등장하면서 분위기는 반전이 되었습니다. 일단 태블릿은 화면이 커 다양한 레이아웃과 위젯 등을 포함시킬 수 있는데 액티비티로만 구성을 하려니 이게 어느 순간 부담이 되어버려 가지고 탄생한 것이 Fragment입니다.
이처럼 프래그먼트를 사용하면 재사용할 수 있는 레이아웃을 분리해서 관리할 수 있고, 액티비티의 복잡도도 줄여주며, 크기가 고정이라 하더라도 부분적인 UI 변화에서 유용하게 사용됩니다. 특히, 액티비티 하나만 만들고 나머지는 프래그먼트로 처리하여 단일 액티비티로 개발할 때도 있습니다.
그럼 프래그먼트와 액티비티의 차이점은 뭘까요?
1. 프래그먼트는 여러 화면에서 재사용이 가능합니다.
2. 생명주기를 가지고 있는 뷰입니다.
3. 프래그먼트는 동적으로 추가, 삭제, 교체가 용이합니다.(transaction)
다음은 프래그먼트 생명주기입니다.
기존의 사용하던 액티비티보다 더욱 세분화 되어있는 것을 볼 수 있습니다. 액티비티가 onCreate()할 때 프래그먼트는 onAttach() -> onCreate() -> onCreateView() -> onActivityCreated() 메소드가 호출합니다. 액티비티가 onDestroy()할 때 프래그먼트는 onDestroyView() -> onDestroy() -> onDetach() 메소드들을 호출합니다.
프래그먼트를 사용하기 위해선 Fragment를 상속받은 클래스를 생성해야 합니다. 그다음 위의 메소드들을 오버라이딩을 해서 구현하면 됩니다.
프래그먼트를 사용하기 전 고려해야 할 것은 앱의 구조입니다. 보통 액티비티는 프래그먼트를 담고 있는 전체 디자인 박스라고 생각하면 편합니다.(하나의 틀) 예를 들어, 액티비티에 메뉴가 있다면, 그 메뉴의 항목에 따라 UI나 아이콘 등이 바뀌는 것은 프래그먼트가 처리를 하는 것입니다. 이는 액티비티로 구현하면 매우 복잡한 일입니다.
이제 프래그먼트에 대한 간단한 구현법에 대해 알아보겠습니다. 먼저 프래그먼트를 레이아웃에 작성하는 법입니다.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<fragment
android:name="hello.world.study.MainActivity"
android:id="@+id/list"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent"/>
<fragment
android:name="hello.world.study.SeondActivity"
android:id="@+id/view"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent"/>
</LinearLayout>
이게 보통의 프래그먼트를 XML로 작성하는 방법입니다. 일반 뷰와 다른 점은 name속성이 필수이며, 실제 프래그먼트 클래스의 전체 경로를 지정합니다. 또한, id 혹은 tag 속성 중 하나는 반드시 사용해야 합니다.
다음은 자바코드입니다.
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
ExampleFragment fragment = new ExampleFragment();
fragmentTransaction.add(R.id.fragment_container, fragment);
fragmentTransaction.commit();
}
}
프래그먼트를 자바 코드로 동적으로 추가하려면 XML의 LinearLayout에 해당하는(id : fragment_container) 뷰 그룹이 하나 필요하며, 프래그먼트의 추가, 제거, 교체를 동적으로 수행하려면 FragmentManager 객체가 필요합니다. 또한, 이 객체를 얻으려면 getFragmentManager() 혹은 getSupportFragmentManager() 메소드를 사용해야 합니다.
getSupportFragmentManager()는 getFragmentManager()이랑 같은 기능인데, 더 낮은 안드로이드 버전에서 원활하게 돌아갈 수 있도록 하는 메소드입니다.
프래그먼트의 추가, 제거, 교체를 한 번에 여러 가지를 동시에 수행할 수 있는 집합이 Transaction입니다. 마지막으로 트랜잭션을 commit() 메소드를 호출하면 작업한 내용들이 적용됩니다.
프래그먼트 매니저는 액티비티처럼 BackStack을 가지고 있습니다. 이를 이용해 프래그먼트가 뒤로 가는 효과를 낼 수 있습니다. 백스택을 사용하려면 addToBackStack()을 수행해야 합니다. 다음은 하나의 프래그먼트를 다른 프래그먼트로 교체하고 이전 상태를 백스택에 보존하는 방법입니다.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//새 프래그먼트와 새 트랜잭션
Fragment newFragment = new ExampleFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
//fragment_container 영역의 프래그먼트를 newFragment로 교체
//백스택에 트랜잭션 추가
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
transaction.commit();
}
프래그먼트는 액티비티와도 서로 접근이 가능합니다.
//프래그먼트에서 액티비티에 접근하는 예
View listView = getActivity().findViewById(R.id.list);
//액티비티에서 프래그먼트로 접근하는 예
ExampleFragment fragment = (ExampleFragment) getFragmentManager().findFragmentById(R.id.example_fragment);
여기까지 프래그먼트에 대해 기초적인 것을 배웠습니다. 다음 포스트에선 간단한 프래그먼트 예제를 만들어 보겠습니다. 감사합니다.
'Android > Android' 카테고리의 다른 글
[Android] 안드로이드 프래그먼트 (Fragment) (3) (4) | 2020.06.15 |
---|---|
[Android] 안드로이드 프래그먼트 (Fragment) (2) (0) | 2020.06.15 |
[Android] 안드로이드 화면 회전 시 데이터 사라지는 현상 막기(onSaveInstanceState, onRestoreInstanceState) (0) | 2020.06.14 |
[Android] 다중 창 막기 (0) | 2020.06.14 |
[Android] 화면 회전 고정 (0) | 2020.06.14 |