반응형
프래그먼트 사용 목적
분할된 화면들을 독립적으로 구성하기 위해 사용함
분할된 화면들의 상태를 관리하기 위해 사용함
액티비티는 시스템에서 관리하는 화면이고, 프래그먼트는 액티비티 위에 올라가는 화면의 일부
Fragment 클래스에 있는 주요 메소드
public final Activity getActivity()
이 프래그먼트를 포함하는 액티비티를 반환함
public final FragmentManager getFragmentManager()
이 프래그먼트를 포함하는 액티비티에서 프래그먼트 객체들과 의사소통하는 프래그먼트 매니저를 반환함
public final Fragment getParentFragment()
이 프래그먼트를 포함하는 부모가 프래그먼트일 경우 리턴함. 액티비티이면 null을 반환함
public final int getId()
이 프래그먼트의 id를 반환함
FragmentManager 클래스에 있는 주요 메소드
public abstract FragmentTransaction beginTransaction()
프래그먼트를 변경하기 위한 트랜잭션을 시작함
public abstract Fragment findFragmentById(int id)
ID를 이용해 프래그먼트 객체를 찾음
public abstract Fragment findFragmentByTag(String tag)
태그 정보를 사용해 프래그먼트 객체를 찾음
public abstract boolean executePendingTransactios()
트랜잭션은 commit 메소드를 호출하면 실행되지만 비동기 방식으로 실행되므로 즉시 실행하고 싶다면
이 메소드를 추가로 호출해야함
프래그먼트가 화면에 보이기 전까지 호출될 수 있는 수명 주기 메소드
onAttach(Activity)
프래그먼트가 액티비티와 연결될 때 호출됨
onCreate(Bundle)
프래그먼트가 초기화될 때 호출됨
new 연산자를 이용해 새로운 프래그먼트 객체를 만드는 시점이 아니라는 점에 주의
onCreateView(LayoutInflator, ViewGroup, Bundle)
프래그먼트와 관련되는 뷰 계층을 만들어서 리턴함
onActivityCreated(Bundle)
프래그먼트와 연결된 액티비티가 onCreate 메소드의 작업을 완료했을 때 호출됨
onStart()
프래그먼트와 연결된 액티비티가 onStart되어 사용자에게 프래그먼트가 보일 때 호출됨
onResume()
프래그먼트와 연결된 액티비티가 onResume되어 사용자와 상호작용할 수 있을 때 호출됨
프래그먼트가 화면에서 보이지 않게 되면서 호출되는 상태 메소드
onPause()
프래그먼트와 연결된 액티비티가 onPause되어 사용자와 상호작용을 중지할 때 호출됨
onStop()
프래그먼트와 연결된 액티비티가 onStop되어 화면에서 더 이상 보이지 않을 때나
프래그먼트의 기능이 중지되었을 때 호출됨
onDestroyView()
프래그먼트와 관련된 뷰 리소스를 해제할 수 있도록 호출됨
onDestroy()
프래그먼트의 상태를 마지막으로 정리할 수 있도록 호출됨
onDetach()
프래그먼트가 액티비티와 연결을 끊기 바로 전에 호출됨
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/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<fragment
android:id="@+id/mainFragment"
android:name="com.example.a28_samplefragment.MainFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"></fragment>
</FrameLayout>
fragment_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainFragment" >
<EditText
android:id="@+id/editTextTextPersonName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="textPersonName"
android:text="메인 프래그먼트"
android:textSize="30sp" />
<Button
android:id="@+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="메뉴 화면으로" />
</LinearLayout>
fragment_menu.xml (fragment_main.xml를 그대로 복사하여, 버튼의 id가 button2가 아니라, 똑같이 button이다)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#EDBEBE"
android:orientation="vertical"
tools:context=".MainFragment">
<EditText
android:id="@+id/editTextTextPersonName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="textPersonName"
android:text="메뉴 프래그먼트"
android:textSize="30sp" />
<Button
android:id="@+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="메인 화면으로" />
</LinearLayout>
MainActivity
package com.example.a28_samplefragment;
import androidx.appcompat.app.AppCompatActivity;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
public class MainActivity extends AppCompatActivity {
MainFragment mainFragment;
MenuFragment menuFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 메인 프래그먼트는 액티비티를 위한 activity_main.xml 파일에 추가되어 있으므로 id를 사용해서 찾아야한다
// 그런데 프래그먼트는 뷰가 아니라서 Activity 클래스에 있는 findViewById 메소드로 찾을 수 없다
// 대신에 프래그먼트를 관리하는 FragmentManager 객체의 findFragmentById 메소드를 사용해서 찾을 수 있다
//
// 액티비티에 추가 된 후 프래그먼트로 동작함
mainFragment = (MainFragment) getSupportFragmentManager().findFragmentById(R.id.mainFragment);
// 프래그먼트 객체는 만들어졌지만 프래그먼트로 동작하지는 않음
menuFragment = new MenuFragment();
}
// 왜 액티비티에서 코드를 작성하는가
// 프래그먼트가 액티비티를 본떠 만들었고, 액티비티 관리를 시스템에서 하는 것처럼, 프래그먼트 관리를 액티비티가 하기 때문에
// 액티비티에서 프래그먼트를 전환하도록 만들어야 하기 때문이다
// 하나의 프래그먼트에서 다른 프래그먼트를 띄우는 것이 아니라, 액티비티를 통해 띄워야한다
public void onFragmentChanged(int index) {
// 프래그먼트 매니저 객체를 사용할 때는 트랜잭션이 사용된다
// 프래그먼트 매니저는 프래그먼트를 다루는 작업을 해주는 객체로 프래그먼트 추가, 삭제, 또는 교체 등의 작업을 할 수 있게 한다
// 그런데 이런 작업들은 프래그먼트를 변경할 때 오류가 생기면 다시 원래 상태로 돌릴 수 있어야 하므로 트랜잭션 객체를 만들어 실행한다
// 트랜잭션 객체는 beginTransaction 메소드를 호출하면 시작되고, commit 메소드를 호출하면 실행된다
if (index == 0) {
getSupportFragmentManager().beginTransaction().replace(R.id.container, menuFragment).commit();
} else if (index == 1) {
getSupportFragmentManager().beginTransaction().replace(R.id.container, mainFragment).commit();
}
}
}
MainFragment
package com.example.a28_samplefragment;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
public class MainFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// 첫 번째 파라미터 - xml 레이아웃 파일
// 두 번째 파라미터 - xml 레이아웃이 설정될 뷰그룹 객체, onCreateView 메소드로 전달되는 두 번째 파라미터가 이 프래그먼트의 가장 상위 레이아웃이므로 그대로 container 객체 전달
ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.fragment_main, container, false);
Button button = rootView.findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
MainActivity activity = (MainActivity) getActivity();
// onFragmentChanged - 프래그먼트매니저를 이용해 프래그먼트를 전환하는 메소드
// 프래그먼트 관리를 액티비티가 하기 때문에, 액티비티에서 프래그먼트를 전환하도록 만들어야한다
// 하나의 프래그먼트에서 다른 프래그먼트를 직접 띄우는 것이 아니라, 액티비티를 통해 띄워야한다
activity.onFragmentChanged(0);
}
});
return rootView;
}
}
MenuFragment
package com.example.a28_samplefragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import androidx.fragment.app.Fragment;
public class MenuFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.fragment_menu, container, false);
Button button = rootView.findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
MainActivity activity = (MainActivity) getActivity();
activity.onFragmentChanged(1);
}
});
return rootView;
}
}
반응형
'안드로이드' 카테고리의 다른 글
액션바 (0) | 2021.10.19 |
---|---|
한 화면에 2개의 프래그먼트 (0) | 2021.10.19 |
라이프사이클 (0) | 2021.10.18 |
태스크 관리 (0) | 2021.10.14 |
Paracelable 다른 참고 자료 (0) | 2021.10.14 |