[Android] Fragment 정리

Minjun Kim·2023년 8월 22일
0

Android

목록 보기
19/47
post-thumbnail

📝 스파르타코딩클럽의 '내일배움캠프' 지급 강좌를 정리한 글 입니다.


❓ Fragment 란?

액티비티 위에서 동작하는 모듈화된 사용자 인터페이스

앱을 개발하면서 액티비티가 점점 늘어날 경우에 그것들을 모두 Intent로 연결하는 것은 너무 복잡하다.

그래서 Fragment 를 사용하게 된다.

즉, 하나의 액티비티 안에서 특정 영역 만 프래그먼트로 표시하는 것이다.

📌 액티비티와 프래그먼트의 차이

Activity 는 시스템의 액티비티 매니저에서 인텐트를 해석해 액티비티 간 데이터를 전달

Fragment 는 액티비티의 프래그먼트 매니저에서 메소드로 프래그먼트 간 데이터를 전달

❓ 프래그먼트를 사용하는 이유

  1. Fragment를 사용하면 Activity를 적게 만들 수 있다.

  2. Activity의 복잡도를 줄일 수 있다.

  3. Fragment를 사용하면 재사용할 수 있는 레이아웃을 분리해서 관리가 가능하다.

  4. Fragment를 사용하면 최소 1개의 Activity 안에서 Fragment 공간에 View만 집어넣으면 여러 Activity 를 만들지 않아도 여러 화면을 보여줄 수 있다.

액티비티의 화면 전환보다 프래그먼트로 화면 일부만 전환하는 것이 자원이 적게 든다.

❗ 결국 퍼포먼스 때문에 사용한다는 의미


📚 Fragment 사용 방법

액티비티와 비슷하게 하나의 KT 파일과 하나의 XML 레이아웃을 정의한다.
그리고 액티비티 레이아웃 파일에 추가한다.

1. KT 소스 코드 파일 생성

class FirstFragment : Fragment() {
	override fun onCreateView(
    	inflater: LayoutInflater, container: ViewGroup?,
		savedInstanceState: Bundle?
    ): View? {
    	// Inflate the layout for this fragment
    	return inflater.inflate(R.layout.fragment_first, container, false)
	}
  • Fragment를 상속 받는다.

  • 반드시 onCreateView() 콜백 메소드를 구현한다.

  • inflate로 사용할 레이아웃 XML 파일 지정한다.

2. XML 레이아웃 생성

/res/layout 폴더 하위에 레이아웃.xml 생성

3. 프래그먼트를 액티비티 레이아웃 파일에 추가

2가지 방법이 있다.

  • 액티비티 XML 파일 안에서 정적으로 추가

  • KT 소스 코드에서 동적으로 추가

액티비티 XML 파일 안에서 추가

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!" />
    <fragment
        android:name="com.skmns.fragmentbasic.FirstFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/fragment" />
</LinearLayout>
  • android:name 으로 사용할 프래그먼트 지정

❗ 프래그먼트는 액티비티가 재시작되는 경우 프래그먼트를 복구하기 위해 시스템이 사용할 수 있는 고유한 식별자가 필요하다. 프래그먼트에 ID를 지정하는 방법은 3가지가 있다.

  1. android:id 속성으로 지정

  2. android:tag 속성으로 지정

  3. 만약 아무것도 지정하지 않는다면 시스템은 컨테이너 뷰의 ID를 사용한다.

KT 소스 코드에서 추가

  • Fragment Manager 를 사용한다.
supportFragmentManager.commit {
            replace(R.id.frameLayout, frag)
            setReorderingAllowed(true)
            addToBackStack("")
        }
  • supportFragmentManager
    사용자 상호작용에 응답해 Fragment를 추가하거나 삭제하는등 작업을 할 수 있게 해주는 매니저

  • replace
    어느 프레임 레이아웃에 띄울것이냐, 어떤 프래그먼트냐

  • setReorderingAllowed
    애니메이션과 전환이 올바르게 작동하도록 트랜잭션과 관련된 프래그먼트의 상태 변경을 최적화

  • addToBackStack
    뒤로가기 버튼 클릭시 다음 액션 (이전 fragment로 가거나 앱이 종료되거나)

실습 예제

아래와 같은 화면을 구성해보자.

1. Fragment (Blank) 생성

  • 파일은 FirstFragment로 생성했다.

  • 자동으로 res/layout 하위에 fragment_first.xml 파일이 생성된다.

2. fragment_first.xml 수정

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
	xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#F19B9B">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="프래그먼트 1"
        android:textAllCaps="false"
        android:textSize="40sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

3. SecondFragment도 동일하게 생성

  • fragment_second.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:background="#C785D3"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="프래그먼트 2"
        android:textAllCaps="false"
        android:textSize="40sp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>

4. activity_main.xml 수정

  • Fragment 를 표시할 FrameLayout과 버튼 2개 선언

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 
    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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <FrameLayout
        android:id="@+id/frameLayout"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginStart="10dp"
        android:layout_marginEnd="10dp"
        app:layout_constraintBottom_toTopOf="@+id/fragment1_btn"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">
    </FrameLayout>

    <Button
        android:id="@+id/fragment1_btn"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"
        android:text="Frag1"
        android:textAllCaps="false"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@+id/fragment2_btn"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/frameLayout" />

    <Button
        android:id="@+id/fragment2_btn"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"
        android:text="Frag2"
        android:textAllCaps="false"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@+id/fragment1_btn"
        app:layout_constraintTop_toBottomOf="@+id/frameLayout" />

</androidx.constraintlayout.widget.ConstraintLayout>

5. KT 소스 코드 작성

Fragment 를 동적으로 추가 해보자.

  • 우선 build.gradle에 fragment 라이브러리를 추가한다.
implementation("androidx.fragment:fragment-ktx:1.5.5")

KT 파일 작성

  • MainActivity.kt
package com.example.test

class MainActivity : AppCompatActivity() {

	private val binding by lazy { ActivityMainBinding.inflate(layoutInflater) }

	override fun onCreate(savedInstanceState: Bundle?) {
		super.onCreate(savedInstanceState)
		setContentView(binding.root)

		binding.apply {
			fragment1Btn.setOnClickListener {
				setFragment(FirstFragment())
			}
			fragment2Btn.setOnClickListener {
				setFragment(SecondFragment())
			}
		}
		setFragment(FirstFragment())
	}

	private fun setFragment(frag: Fragment) {
		supportFragmentManager.commit {
			replace(R.id.frameLayout, frag)
			setReorderingAllowed(true)
			addToBackStack("")
		}
	}
}
profile
응애 나 아기 뉴비

0개의 댓글