Computer >> 컴퓨터 >  >> 프로그래밍 >> Android

Kotlin으로 안드로이드 앱 탭 레이아웃(TabLayout) 구현하는 방법

이 튜토리얼에서는 Kotlin을 사용하여 안드로이드 앱에서 탭 레이아웃(TabLayout)을 구현하는 방법을 단계별로 살펴봅니다. TabLayout과 ViewPager를 연동하면 스와이프로 화면을 전환할 수 있는 직관적인 탭 UI를 손쉽게 만들 수 있습니다.

구현 순서 한눈에 보기

전체 과정은 다음 6단계로 진행됩니다.

  • 새 프로젝트 생성
  • 메인 레이아웃(activity_main.xml) 작성
  • MainActivity.kt에서 TabLayout과 ViewPager 연결
  • 어댑터(MyAdapter.kt) 클래스 작성
  • 탭별 프래그먼트 3개 생성
  • AndroidManifest.xml 확인 후 앱 실행

1단계 — 새 프로젝트 만들기

Android Studio에서 File → New Project를 선택하고, 빈 프로젝트(Empty Activity) 템플릿으로 새 프로젝트를 생성합니다. 언어는 Kotlin으로 지정하세요.

2단계 — 메인 레이아웃 작성

res/layout/activity_main.xml 파일에 아래 코드를 추가합니다. 상단에는 TabLayout, 하단에는 ViewPager를 배치합니다.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

<com.google.android.material.tabs.TabLayout
    android:id="@+id/tabLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="#1db995">
</com.google.android.material.tabs.TabLayout>

<androidx.viewpager.widget.ViewPager
    android:id="@+id/viewPager"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@id/tabLayout"
    android:layout_centerInParent="true"
    android:layout_marginTop="100dp"
    tools:layout_editor_absoluteX="8dp" />

</RelativeLayout>

3단계 — MainActivity.kt 작성

src/MainActivity.kt 파일에 아래 코드를 추가합니다. 여기서는 탭 3개(Football, Cricket, NBA)를 동적으로 추가하고, 탭 선택 이벤트와 ViewPager 페이지 변경 이벤트를 서로 연동합니다.

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.viewpager.widget.ViewPager
import com.google.android.material.tabs.TabLayout
import com.google.android.material.tabs.TabLayout.OnTabSelectedListener
import com.google.android.material.tabs.TabLayout.TabLayoutOnPageChangeListener

class MainActivity : AppCompatActivity() {
    lateinit var tabLayout: TabLayout
    lateinit var viewPager: ViewPager

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

        tabLayout = findViewById(R.id.tabLayout)
        viewPager = findViewById(R.id.viewPager)

        tabLayout.addTab(tabLayout.newTab().setText("Football"))
        tabLayout.addTab(tabLayout.newTab().setText("Cricket"))
        tabLayout.addTab(tabLayout.newTab().setText("NBA"))
        tabLayout.tabGravity = TabLayout.GRAVITY_FILL

        val adapter = MyAdapter(this, supportFragmentManager,
            tabLayout.tabCount)
        viewPager.adapter = adapter

        viewPager.addOnPageChangeListener(TabLayoutOnPageChangeListener(tabLayout))

        tabLayout.addOnTabSelectedListener(object : OnTabSelectedListener {
            override fun onTabSelected(tab: TabLayout.Tab) {
                viewPager.currentItem = tab.position
            }
            override fun onTabUnselected(tab: TabLayout.Tab) {}
            override fun onTabReselected(tab: TabLayout.Tab) {}
        })
    }
}

4단계 — 어댑터 클래스 작성

새 Kotlin 클래스 파일 MyAdapter.kt를 만들고 아래 코드를 추가합니다. 이 어댑터는 탭 위치(position)에 따라 해당 프래그먼트를 반환하는 역할을 합니다.

import android.content.Context
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentPagerAdapter

@Suppress("DEPRECATION")
internal class MyAdapter(
    var context: Context,
    fm: FragmentManager,
    var totalTabs: Int
) : FragmentPagerAdapter(fm) {

    override fun getItem(position: Int): Fragment {
        return when (position) {
            0 -> {
                Football()
            }
            1 -> {
                Cricket()
            }
            2 -> {
                NBA()
            }
            else -> getItem(position)
        }
    }

    override fun getCount(): Int {
        return totalTabs
    }
}

5단계 — 프래그먼트 3개 생성

각 탭에 표시될 프래그먼트 3개(Cricket, Football, NBA)를 생성합니다. 이름은 프로젝트 성격에 맞게 자유롭게 변경할 수 있습니다.

Cricket.kt

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment

class Cricket : Fragment() {
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // 이 프래그먼트의 레이아웃을 인플레이트합니다
        return inflater.inflate(R.layout.fragment_cricket, container, false)
    }
}

fragment_cricket.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".Cricket">

<TextView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:text="Cricket Fragment"
    android:textAlignment="center"
    android:textSize="16sp"
    android:textStyle="bold" />

</FrameLayout>

Football.kt

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment

class Football : Fragment() {
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // 이 프래그먼트의 레이아웃을 인플레이트합니다
        return inflater.inflate(R.layout.fragment_football, container, false)
    }
}

fragment_football.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".Football">

<TextView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:text="Football Fragment"
    android:textAlignment="center"
    android:textSize="16sp"
    android:textStyle="bold" />

</FrameLayout>

NBA.kt

import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup

class NBA : Fragment() {
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // 이 프래그먼트의 레이아웃을 인플레이트합니다
        return inflater.inflate(R.layout.fragment_n_b_a, container, false)
    }
}

fragment_n_b_a.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".NBA">

<TextView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:text="NBA Fragment"
    android:textAlignment="center"
    android:textSize="16sp"
    android:textStyle="bold" />

</FrameLayout>

6단계 — AndroidManifest.xml 설정

AndroidManifest.xml 파일에 아래와 같이 MainActivity가 등록되어 있는지 확인합니다.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
    package="com.example.q11">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

앱 실행 및 결과 확인

이제 애플리케이션을 실행해 보겠습니다. 실제 안드로이드 기기를 컴퓨터에 연결했다고 가정합니다. Android Studio에서 프로젝트의 액티비티 파일 중 하나를 연 뒤, 툴바의 Run(실행) 아이콘Kotlin으로 안드로이드 앱 탭 레이아웃(TabLayout) 구현하는 방법을 클릭하세요. 실행 대상 목록에서 본인의 모바일 기기를 선택하면, 기기 화면에 아래와 같은 결과가 표시됩니다.

Kotlin으로 안드로이드 앱 탭 레이아웃(TabLayout) 구현하는 방법


Kotlin으로 안드로이드 앱 탭 레이아웃(TabLayout) 구현하는 방법

Kotlin으로 안드로이드 앱 탭 레이아웃(TabLayout) 구현하는 방법


마무리 및 참고 사항

위 예제처럼 TabLayout과 ViewPager를 함께 사용하면 탭을 누르거나 화면을 좌우로 스와이프할 때 자동으로 페이지가 전환되는 UI를 쉽게 구현할 수 있습니다. 참고로 TabLayout은 머티리얼 디자인 라이브러리에 포함되어 있으므로, build.gradle(app)에 com.google.android.material:material 의존성이 추가되어 있는지 반드시 확인하세요. 또한 최신 프로젝트에서는 FragmentPagerAdapter 대신 FragmentStateAdapter(ViewPager2용) 사용을 권장하며, 이 경우 마이그레이션 가이드를 참고하면 좋습니다.