<프래그먼트란?>
프래그먼트는 분할된 화면들을 독립적으로 구성하고, 화면들의 상태를 관리하기 위해 존재한다. (그래서 태블릿의 경우 더욱 유용하게 사용됨)
액티비티 안에 다른 액티비티를 넣는 것은 비효율적이기 때문에 프래그먼트를 넣는 것.
프래그먼트 관점에서 액티비티가 시스템 역할을 해주기 때문에, 프래그먼트는 액티비티 위에 올라가야함. (올라가는 시점이 프래그먼트가 동작하는 시점이다.)
(액티비티의 '화면'과 프래그먼트의 '화면'은 다른 것이다. 액티비티는 시스템에서 관리하는 화면이고 프래그먼트는 단순히 화면의 일부이다.)
액티비티와 액티비티 간의 데이터 전달 : 인텐트 사용
액티비티와 프래그먼트 간의 데이터 전달 : 메서드 사용 (더 단순함)
-> 화면 전환에는 액티비티보단 프래그먼트를 사용하는 것이 더 가볍게 만들 수 있음.
<Fragment 클래스>
public final Activity getActivity()
이 프래그먼트를 포함하는 액티비티를 반환함.
public final FragmentManager getFragmentManager()
이 프래그먼트를 포함하는 액티비티의 프래그먼트 매니저를 반환함. (프래그먼트 매니저 : 프래그먼트를 관리함)
public final Fragment getParentFragment()
이 프래그먼트를 포함하는 부모가 프래그먼트일 경우 리턴함. 액티비티라면 null을 반환함.
public final int getid()
이 프래그먼트의 ID를 반환함.
<FragmentManager 클래스>
FragmentManager 객체는 add(프래그먼트를 액티비티에 추가), replace(다른 프래그먼트로 변경), remove(삭제)할 때 주로 사용할 수 있다.
getSupportFragmentManager 또는 getFragmentManager 메서드를 호출하면 참조할 수 있다. (전자의 경우 예전 버전까지 호환되기 때문에, 전자의 메서드를 사용하는 것을 권장한다.)
public abstract FragmentTransaction beginTransaction()
프래그먼트를 변경하기 위한 트랜잭션을 시작함.
public abstract Fragment findFragmentById(int id)
ID를 이용해 프래그먼트 객체를 찾음.
public abstract Fragment findFragmentByTag(String tag)
태그 정보를 사용해 프래그먼트 객체를 찾음.
public abstract boolean executePendingTransactions()
즉시 실행하고 싶을 시 이 메서드를 추가로 호출해야 함. (트랜잭션은 commit 메서드를 호출하면 실행되지만 비동기 방식으로 실행되기 때문)
<Fragment 만들어 화면에 추가하기>
1. 프로젝트를 만드는데 이 때 패키지명을 새로 입력한다. (org.techtown.fragment)
(나의 경우 새 프로젝트를 이미 생성한 뒤에 패키지명을 새로 입력해야한다는 사실을 알고 바꿔줌. https://sand-to-desert.tistory.com/80)
자동으로 입력되는 패키지명을 사용할 경우, 패키지명이 너무 길어질 수 있어서 그렇다고 함.
2. 새 프래그먼트를 만든다.
프래그먼트의 이름은 MainFragment로 만들었다.
(위에서 처음부터 패키지명을.. 입력해줬으면 상관없겠지만 나의 경우 새 프로젝트를 만든 뒤 후에 패키지명을 변경해줬기 때문에, 위 사진처럼 프래그먼트를 생성하면 처음에 만든 패키지명대로 폴더가 생성되면서 거기에 프래그먼트가 만들어진다. 귀찮군.. 그래서 생성한 프래그먼트를 MainActivity가 있는 폴더로 넣어주는 과정이 추가되었다.)
3. <MainFragment.java>
package org.techtown.fragment;
public class MainFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_main, container, false);
}
}
프래그먼트를 만들면 코드가 많지만, 이번 예제에서는 화면에 나타내기만 할 것이기 때문에 onCreateView 메서드를 제외하고 모두 지운다. (추가되는 코드는 없다.)
return inflater.inflate(R.layout.fragment_main, container, false);
inflate 메서드의 파라미터를 보자.
첫번째 파라미터는 XML 레이아웃 파일이다.
두번째 파라미터는 이 XML 레이아웃이 설정될 뷰그룹 객체가 된다. (onCreateView 메서드로 전달되는 두번째 파라미터(ViewGroup container)가 이 프래그먼트의 가장 상위 레이아웃이므로, containor 객체를 전달하면 된다. 좀 이해가 안가지만 일단 넘어가자.)
4. 프래그먼트를 액티비티에 추가하기
XML 또는 java 소스코드에서 추가할 수 있는데, 여기선 XML 레이아웃을 사용하여 추가하겠다.
방법 1. 태그 사용
직접 입력하기.
<activity_main.xml>
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="org.techtown.fragment.MainActivity">
<fragment
android:id="@+id/mainFragment"
android:name="org.techtown.fragment.MainFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</FrameLayout>
솔직히 뭐.. 태그는 귀찮으니까 이렇게 작성하는건 비추고. 태그 한번 보면서 어떻게 되어있는지 보려고 써둔거.
최상위 레이아웃 -> FrameLayout으로 변경
안에 <fragment> 태그 추가. 그 안에 id와 name을 설정해준다. name은 패키지명을 포함한 이름으로 설정한다.
프래그먼트가 꽉 찰 수 있게 너비와 높이는 모두 match_parent로 설정해준다.
방법 2. 드래그
Palette > Common > FragmentContainorView를 드래그해서 레이아웃에 배치한다.
<문제 발생 - 화면에 꽉 안차는 상황>
방법 2를 사용하면 방법 1이랑 코드가 좀 다르다.
방법 2로 만든 뒤 실행했는데 왼쪽 사진과 같이 화면에 꽉 차지 않았다.
코드를 확인해보니, 프래그먼트의 너비와 높이가 wrap_content로 설정되어있었다.
match_parent로 변경해주었더니 해결.
<문제 발생2 - 패키지명 변경에 의한 후폭풍>
이건 처음 앱 실행 때 발생한 에러이다. (패키지명을 나중에 바꾸지만 않았으면.. 발생하지 않았을 문제)
뭐 해결하기 어려운 문제는 아니었음. 그냥 MainActivity에서 자동으로 처음에 import 처음의 패키지명.R로 작성되어서,
변경한 패키지명을 작성하니까 제대로 작동했다.
근데 이걸로 알았다.. 패키지명 변경하면 진짜 개 귀찮다는 사실을.
'TIL > 안드로이드 스튜디오' 카테고리의 다른 글
5장 - 프래그먼트 수명주기 & 분할화면 만들기 (0) | 2024.12.16 |
---|---|
5장 - 프래그먼트 기초1 : 2개의 화면전환 (0) | 2024.12.16 |
패키지명 변경하기 (0) | 2024.12.16 |
도전!8 - 세 개 이상의 화면 만들어 전환하기 (0) | 2024.12.13 |
도전!7 - 로그인 화면과 메뉴 화면 전환하기 (0) | 2024.12.12 |