[UMC 5기] Android 워크북 3주차

2023. 9. 29. 08:02·대외활동/UMC 동아리

BottomNavigationView란

BottomNavigationView란 무엇이고 어떤 기능

뜻 : 

  • 화면 맨 위나 맨 밑에 있는 네비게이션 역할을 하는 버튼 모음
  • fragment를 활용해서 각각 다른 화면들을 보여줄 때 사용
  • 각각의 버튼을 눌렀을 때 레이아웃에 fragment를 붙일 수 있음
  • 안드로이드 support Library 25 이상부터 지원

기능 : 

  • 각 탭 선택 시 fragment를 전환함

 

BottomNavigationView가 사용된 예시

1. 카카오톡

 

2. FLO

 


BottomNavigationView의 구성 요소

BottomNavigationView를 사용하려면 레이아웃에 추가를 해야함. 이때 어떤 값들이 필수적으로 지정?

기본 레이아웃 : 

<com.google.android.material.bottomnavigation.BottomNavigationView
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schema.android.com/apk/res/res-auto"
     android:id="@+id/navigation"
     android:layout_width="match_parent"
     android:layout_height="56dp"
     android:layout_gravity="start"
     app:menu="@menu/my_navigation_items" />

 

기타 참고사항 : 

  • 빈틈 없이 뷰에 딱 맞게 들어가도록 0으로 설정
android:layout_marginEnd="0dp"
android:layout_marginStart="0dp"

 

  • 아래 부분으로 위치
android:layout_gravity="bottom"
  • 배경색 지정
android:background="@color/background"
  • 참조할 메뉴의 경로
app:menu="@menu/menu_bottom"

 

 

Menu 리소스 XML

<menu> 태그는 무엇

  • 필수사항
  • 메뉴 항목의 컨테이너인 Menu를 정의
  • <menu> 요소는 루트 노드여야 하고 하나 이상의 <item>과 <group> 요소를 보유할 수 있음

 

<item> 태그는 무엇

  • 메뉴 내 단일 항목을 나타내는 MenuItem을 생성
  • 이 요소는 하위 메뉴를 생성하기 위한 중첩 <menu> 요소를 포함할 수 있음
  • <group> : 
    • <item> 요소를 위한 투명 컨테이너 (선택사항)
    • 이 컨테이너를 사용하면 메뉴 항목을 분류하여 활성 상태와 가시성 등의 속성을 공유할 수 있음

<item>태그에 설정할 수 있는 항목 무엇

android:id
  • 항목에 고유한 리소스 ID
  • 새 리소스 ID를 만들려면 "@+id/name" 양식을 사용
  • 사용자가 항목을 선택하면 애플리케이션이 이 ID를 통해 해당 항목을 인식

android:icon
  • 항목의 아이콘으로 사용할 수 있는 드로어블에 관한 참조

android:title
  • 항목의 제목으로 사용할 문자열에 관한 참조

android:showAsAction
  • 항목이 앱 바에서 작업 항목으로 표시되어야 하는 시기와 방법을 지정

android:titleCondensed
  • 문자열 리소스
  • 문자열 리소스 또는 원시 문자열로 요약된 제목
  • 이 제목은 일반 제목이 너무 긴 경우에 사용

android:onClick
  • 메서드 이름
  • 이 메뉴 항목을 클릭하면 호출할 메서드
  • 이 메서드는 활동에서 공개로 선언해야 함
  • MenuItem이 유일한 매개변수로 허용되며, 이는 클릭한 항목을 나타남
  • 이 메서드는 onOptionsItemSelected() 표준 콜백보다 우선
  • API 수준 11에 도입

android:actionLayout
  • 레이아웃 리소스
  • 작업 뷰로 사용할 레이아웃
  • API 수준 11에 도입

 

화면구성

1. 왼쪽의 예시 화면에서 (A)와 (B)에 해당하는 각각의 알맞은 화면 구성 요소를 선택

  • (A) = Activity / Fragment
  • (B) = Activity / Fragment

2. 왼쪽 화면을 구성하기 위해서 일반적으로 몇 개의 Fragment가 필요한가

  • 정답 )   3   개

 


BottomNavigationView 설정하기

각 Item을 클릭했을 때 나타나는 이벤트 설정하기

1. 원하는 activity 레이아웃 xml에 BottomNavigationView 추가

<com.google.android.material.bottomnavigation.BottomNavigationView
     android:id="@+id/main_bnv"
     android:layout_width="match_parent"
     android:layout_height="56dp"
     android:layout_gravity="start"
     app:menu="@menu/bottom_nav_menu" />

2. res - menu 폴더에 원하는 menu xml 생성

 <menu xmlns:android="http://schemas.android.com/apk/res/android">
 
     <item android:id="@+id/action_search"
          android:title="@string/menu_search"
          android:icon="@drawable/ic_search" />
          
     <item android:id="@+id/action_settings"
          android:title="@string/menu_settings"
          android:icon="@drawable/ic_add" />
          
     <item android:id="@+id/action_navigation"
          android:title="@string/menu_navigation"
          android:icon="@drawable/ic_action_navigation_menu" />
          
 </menu>

3. 각 메뉴에 해당되는 Fragment 생성

class SearchFragment : Fragment() {

    lateinit var binding: FragmentSearchBinding

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        binding = FragmentSearchBinding.inflate(inflater, container, false)

        return binding.root
    }
}

4. MainActivity.kt와 Fragment 연결 추가

supportFragmentManager.beginTransaction()
            .replace(R.id.main_frm, HomeFragment())
            .commitAllowingStateLoss()

        binding.mainBnv.setOnItemSelectedListener{ item ->
            when (item.itemId) {

                R.id.action_search -> {
                    supportFragmentManager.beginTransaction()
                        .replace(R.id.main_frm, SearchFragment())
                        .commitAllowingStateLoss()
                    return@setOnItemSelectedListener true
                }
                R.id.action_settings -> {
                    supportFragmentManager.beginTransaction()
                        .replace(R.id.main_frm, SettingFragment())
                        .commitAllowingStateLoss()
                    return@setOnItemSelectedListener true
                }
                R.id.action_navigation -> {
                    supportFragmentManager.beginTransaction()
                        .replace(R.id.main_frm, NavigationFragment())
                        .commitAllowingStateLoss()
                    return@setOnItemSelectedListener true
                }
            }
            false
        }

 

BottomNavigationView의 주요 속성들을 정리

각 Item을 클릭했을 때 나타나는 이벤트 설정 방법 꼭 정리

		// transaction 호출하기 위한 코드
        supportFragmentManager.beginTransaction()
            .replace(R.id.main_frm, HomeFragment())
            .commitAllowingStateLoss()

		아이템 골랐을 때
        binding.mainBnv.setOnItemSelectedListener{ item ->
            when (item.itemId) {

				// 검색 아이콘일때
                R.id.action_search -> {		
                    supportFragmentManager.beginTransaction()
                        .replace(R.id.main_frm, SearchFragment())	// SearchFragment로 대체
                        .commitAllowingStateLoss()	// 적용
                    return@setOnItemSelectedListener true
                }
                // 설정 아이콘일때
                R.id.action_settings -> {
                    supportFragmentManager.beginTransaction()
                        .replace(R.id.main_frm, SettingFragment())	// settingFragment로 대체
                        .commitAllowingStateLoss()	// 적용
                    return@setOnItemSelectedListener true
                }
            }
            false
        }

TabLayout

TabLayout이란 무엇이고 어떤 기능?

뜻 : 

  •  각각의 탭 메뉴
  • 탭을 이용하여 겹쳐진 자식 중에서 하나를 선택하는 레이아웃

 

기능 : 

  • 상위에 탭 메뉴를 구현
  • 탭을 표시할 수 있는 수평 레이아웃을 제공
  • 화면 전환을 위해 ViewPager와 함께 사용

 

TabLayout이 사용된 예시

1. FLO

2. 구글 플레이 스토어

 

TabLayout에서 사용할 수 있는 속성들은 무엇

app:tabTextColor="색상"
  • 기본 텍스트 색상 

 

app:tabSelectedTextColor="색상"
  • 선택된 텍스트 색상 

 

android:layout_height="높이dp"
  • 탭 전체 높이

 

app:tabGravity="fill"
  • 탭 전체 너비

 

android:background="색상"
  • 탭 배경 색상

 

app:tabIndicatorColor="색상"
  • 밑줄 색상

 

app:tabIndicatorHeight="높이dp"
  • 밑줄 두께

 

app:tabIndicatorGravity="top | center | bottom | stretch"
  • 밑줄 위치

 

android:icon="@drawable/아이콘이름"
  • 아이콘 설정

 


ViewPager2

ViewPager란 무엇이고 어떤 기능

뜻 : 

  •  화면에 표시될 컨텐츠를 전환하는 방법
  • 데이터를 페이지 단위로 표시하고, 좌/우 뒤집기(flip)을 통해 페이지를 전환할 수 있도록 만들어주는 컨테이너

기능 : 

  • 여러 종류의 뷰(View) 위젯을 사용하여 각 뷰페이저의 페이지를 구성
  • 데이터를 "페이지 단위"로 화면에 표시

 

ViewPager가 사용된 예시에는 무엇

1. 쿠팡

2. 버커킹

 

 

ViewPager와 ViewPager2의 차이는 무엇

  • ViewPager2는  ViewPager 라이브러리 개선된 버전
  • ViewPager2는  ViewPager 사용시 발생하는 일반적인 문제를 해결
  • ViewPager2는 적극적인 개발 지원을 받음
  • ViewPager2는 가로페이징 뿐만 아니라 세로페이징도 제공함
  • ViewPager2는 오른쪽에서 왼쪽 (RTL) 페이징을 제공함
  • ViewPager2는  수정 가능한 Fragment 컬렉션을 통해 페이징을 지원
  • ViewPager2는 기본 컬렉션이 변경되면 notifyDatasetChanged()를 호출하여 UI 업데이트함
  • ViewPager2는 앱을 런타임 시 fragment 컬렉션으로 동적으로 수정할 수 있음
  • ViewPager2는 RecyclerView를 기반으로 빌드되므로 DiffUtil 클래스에 엑세스하여 데이터세트 변경, 애니메이션 등을 활용할 수 있음

 

VIewPager2에서 사용할 수 있는 속성들은 무엇

android:id="@+id/viewPager1"
  • id 설정

 

android:layout_width="match_parent"
  • 넓이 설정

 

android:layout_height="0dp"
  • 높이 설정

 

android:orientation="horizontal"
  • 방향 설정

 

android:layoutDirection="rtl"
  • 오른쪽에서 왼쪽으로 가기 설정

 

android:layout_weight="0.5"
  • 무게 설정

ViewPager2 설정하기

ViewPager2를 이용하기 위해 어떤 라이브러리를 사용

XML에 들어가야 하는 속성도 작성

1. build.gradle 파일에 종속 항목 추가

  • Groovy
dependencies {
    implementation "androidx.viewpager2:viewpager2:1.0.0"
}
  • Kotlin
dependencies {
    implementation("androidx.viewpager2:viewpager2:1.0.0")
}

2. 사용할 레이아웃 xml에 Viewpager2 추가

        <androidx.viewpager2.widget.ViewPager2
            android:id="@+id/home_banner_vp"
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:layout_marginTop="15dp"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"/>

3. Viewpager2로 보여주고 싶은 내부용 xml 파일 생성

// fragment_banner.xml로 만듦

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

    <ImageView
        android:id="@+id/banner_image_iv"
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:scaleType="fitXY"
        android:src="@drawable/img_viewpager_exp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>

4. Adapter 파일 생성

class BannerVPAdapter(fragment: Fragment) : FragmentStateAdapter(fragment) {

    private val fragmentlist : ArrayList<Fragment> = ArrayList()

	//사용할 Fragment 개수
	override fun getItemCount(): Int = fragmentlist.size	

	//Fragment 생성
    override fun createFragment(position: Int): Fragment = fragmentlist[position]

	// Fragment 추가
    fun addFragment(fragment: Fragment){
        fragmentlist.add(fragment)
        notifyItemInserted(fragmentlist.size-1)
    }
}

5. ViewPager2로 보일 Fragment 생성

class BannerFragment(val imgRes : Int) : Fragment() {

	// 보이고픈 레이아웃 뷰바인딩
    lateinit var binding: FragmentBannerBinding

	// 뷰 만들기
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        binding = FragmentBannerBinding.inflate(inflater, container, false)

		// 이미지 넣음
        binding.bannerImageIv.setImageResource(imgRes)
        return binding.root
    }

}

6. ViewPager2를 가진 메인 Fragment에 추가

class MainFragment : Fragment() {

    lateinit var binding: FragmentMainBinding

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        binding = FragmentMainBinding.inflate(inflater, container, false)

        binding.mainViewPagerBtn.setOnClickListener {
            (context as MainActivity).supportFragmentManager.beginTransaction()
                .replace(R.id.main_frm, TempFragment())
                .commitAllowingStateLoss()
        }

        val bannerAdapter = BannerVPAdapter(this)
        bannerAdapter.addFragment(BannerFragment(R.drawable.img_viewpager_exp))
        bannerAdapter.addFragment(BannerFragment(R.drawable.img_viewpager_exp2))
        
        binding.mainBannerVp.adapter = bannerAdapter
        binding.mainBannerVp.orientation = ViewPager2.ORIENTATION_HORIZONTAL

        return binding.root
    }
}

 

ViewPager2에서 FragmentStateAdapter는 무엇이고 어떤 기능?

  • ViewPager2가 제공하는 어댑터 클래스
  • 각 페이지를 프래그먼트로 구성하고 싶을 때 사용

getItemCount()

  • FragmentStateAdapter는 RecyclerView.Adapter를 상속함
  • RecyclerView.Adapter의 abstarct 함수는 하위 클래스에서 반드시 오버라이딩
  • FragmentStateAdapter에서 getItemCount()를 오버라이딩하지 않고 있음
  • FragmentStateAdapter 클래스를 상속하는 하위 클래스에서 오버라이딩 해줘야 함
  • ViewPager2에서의 getItemCount()는 페이지 개수를 반환

createFragment()

  • 파아미터 : position의 값
  • 반환값 : Fragment 인스턴스
  • position 별로 서로 다른 프래그먼트를 보여주기 위해 서로 다른 프래그먼트를 생성해서 반환
  • 모든 position에 똑같은 프래그먼트를 보여줘야 하면 계속 같은 프래그먼트를 생성해서 반환하면 됨

ViewPager2 Indicator 설정하기

Indicator란 무엇이고 어떤 역할

  • 하단 점
  • viewPager 밑에 점처럼 생겨서 현재 몇번째 이미지를 보여주고 있는지 알려줌

 

ViewPager2에서 Indicator를 설정하려면 어떻게 해야하나

1. build.gradle에 설정 추가

dependencies {
    implementation 'me.relex:circleindicator:2.1.6'
}

2. 원하는 레이아웃 xml의 viewPager 아래에 추가

<me.relex.circleindicator.CircleIndicator3
            android:layout_width="match_parent"
            android:layout_height="48dp"
            app:ci_drawable="@color/purple"
            app:ci_drawable_unselected="@color/gray"/>

3. ViewPager2 가진 메인 Fragment에 코드 추가

val indicator = binding.PannelIndicator
indicator.setViewPager(binding.PannelViewpager2)

 

 

 

 

 

 

참고 사이트 : 

https://velog.io/@abc9985/AndroidBottomNavigationView-%EB%A7%8C%EB%93%A4%EC%96%B4%EB%B3%B4%EA%B8%B0

https://velog.io/@renovatio_hyuns/Activity%EC%99%80-Fragment%EA%B0%84%EC%9D%98-%ED%99%94%EB%A9%B4%EC%A0%84%ED%99%98

https://developer.android.com/reference/com/google/android/material/bottomnavigation/BottomNavigationView#onMeasure(int,%20int) 

https://lktprogrammer.tistory.com/183

https://snakehips.tistory.com/104

https://everyshare.tistory.com/21

https://doitddo.tistory.com/88

https://angangmoddi.tistory.com/323

https://onlyfor-me-blog.tistory.com/425

https://colinch4.github.io/2020-11-25/BottomNavigationView/

https://velog.io/@abc9985/AndroidBottomNavigationView-%EB%A7%8C%EB%93%A4%EC%96%B4%EB%B3%B4%EA%B8%B0

https://onedaythreecoding.tistory.com/entry/Android-%EB%8B%A4%EB%A5%B8-%EC%95%A1%ED%8B%B0%EB%B9%84%ED%8B%B0-%EC%8B%A4%ED%96%89-%ED%9B%84-%EA%B2%B0%EA%B3%BC-%EB%B0%9B%EC%95%84%EC%98%A4%EA%B8%B0-startActivityForResult-setRestult-%EA%B5%AC-onActivityResult

https://curryyou.tistory.com/432

https://code-hyoon.tistory.com/11

https://parkjh7764.tistory.com/149

https://helloit.tistory.com/309

https://korean-otter.tistory.com/84

https://ppeper.github.io/android/android-viewpager2/

https://velog.io/@changhee09/%EC%95%88%EB%93%9C%EB%A1%9C%EC%9D%B4%EB%93%9C-ViewPager2

https://jgeun97.tistory.com/216

https://recipes4dev.tistory.com/148

https://onedaycodeing.tistory.com/211

https://yuar.tistory.com/entry/%EC%9D%B4%EB%AF%B8%EC%A7%80-%EC%8A%AC%EB%9D%BC%EC%9D%B4%EB%8D%94-%EC%9D%B8%EB%94%94%EC%BC%80%EC%9D%B4%ED%84%B0-ViewPager2-TabLayout

https://todaycode.tistory.com/27

https://heechokim.tistory.com/23

 

'대외활동 > UMC 동아리' 카테고리의 다른 글

[UMC 5기] Android 스터디 4주차  (0) 2023.10.05
[UMC 5기] Android 스터디 3주차  (0) 2023.09.29
[UMC 5기] Android 워크북 2주차  (1) 2023.09.29
[UMC 5기] Android 스터디 2주차  (0) 2023.09.24
[UMC 5기] Android 워크북 1주차  (0) 2023.09.22
'대외활동/UMC 동아리' 카테고리의 다른 글
  • [UMC 5기] Android 스터디 4주차
  • [UMC 5기] Android 스터디 3주차
  • [UMC 5기] Android 워크북 2주차
  • [UMC 5기] Android 스터디 2주차
월월
월월
  • 월월
    서벅돌의 성장일기
    월월
  • 전체
    오늘
    어제
    • 분류 전체보기 (121)
      • TIL (2)
      • Server (29)
        • spring (8)
        • node.js (16)
        • 기타 (5)
      • App&Web (17)
        • Web (1)
        • Android (16)
        • iOS (0)
      • 공부 (59)
        • 깃&깃허브 (3)
        • 파이썬 (17)
        • 유니티 (4)
        • 자료구조 | 알고리즘 (15)
        • 자바 (3)
        • 운영체제 (8)
        • AI와 데이터 (9)
      • 대외활동 (12)
        • NPC 동아리 (1)
        • UMC 동아리 (11)
      • 대학교 (1)
        • 교직 (1)
      • 기타 (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
    • 글 관리
  • 링크

  • 공지사항

    • Notice
  • 인기 글

  • 태그

    C
    자바
    루아
    Python
    mysql
    kotlin
    안드로이드
    Lua
    Unity
    Android
    파이썬
    java
    유니티
    코틀린
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
월월
[UMC 5기] Android 워크북 3주차
상단으로

티스토리툴바