1. Viewpager2
- ViewPager 라이브러리의 개선된 버전으로, 세로 페이징 (android:orientation="vertical")과 오른쪽에서 왼쪽 페이징 (android:layoutDirection="rtl")을 지원한다.
- 화면 슬라이드: 하나의 전체 화면에서 다른 전체 화면으로 전환하는 것
- Viewpager2 객체를 활용하여 스와이프로 화면 전환을 구현할 수 있다.
Viewpager2를 쓰기 위해서 build.gradle.kts (Module :app)에서 플러그인을 추가해줘야 한다.
dependencies {
implementation("androidx.viewpager2:viewpager2:1.0.0")
}
Viewpager2를 사용하기 위해 화면에 보여줄 프래그먼트 레이아웃과 클래스를 작성해주고, Viewpager2의 adpater를 만들어준다.
class MyPagerAdapter(fa: FragmentActivity) : FragmentStateAdapter(fa) {
// 외부에서 FragmentActivity를 받아와서 그걸 처리.
private val NUM_PAGES = 3
override fun getItemCount(): Int = NUM_PAGES
// 만들어줄 전체 페이지 수
override fun createFragment(position: Int): Fragment {
// 각 페이지가 어떤 프래그먼트로 만들어질지 내용 전해줌.
return when (position) {
0 -> { MyFragment.newInstance("Page 1", "")}
1 -> { MyFragment.newInstance("Page 2", "")}
else -> { MyFragment.newInstance("Page 3", "")}
}
}
}
activity_main.xml에서 메인 액티비티 화면을 구성하는데 여기서 뷰페이저를 배치해준다. 다음으로 구현할 TabLayout을 위해 viewpager 아래에 appBarLayout을 배치하고 그 안에 TabLayout을 배치해주었다.
<?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">
<androidx.viewpager2.widget.ViewPager2
android:layout_width="0dp"
android:layout_height="0dp"
android:id="@+id/viewpager"
android:orientation="horizontal"
app:layout_constraintBottom_toTopOf="@+id/appBarLayout"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<com.google.android.material.appbar.AppBarLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="@+id/appBarLayout"
android:theme="@style/Theme.AppCompat.Light.DarkActionBar"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<com.google.android.material.tabs.TabLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:id="@+id/tabs"
android:background="@color/white"
app:tabIndicatorColor="@color/design_default_color_primary"
app:tabRippleColor="@color/design_default_color_primary"
app:tabSelectedTextColor="@color/design_default_color_primary"
app:tabTextColor="@color/black"/>
</com.google.android.material.appbar.AppBarLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
MainActivity 클래스에서 뷰페이저 어뎁터를 연결시켜준다. setPageTransformer 함수를 이용하여 화면 슬라이드 애니메이션 설정을 할 수 있다. 구글에서 ZoomOutPageTransformer, DepthPageTransformer 와 같이 전환 효과를 구현할 수 있는 코드를 공개하고 있다. 이를 복사해서 클래스를 만들고 활용하면 보다 더 풍부한 화면 전환 효과를 나타낼 수 있다.
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
// 어뎁터 설정
binding.viewpager.apply {
adapter = MyPagerAdapter(context as FragmentActivity)
// MyPagerAdapter 객체 만들어서 뷰페이저 어뎁터 속성에 연결
setPageTransformer(ZoomOutPageTransformer())
// 페이지 슬라이드 효과
}
}
}
2. TabLayout
- TabLayout을 사용하면 탭을 가로로 나타낼 수 있다.
- Viewpager와 TabLayout을 함께 사용하면 스와이프 뿐만 아니라 탭 버튼을 통해서도 화면 전환이 가능하다.
- 탭으로 어떤 페이지에 있는지 직관적으로 알 수 있도록 하여 탐색의 용이성을 제공한다.
메인 액티비티 레이아웃에 TabLayout을 배치한다. 이에 대한 코드는 위의 1번 내용에 있다.
TabLayout을 사용하기 위해 MainActivity 클래스에 TabLayoutMediator를 사용한다. 메뉴 바를 나타내기 위해 res>drawable 에 아이콘을 추가하고 배열에 넣어준다.
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
// 메뉴 바 아이콘 배열
private val tabIcon = listOf(
R.drawable.ic_baseline_format_list_bulleted_24,
R.drawable.ic_baseline_map_24,
R.drawable.ic_baseline_info_24
)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.viewpager.apply {
adapter = MyPagerAdapter(context as FragmentActivity)
setPageTransformer(ZoomOutPageTransformer())
}
// 탭 레이아웃과 뷰페이저2를 연결할 때 TabLayoutMediator 씀.
TabLayoutMediator(binding.tabs, binding.viewpager) { tab, position ->
tab.text = "Title $position"
tab.setIcon(tabIcon[position]) // 포지션에 따라 서로 다른 아이콘을 가져오도록, 탭에 아이콘을 지정하기 위해 setIcon 함수 이용.
}.attach()
}
}
3. Navigation View
바텀 네비게이션을 구현하기 위해 build.gradle.kts (Module :app)에서 플러그인을 추가해준다.
dependencies {
// 메테리얼 디자인
implementation("com.google.android.material:material:1.10.0")
}
메인 액티비티 레이아웃에 바텀 네비게이션을 배치해준다. 그리고 activity_main.xml과 같은 위치인 res>layout에 프래그먼트 레이아웃을 원하는 개수만큼 만든다.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
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"
android:background="#D8D8D8">
<FrameLayout
android:id="@+id/fragments_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/bottom_nav"
android:layout_centerHorizontal="true"
android:background="@color/design_default_color_primary"/>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_nav"
app:menu="@menu/bottom_nav_menu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:background="#fff"
app:labelVisibilityMode="unlabeled"
app:itemIconSize="40dp" />
</RelativeLayout>
다음은 프래그먼트 클래스 중 하나의 코드이다. 외부에서 접근할 때 메모리에 올린 것을 가져오기 위해 compation object 안에 fragment 인스턴스를 만들어 반환하는 코드를 넣어준다.
class HomeFragment : Fragment() {
companion object {
// Fragment 인스턴스를 만들어 반환
fun newInstance() : HomeFragment {
return HomeFragment()
}
}
// 메모리에 올라갔을 때
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
// 프래그먼트를 안고 있는 액티비티에 붙었을 때
override fun onAttach(context: Context) {
super.onAttach(context)
}
// 뷰가 생성되었을 때
// 프래그먼트와 레이아웃을 연결시켜주는 부분이다.
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.fragment_home, container, false)
return view
}
}
다음은 메인 액티비티 클래스 코드이다. 바텀 네비게이션에서 버튼이 클릭되었을 때 메인 액티비티에서 반응을 할 수 있도록 BottomNavigation.OnNavigationItemSelectedListener를 추가한다. 버튼이 클릭되었을 때 그에 해당하는 프래그먼트를 보여주기 위해 리스너 안에 supportFragmentManager를 사용하여 교체 설정을 넣는다. 초기 화면에는 홈 화면이 나타나도록 add를 사용한다.
class MainActivity : AppCompatActivity(){
private var mBinding: ActivityMainBinding? = null
private val binding get() = mBinding!!
private lateinit var homeFragment: HomeFragment
private lateinit var rankingFragment: RankingFragment
private lateinit var profileFragment: ProfileFragment
// 메모리에 올라갔을 때
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mBinding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.bottomNav.setOnNavigationItemSelectedListener(onBottomNavItemSelectedListener)
// 초기 화면으로 HomeFragment를 추가하여 표시
homeFragment = HomeFragment.newInstance()
supportFragmentManager.beginTransaction().add(R.id.fragments_frame, homeFragment).commit()
}
// 바텀네비게이션 아이템 클릭 리스너 설정
private val onBottomNavItemSelectedListener = BottomNavigationView.OnNavigationItemSelectedListener {
when(it.itemId) {
R.id.menu_home -> {
homeFragment = HomeFragment.newInstance() // 프래그먼트를 가져옴.
supportFragmentManager.beginTransaction().replace(R.id.fragments_frame, homeFragment).commit()
// supportFragmentManager : 프래그먼트 관리
}
R.id.menu_ranking -> {
rankingFragment = RankingFragment.newInstance()
supportFragmentManager.beginTransaction().replace(R.id.fragments_frame, rankingFragment).commit()
}
R.id.menu_profile -> {
profileFragment = ProfileFragment.newInstance()
supportFragmentManager.beginTransaction().replace(R.id.fragments_frame, profileFragment).commit()
}
}
true
}
}
<참고>
https://developer.android.com/training/animation/screen-slide-2?hl=ko
ViewPager2로 프래그먼트 간 슬라이드 | Android 개발자 | Android Developers
ViewPager2로 프래그먼트 간 슬라이드 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 화면 슬라이드는 하나의 전체 화면에서 다른 전체 화면으로 전환하는 것
developer.android.com
https://developer.android.com/guide/navigation/navigation-swipe-view-2?hl=ko
ViewPager2를 사용하여 탭으로 스와이프 뷰 만들기 | Android 개발자 | Android Developers
ViewPager2를 사용하여 탭으로 스와이프 뷰 만들기 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 스와이프 뷰를 사용하면 손가락의 가로 동작이나 스와이프
developer.android.com
https://cliearl.github.io/posts/android/viewpager2-tablayout/
ViewPager2와 TabLayout을 이용해 스와이프 되는 화면 구현하기
이번 포스팅에서는 ViewPager2와 TabLayout을 이용해 스와이프 되는 화면을 구현해 보도록 하겠습니다. ViewPager2를 사용하는 이유나 장점에 대해서는 ViewPager1 프로젝트를 ViewPager2 프로젝트로 변환하기
cliearl.github.io
'Group Study (2023-2024) > Android 입문' 카테고리의 다른 글
[Android 입문] 5주차 스터디 - RoomDB, SharedPreferences, Datastore (0) | 2023.12.25 |
---|---|
[Android 입문] 3주차 스터디 -ListView, RecyclerView, ListView와 RecyclerView의 차이점 (1) | 2023.11.20 |
[Android 입문] 2주차 스터디 -Activity와 Fragment, ViewBinding (0) | 2023.11.13 |
[Android 입문] 1주차 스터디 -View와 Layout (0) | 2023.11.07 |