제트팩 라이브러리 - 2

이윤설·2024년 8월 29일
0

3. 프래그먼트 - 액티비티처럼 동작하는 뷰

프래그먼트와 뷰 페이저2는 중요하다.
androidx.fragment 라이브러리를 이용해 구현한다.

프래그먼트 소개

하나의 액티비티 안에서 화면 일부분을 따로 만지고 싶은데 어떻게 하지..?
다른 액티비티에서도 현재 액티비티의 부분들을 써야하는데..
그 때 필요한 개념이 프래그먼트(Fragment)다.
프래그먼트는 하나의 UI 내에서 독립적으로 동작하는 화면 부분을 만들고 싶을 때 사용한다.

프래그먼트는 반드시 액티비티에 속해야 하며, 액티비티와 상호작용하여 자신의 생명 주기를 관리한다. 즉, 프래그먼트는 액티비티가 관리하는 컨테이너에 삽입되어야 한다.

프래그먼트 구현

프래그먼트 등록 과정

1. 레이아웃 파일 생성: Fragment의 UI를 정의하는 XML 파일을 작성한다.
2. Fragment 클래스 생성: UI를 표시하고 동작을 정의하는 Fragment 클래스를 구현한다.
3. Activity 레이아웃에 공간 정의: Fragment가 삽입될 공간을 Activity의 레이아웃 파일에 정의한다.
4. Fragment 삽입 코드 작성: Activity에서 Fragment를 동적으로 추가하거나 교체하는 코드를 작성한다.


1. Fragment 레이아웃 파일 (fragment_example.xml)

<!-- res/layout/fragment_example.xml -->
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp">

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="I am Fragment" />
</LinearLayout>

2. Fragment 클래스 (ExampleFragment.kt)

class ExampleFragment : Fragment() {

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val view = inflater.inflate(R.layout.fragment_example, container, false)
        
        // Button을 찾고 클릭 리스너를 설정
        val button: Button = view.findViewById(R.id.button)
        button.setOnClickListener {
            Log.d("ExampleFragment", "Button in Fragment clicked!")
        }
        
        return view
    }
}
  • ExampleFragment 클래스는 Fragment를 상속받아 Fragment를 정의한다.
  • onCreateView: 이 함수는 우리의 화면 조각이 보여질 때 실행된다. 여기서 화면에 무엇을 보여줄지 결정한다.
  • inflater.inflate(R.layout.fragment_example, container, false):
    • fragment_example.xml은 Fragment의 모양을 정의한 설계도 같은 파일이다.
    • inflater.inflate는 이 설계도를 실제 화면에 그릴 수 있는 View 객체로 만드는 과정이다. 쉽게 말하면, 종이에 그려진 설계도를 실제 건물로 만드는 것이다.
    • container는 이 Fragment가 들어갈 큰 공간(부모 뷰)을 나타낸다.
    • false는 "지금 당장 이 Fragment를 화면에 붙이지 말고, 나중에 내가 직접 붙일게"라는 의미이다.
  • findViewById(R.id.button): 우리가 만든 화면에서 버튼을 찾는 것이다.
  • button.setOnClickListener: 버튼에 클릭 리스너를 설정한다. 버튼이 클릭되면 로그 메시지를 출력한다 (Log.d).

3. Activity 레이아웃 파일 (activity_main.xml)

<!-- res/layout/activity_main.xml -->
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/fragment_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

android:id="@+id/fragment_container": 이 FrameLayout의 ID다. Fragment를 이 컨테이너에 추가할 때 사용된다.

4. Activity 클래스 (MainActivity.kt)

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        if (savedInstanceState == null) {
            // Create a new instance of the fragment
            val exampleFragment = ExampleFragment()

            // Get the FragmentManager
            val fragmentManager: FragmentManager = supportFragmentManager

            // Begin a transaction to add the fragment
            fragmentManager.beginTransaction()
                .replace(R.id.fragment_container, exampleFragment) // Replace or add the fragment
                .commit() // Commit the transaction
        }
    }
}

프래그먼트 생명주기

프래그먼트는 액티비티처럼 동작하는 뷰이다.
따라서 액티비티에 작성하는 코드는 모두 프래그먼트에서도 작성할 수 있다. 따라서 프래그먼트도 액티비티와 생명주기가 동일하다.

프래그먼트와 액티비티의 생명주기 함수, 생명주기 함수가 호출되는 시점도 모두 동일하다. 즉, 액티비티의 onStart() 함수가 호출되는 순간 해당 액티비티가 출력하는 프래그먼트의 onStart() 함수도 호출된다.

프래그먼트의 생명주기는 크게 initialized -> created -> started -> resumed(재개) -> destroyed 단계로 구분된다.

1. onAttach()

  • 설명: Fragment가 액티비티에 처음 연결될 때 호출된다. 이 단계에서 Fragment는 자신이 속할 액티비티에 접근할 수 있게 된다.
  • 용도: 액티비티와의 인터페이스를 초기화하거나 필요한 리소스를 확보할 때 사용한다.

2. onCreate()

  • 설명: Fragment가 생성될 때 호출된다. 이 단계에서는 UI를 생성하지 않으며, Fragment의 상태를 유지하거나 초기화하는데 사용된다.
  • 용도: UI와 관련 없는 초기화 작업, 예를 들어, 필요한 데이터 준비나 객체 생성 등을 처리한다.

3. onCreateView()

  • 설명: Fragment가 UI를 처음으로 그릴 때 호출된다. 여기에서 Fragment의 레이아웃을 인플레이트하고 반환해야 한다.
  • 용도: Fragment의 UI를 정의하고 레이아웃을 반환한다.

4. onViewCreated()

  • 설명: onCreateView() 이후에 호출되며, Fragment의 뷰가 완전히 생성된 상태다.
  • 용도: 뷰가 생성된 후에 UI 초기화 작업을 수행하거나, 뷰에 리스너를 설정하는 작업을 한다.

5. onStart()

  • 설명: Fragment가 사용자에게 표시되기 직전에 호출된다. Fragment는 이 단계에서 사용자에게 보이기 시작한다.
  • 용도: Fragment가 사용자와 상호작용할 준비가 되었음을 나타낸다.

6. onResume()

  • 설명: Fragment가 화면에 완전히 표시되고, 사용자와 상호작용할 준비가 완료된 상태이다.
  • 용도: 사용자와의 상호작용이 활성화된 상태로, 애니메이션을 시작하거나 센서 데이터 수집 등을 처리한다.

7. onPause()

  • 설명: Fragment가 사용자와의 상호작용을 멈출 때 호출된다. 이는 일반적으로 액티비티가 다른 액티비티로 대체되거나, 화면이 부분적으로 가려질 때 발생한다.
  • 용도: 리소스를 해제하거나, 저장되지 않은 데이터를 저장하는 데 사용한다.

8. onStop()

  • 설명: Fragment가 화면에서 더 이상 보이지 않을 때 호출된다.
  • 용도: Fragment가 화면에서 사라질 때 필요한 작업(예: 애니메이션 정지, 센서 데이터 수집 중단)을 처리한다.

9. onDestroyView()

  • 설명: Fragment의 뷰 계층이 제거될 때 호출된다. 하지만 Fragment 자체는 여전히 메모리에 남아 있는 상태이다.
  • 용도: 뷰와 관련된 리소스를 정리하거나, 메모리 누수를 방지하기 위한 작업을 수행한다.

10. onDestroy()

  • 설명: Fragment가 더 이상 사용되지 않을 때 호출된다. 이 단계에서는 Fragment에 연결된 모든 리소스와 상태를 정리해야 한다.
  • 용도: Fragment가 완전히 소멸되기 전의 마지막 정리 작업을 처리한다.

11. onDetach()

  • 설명: Fragment가 액티비티와 완전히 분리될 때 호출된다.
  • 용도: Fragment가 액티비티와의 모든 연결을 해제하고, 필요시 메모리 정리 작업을 수행한다.

백 스택(back stack)

백 스택(Back Stack)은 Android에서 프래그먼트(Fragment)를 관리하는 데 중요한 역할을 한다.

프래그먼트 간의 전환이나 교체가 발생할 때, 백 스택을 사용하면 이전 프래그먼트를 메모리에 유지해 두고, 다시 필요할 때 복원할 수 있다.

이를 통해 사용자는 뒤로가기 버튼을 눌러 이전 화면으로 돌아갈 수 있는 경험을 얻을 수 있다.

백 스택의 주요 개념:

  1. 백 스택 사용 시:

    • 프래그먼트를 교체할 때, 기존의 프래그먼트는 제거되지 않고 백 스택에 저장된다.
    • 사용자가 뒤로가기 버튼을 누르면, 현재 화면에 표시된 프래그먼트가 사라지고 백 스택에 저장된 이전 프래그먼트가 복원되어 화면에 표시된다.
    • 생명주기: 이 경우, 교체된 프래그먼트는 onDestroyView()까지만 호출되며, UI가 제거되지만 프래그먼트 인스턴스 자체는 메모리에 유지된다. 이후 뒤로가기를 통해 복원되면, onCreateView()부터 다시 호출되어 UI를 재생성한다.
  2. 백 스택을 사용하지 않을 시:

    • 프래그먼트를 교체할 때, 기존의 프래그먼트는 완전히 제거된다.
    • 이 경우, 사용자가 뒤로가기 버튼을 눌러도 이전 프래그먼트로 돌아갈 수 없다. 이전 프래그먼트가 제거되었기 때문에 다시 생성해야 한다.
    • 생명주기: 기존 프래그먼트는 onDestroy()까지 호출되며, 메모리에서 완전히 삭제된다. 이때 프래그먼트의 상태와 모든 데이터도 사라진다.

출처

https://velog.io/@evergreen_tree/Android-%ED%94%84%EB%9E%98%EA%B7%B8%EB%A8%BC%ED%8A%B8-%EC%83%9D%EB%AA%85%EC%A3%BC%EA%B8%B0

https://m.yes24.com/Goods/Detail/116012310

profile
화려한 외면이 아닌 단단한 내면

0개의 댓글