[UMC] Android 6주차 워크북 (고급 Layout과 View)

2022. 11. 7. 21:49·🍞 대외활동 & 부트캠프/IT연합동아리 UMC

📌 학습 목표

- BottomNavigationView을 구성하고 사용할 수 있다.
- TabLayout을 구성하고 사용할 수 있다.
- ViewPager를 구성하고 사용할 수 있다.

 

ViewPager2  |  Android 개발자  |  Android Developers

컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 스와이프할 수 있는 형식으로 뷰 또는 프래그먼트를 표시합니다. 최근 업데이트 공개 버전 출시 후보 베타

developer.android.com

 

📝 Standard Mission

1. BottomNavigationView를 이용해서 3개 이상의 Fragment를 오고가는 Activity 구현하기

    - 각각 다른 아이콘 적용
    - 각각 다른 Fragment로 이동하도록 적용
        - Fragment 내용은 자유
        - 단순하게 구성해도 됨 (ex. Fragment 1, Fragment 2와 같이 TextView 배치)

 

먼저, bottomNavigationView에 들어갈 메뉴 4개(홈, 설정, 알림, 마이페이지)를 넣어준다.

menu/menu_bottomnav.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/menu_home"
        android:title="홈"
        android:icon="@drawable/ic_baseline_home_24" />
    <item
        android:id="@+id/menu_setting"
        android:title="설정"
        android:icon="@drawable/ic_baseline_settings_24" />
    <item
        android:id="@+id/menu_alarm"
        android:title="알림"
        android:icon="@drawable/ic_baseline_notifications_24" />
    <item
        android:id="@+id/menu_mypage"
        android:title="마이페이지"
        android:icon="@drawable/ic_baseline_person_24" />

</menu>

 

HomeFragment (SettingFragment, AlarmFragment, MypageFragment 동일)

package com.example.homework6_1

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import com.example.homework6_1.databinding.FragmentHomeBinding

class HomeFragment: Fragment() {
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return FragmentHomeBinding.inflate(layoutInflater).root
    }
}

 

첫 화면을 home화면으로 설정해준다.

그리고 setOnItemSelectedListener를 통해 id에 따라서 Fragment를 교체한다.

MainActivity.kt

package com.example.homework6_1

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.example.homework6_1.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {

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

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

        // 처음에 어떤 화면을 기본으로 할지
        supportFragmentManager
            .beginTransaction()
            .replace(binding.containerFragment.id, HomeFragment())
            .commitAllowingStateLoss()

        // run(범위함수) 사용하면 navBottom 바로 쓸 수 있음
        binding.navBottom.run {
            setOnItemSelectedListener {
                when (it.itemId) {
                    R.id.menu_home -> {
                        supportFragmentManager
                            .beginTransaction()
                            .replace(binding.containerFragment.id, HomeFragment())
                            .commitAllowingStateLoss()
                    }
                    R.id.menu_setting -> {
                        supportFragmentManager
                            .beginTransaction()
                            .replace(binding.containerFragment.id, SettingFragment())
                            .commitAllowingStateLoss()
                    }
                    R.id.menu_alarm -> {
                        supportFragmentManager
                            .beginTransaction()
                            .replace(binding.containerFragment.id, AlarmFragment())
                            .commitAllowingStateLoss()
                    }
                    R.id.menu_mypage -> {
                        supportFragmentManager
                            .beginTransaction()
                            .replace(binding.containerFragment.id, MypageFragment())
                            .commitAllowingStateLoss()
                    }
                }
                true
            }
            selectedItemId = R.id.menu_home // 초기에 설정한 것을 navBottom 에 알려주기 위해
        }
    }
}

 

Fragment가 들어갈 FrameLayout를 배치하고, menu가 들어갈 BottomNavigationView를 배치해준다. 

BottomNavigationView에는 menu를 연결해주는 것을 잊으면 안 된다!

activity_main.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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <FrameLayout
        android:id="@+id/container_fragment"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toTopOf="@id/nav_bottom"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/nav_bottom"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/container_fragment"
        app:menu="@menu/menu_bottomnav" />

</androidx.constraintlayout.widget.ConstraintLayout>

 

 


2. 1번 과제에서 만들었던 Fragment중 하나에 TabLayout과 ViewPager2를 사용하여 슬라이드로 Fragment 바꾸는 화면 구현해보기

    - Tab 3개 이상 구현하기
    - 각 Tab마다 다른 Fragment 띄우기

 

일단, ViewPager2를 사용하기 위해선 gradle 파일을 수정해줘야 한다. 아래 코드를 작성하고 Sync Now를 해준다!

build.gradle

 

Home Fragment에 TabLayout과 ViewPager2를 배치해준다.

fragment_home.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">

    <com.google.android.material.tabs.TabLayout
        android:id="@+id/tab_home"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toTopOf="@id/vp_home"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <androidx.viewpager2.widget.ViewPager2
        android:id="@+id/vp_home"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/tab_home" />

</androidx.constraintlayout.widget.ConstraintLayout>

 

다음으로, Adapter를 만들어준다. 

HomeVPAdapter.kt

package com.example.homework6_1

import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.fragment.app.FragmentManager
import androidx.lifecycle.Lifecycle
import androidx.viewpager2.adapter.FragmentStateAdapter

class HomeVPAdapter(fragment: Fragment): FragmentStateAdapter(fragment) {
    // 총 아이템의 개수
    override fun getItemCount(): Int = 3
    // position 에 따라서 어떤 fragment 를 보여줄지 설정
    override fun createFragment(position: Int): Fragment {
        return when(position) {
            0 -> OneFragment()
            1 -> TwoFragment()
            2 -> ThreeFragment()
            else -> OneFragment()
        }
    }
}

 

HomeFragment에 Adapter를 연결해준다.

HomeFragment.kt

package com.example.homework6_1

import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.fragment.app.Fragment
import androidx.viewpager2.widget.ViewPager2
import com.example.homework6_1.databinding.FragmentHomeBinding
import com.google.android.material.tabs.TabLayoutMediator

class HomeFragment: Fragment() {

    private lateinit var binding: FragmentHomeBinding
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        binding = FragmentHomeBinding.inflate(layoutInflater)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        // fragment view 생성이 된 후 viewPager2 setting
        val homeVPAdapter = HomeVPAdapter(this)
        binding.vpHome.adapter = homeVPAdapter

        val tabTitleArray = arrayOf(
            "One",
            "Two",
            "Three",
        )

        // TabLayout 연동
        TabLayoutMediator(binding.tabHome, binding.vpHome) { tab, position ->
            tab.text = tabTitleArray[position]
        }.attach() // 연결 최종
    }

}

 

📝 Fragment에 adapter 연결하는 법

원래는 Activity에 연결했지만, 처음으로 fragment에 연결하게 돼서 많이 헤맸었다.

처음에는 onCreateView에 바로 adapter를 연결해줬는데 view가 생성되기 전이라 그런지 화면에 아무것도 뜨지 않았었다. 그래서 Fragment의 생명주기에 대해 찾아봤는데, onCreateView로 view가 생성된 이후에 onViewCreated에서 viewPager2를 adapter로 셋팅해야되는 것을 알게 됐다!

 

[Android] 의외로 잘 모르는 Fragment 의 Lifecycle

많은 앱들이 여러가지 이유로 single activity application 을 지향하고 있습니다. 따라서 Fragment 로 UI 를 구성하는 경우가 굉장히 많은데요. 이때 많은 개발자들이 Activity 의 Lifecycle 에 대해서는 잘 알고

readystory.tistory.com

 

ViewPager

swipe 뷰를 사용하면 손가락의 가로 동작이나 스와이프로 탭과 같은 동위 화면 간을 탐색할 수 있습니다. 이러한 탐색 패턴을 가로 페이징이라고도 합니다. 구성요소 1. Viewpager - 각각의 페이지(Pag

hik-coding.tistory.com

📌 프로젝트 파일 구성

저작자표시 (새창열림)

'🍞 대외활동 & 부트캠프 > IT연합동아리 UMC' 카테고리의 다른 글

[UMC] Android 8주차 워크북 (Database)  (0) 2022.11.21
[UMC] Android 7주차 워크북 (Thread)  (0) 2022.11.17
[UMC] Android 5주차 워크북 (RecyclerView) - 메모장 앱  (0) 2022.10.24
[UMC] Android 5주차 워크북 (ListView)  (0) 2022.10.23
[UMC] Android 4주차 워크북 (LifeCycle)  (0) 2022.10.18
'🍞 대외활동 & 부트캠프/IT연합동아리 UMC' 카테고리의 다른 글
  • [UMC] Android 8주차 워크북 (Database)
  • [UMC] Android 7주차 워크북 (Thread)
  • [UMC] Android 5주차 워크북 (RecyclerView) - 메모장 앱
  • [UMC] Android 5주차 워크북 (ListView)
박빵이
박빵이
2025년에도 갓생살기
  • 박빵이
    기억보다 기록
    박빵이
  • 전체
    오늘
    어제
    • 분류 전체보기 (337)
      • 🍞 FrontEnd (97)
        • HTML+CSS (4)
        • JavaScript (17)
        • TypeScript (4)
        • React (52)
        • Next.js (2)
        • Android (15)
      • 🍞 BackEnd (24)
        • Java (15)
        • Node.js (6)
        • Spring (1)
      • 🍞 Cloud & Infra (0)
        • AWS SAA (0)
        • Microsoft Azure (0)
      • 🍞 Algorithm (147)
        • C++ (4)
        • Baekjoon (41)
        • Programmers (97)
      • 🍞 Computer Science (18)
        • 운영체제 (1)
        • 데이터 통신 (6)
        • 네트워크 (6)
        • 데이터베이스 (1)
      • 🍞 대외활동 & 부트캠프 (42)
        • 삼성 청년 SW 아카데미 (1)
        • LG유플러스 유레카 (0)
        • 한국대학생IT경영학회 (1)
        • IT연합동아리 UMC (17)
        • 길벗 블로깅 멘토 (18)
        • IT연합동아리 피로그래밍 (3)
        • 개발 컨퍼런스 (2)
  • 블로그 메뉴

    • Admin
  • 링크

    • GitHub
  • 인기 글

  • 태그

    안드로이드
    level2
    level1
    알고리즘
    react
    백준
    Java
    map
    유니온파인드
    코딩자율학습
    Front
    프로그래머스
    umc
    길벗 블로깅 멘토링
    위상정렬
    길벗 블로깅 멘토
    코틀린
    C++
    JavaScript
    Android
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
박빵이
[UMC] Android 6주차 워크북 (고급 Layout과 View)
상단으로

티스토리툴바