[Do it! 깡샘의 안드로이드 앱 프로그래밍 with 코틀린] 제트팩 라이브러리
안드로이드 앱 프로그래밍에서 제트팩 라이브러리, 리사이클러 뷰, 뷰 페이저2, 드로어 레이아웃의 사용법을 정리했다. 제트팩 라이브러리는 프래그먼트의 동적 제어와 생명주기를 다루며, 리사이클러 뷰는 목록 화면을 구성하는 방법을 설명한다. 뷰 페이저2는 스와이프로 화면을 전환하는 기능을 제공하며, 드로어 레이아웃은 화면의 옆에서 열리는 기능을 구현한다. 각 섹션은 코드 예제와 함께 상세한 구현 방법을 제공한다.
Aug 08, 2024
🌼제트팩과 androidx 소개
💡플랫폼 API
- 플랫폼 API는 ART에서 제공하는 안드로이드 앱의 핵심 라이브러리다.
java.lang.String, java.util.Date, android.app.Activity, android.widget.TextView
등의 클래스가 모두 플랫폼 API다.
💡제트팩
- 제트팩이란 구글에서 제공하는 안드로이드 앱을 개발하는 데 필요한 다양한 라이브러리 모음이다.
- 제트팩은 다음 3가지 목적으로 제공된다.
- 앱을 개발하는데 필요한 권장 아키텍쳐를 제공
- API 레벨의 호환성 문제를 해결
- 플랫폼 API에서 제공하지 않는 다양한 기능 제공
💡androidx 라이브러리
- 제트팩에는
androidx
라는 패키지명으로 시작하는 다양한 라이브러리가 있다.
- 화면 구성과 관련된 라이브러리는 다음과 같다.
androidx.appcompat
: 앱의 API 레벨 호환성을 해결androidx.recyclerview
: 목록 화면을 구성androidx.viewPager2
: 스와이프로 넘기는 화면을 구성androidx.drawerlayout
: 옆에서 서랍처럼 열리는 화면을 구성
🌼appcompat 라이브러리 - API 호환성 해결
💡appcompat 선언 및 사용
appcompat
라이브러리를 사용하려면 그래들 파일의dependencies
항목에 선언을 해야 한다.
// appcompat 라이브러리 선언
implementation(libs.androidx.appcompat)
appcompat
라이브러리를 이용해서 액티비티를 만들 때는 플랫폼 API의Activity
가 아니라 다음처럼appcompat
의AppCompatActivity
클래스를 상속받아 사용한다.
// appcompat 라이브러리 사용
import androidx.appcompat.app.AppCompatActivity
(...생략...)
class MainActivity: AppCompatActivity(){
}
화면을 포함하는 앱을 개발할 때는
appcompat
라이브러리를 이용하는 것이 바람직하다. 안드로이드 버전이 올라가면서 액티비티으 기능이 추가되거나 변경되어서 대부분 호환성 문제가 발생하기 때문이다.💡툴바
- 툴바는 화면 위쪽에 타이틀 문자열이 출력되는 영역을 꾸미기 위한 뷰다.
- 타이틀 문자열이 나오는 부분을 구성하는 방법은 액션바를 이용하는 방법과 툴바를 이용하는 방법이 있다.
- 툴바를 이용할 것인지, 액션바를 이용할 것인지에 대한 부분은 액티비티에 적용되는 테마 설정에 의해 결정된다.
- 앱 혹은 액티비티에 적용되는 테마는 XML로 설정하는데, 직접 작성하지 않아도 res/values 폴더에 기본 테마가 선언된다.
// themes.xml로 테마 스타일 선언
<resources xmlns:tools="http://schemas.android.com/tools:>
<!--기본 테마 -->
<style name="Base.Theme.Android:ab" parent="Theme.Material3.DayNight.NoActionBar">
<!--여기에 light 테마를 지정 -->
<!-- <item name="colorPrimary">@color/my_light_primary</item> -->
</style>
<style name="Theme.AndroidLab" parent="Base.Theme.AndroidLab" />
</resources>
// AndroidManifest.xml에서 적용 내용 확인
<application
(...생략...)
android:theme="@style/Theme.AndroidLab">
(...생략...)
</application>
androidx.appcompat.widtet.Toolbar
클래스를 선언해 주어야 한다.setSupportactionBar(binding.toolbar)
를 사용한다.툴바를 사용하는 것과 액션바를 사용했을 때의 결과는 같지만, 툴바는 개발자가 직접 제어할 수 있어서 액션바보다 다양한 기능을 제공할 수 있다.
- 툴바의 색상을 지정하려면
themes.xml
파일의<resources>
안의<style>
안의<item>
태그에 다음과 같은 옵션을 사용한다. colorPrimay
: 툴바와 버튼의 배경색statusBarColor
: 상태바의 배경색colorAccent
: 스위치가 켬 상황일떄와 같은 활성 모드 상태
- 업 버튼은 액티비티 화면이 앱의 첫 화면이 아닐 때 이전 화면으로 되돌아가는 기능이다.
// 매니페스트 파일에서 업 버튼 설정
<activity
android:name=".test1.TwoActivity"
android:exported="false"
android:parentActivityName=".MainActivity"/>
// 또는 액티비티 코드로 등록
supportActionBar?.setDisplayHomeAsUpEnabled(true)
onSupportNavigateUp()
함수를 재정의한다.// 업 버튼 클릭 시 자동으로 호출되는 함수 재정의
override fun onSupportNavigateUp(): Boolean{
Log.d("kkang","onSupportNavigateUp"
return super.onSupportNavigateUp()
}
💡메뉴 구성
- 메뉴를 통해 액티비티 화면에서 사용자 이벤트를 사용할 수 있다. 액티비티에 메뉴를 추가하면 툴바 오른쪽에 오버플로 버튼이 나타난다.
- 오버플로 메뉴 중에서 몇몇은 툴바에 아이콘으로 나오게 할 수 있다. 이를 액션 아이콘이라고 한다.
// 메뉴 구성 함수
override fun onCreateOptionMenu(menu: Menu?): Boolean{
// 두 번째 인수는 메뉴의 식별자다.
val menuItem1: MenuItem? = menu?.add(0,0,0,"menu1")
val menuItem2: MenuItem? = menu?.add(0,1,0,"menu2")
return super.onCreateOptionsMenu(menu)
}
// 메뉴 선택 시 이벤트 처리
override fun onOptionItemSelected(item: MenuItem): Boolean when(item.itemId){
0 -> {
Log.d("kkang","menu1 click")
true
}
1 -> {
Log.d("kkang","menu2 click")
true
}
else -> super.onOptionItemSelected(item)
}
- 리소스로 메뉴를 구현할 수도 있다. 메뉴를 구성하는 XML 파일은 res 폴더 아래 menu 디렉터리에 만든다.
- 메뉴 XML의
<item>
태그 하나가 메뉴 하나에 해당한다.id
는 메뉴 식별자,title
과icon
속성은 메뉴 문자열과 아이콘을 지정한다. - 메뉴는 기본으로 오버플로 메뉴로 나오는데, 만약 툴바에 아이콘으로 나타나게 하려면
showAsAction
속성을 이용한다. never
(기본) : 항상 오버플로 메뉴로 출력ifRoom
: 툴바에 공간이 있다면 액션 아이템으로, ㅇ벗다면 오버플로 메뉴로 출력always
: 항상 액션 아이템으로 출력
// 메뉴 XML
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/menu1"
android:title="menu1" />
<item
android:id="@+id/menu2"
android:icon="@android:drawable/ic_menu_add"
android:title="menu2" />
app:showAsAction="always" />
</menu>
// 액티비티 코드에 메뉴 XML 적용
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.menu_main, menu)
return super.onCreateOptionsMenu(menu)
}
- 액션 뷰는 액션바에서 특별한 기능을 제공하며 대표적으로
androidx.appcompat.widget.SearchView
가 있다. 서치뷰는 액션바에서 검색 기능을 제공한다.
// 서치 뷰 사용
<item android:id="@+id/menu/search"
android:title="search"
app:showAsAction="always"
app:actionViewClass="androidx.appcompat.widget.SearchView"/>
// 서치 뷰 검색 기능 구현
override fun onCreateOptionsMenu(menu: Menu?): Boolean{
val inflater = menuInflater
inflater.inflate(R.menu.menu_main, menu)
val menuItem = menu?.findItem(R.id.menu_search)
val searchView = menuItem?.actionView as SearchView
searchView.setOnQueryTextListener(object: SearchView.OnQueryTextListener{
override fun onQueryTextChange(newText: String?): Boolean{
// 검색어 변경 이벤트
return true
}
override fun onQueryTextSubmit(query: String?): Boolean{
// 키보드의 검색 버튼을 클릭한 순간의 이벤트
return ture
}
})
return true
}
🌼프래그먼트 - 액티비티처럼 동작하는 뷰
💡프래그먼트 소개
- 프래그먼트는 텍스트 뷰나 버튼처럼 액티비티 화면을 구성하는 뷰다. 액티비티에 작성할 수 있는 모든 코드는 프래그먼트에도 사용할 수 있다.
- 한 화면은 하나의 액티비티 클래스에서 작성해야 하는데, 화면이 크면 액티비티 클래스에 너무 많은 코드를 작성해야 하는 문제가 있다.
- 이 때 한 화면을 각각 클래스로 분리해서 작성하고 액티비티에서는 두 클래스를 조합만 하는 식으로 구현할 수 있다.
- 이 경우 두 클래스가 액티비티 화면에 출력되어야 하므로 각각의 클래스를 뷰 클래스로 만들어야 한다.
- 문제는 뷰 클래스는 액티비티가 아니므로 액티비티에 작성된 모든 내용을 뷰 클래스에 담을 수가 없다. 이 때 프래그먼트가 필요하다.
💡프래그먼트 구현
- 먼저 프래그먼트 화면을 구성하는 레이아웃 XML 파일을 작성해야 한다. 프래그먼트는
Fragment
를 상속받아 작성하는 클래스다. 해당 클래스에 최소한으로 작성해야 하는 함수는onCreateView()
다. 이 함수가 자동 호출되며 반환한 View 객체가 화면에 출력된다.
// 프래그먼트 구현
import androidx.fragment.app.Fragment
class OneFragment : Fragment(){
lateinit var binding: FragmentOneBinding
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup, savedInstanceState: Bundle?
): View?{
binding = FragmentOneBinding.inflate(inflater, container, false)
return binding.root
}
}
// 레이아웃 XML에서 프래그먼트 출력
<fragment
android:name="com.example.test11.OneFragment"
android:id="@+id/fragmentView"
(...생략...) />
// 프래그먼트를 출력할 뷰 준비
<LinearLayout
android:id="@+id/fragment_content"
(...생략...) >
</LinearLayout>
- 코드에서 프래그먼트를 동적으로 제어(추가, 제거 등)하려면
FragmentManager
로 만든FragmentTransaction
클래스의 함수를 이용한다. add(int containerViewId, Fragment fragment)
: 새로운프래그먼트를 화면에 추가replace(int containerViewId, Fragment fragment)
: 추가된 프래그먼트를 대체remove(Fragment fragment)
: 추가된 프래그먼트를 제거commit()
: 화면에 적용
// 프래그먼트 동작 제어
val fragmentManager: FragmentManager = supportFragmentManager
val transactino: FragmentTransaction = fragmentManager.beginTransaction()
val fragment = OneFragment()
transaction.add(R.id.fragment_content, fragment)
transaction.commit()
- 프래그먼트도 액티비티와 생명주기가 같다.
- 프래그먼트의 생명주기는 크게 5단계로 나뉜다. 초기화, 생성, 시작, 재개, 소멸 단계로 구분되며, 각 단계가 진행되며 자동으로 함수가 호출된다.
- 어떤 프래그먼트가 처음 화면에 나온다면
onAttach → onCreate → onCreateView → onViewCreated → onStart → onResume
순서로 함수가 호출된다. 이후 다른 프래그먼트로 교체될 때는 백 스택을 사용하는지에 따라 생명주기가 다르게 동작한다. - 백 스택을 사용하면 프래그먼트가 제거되지 않고
onPause → onStop → onDestroyView
함수까지만 호출된다.onDestroyView
까지 호출된 프래그먼트가 다시 준비되어 화면에 출력된다면onCreateView →onViewCreated → onStart → onResume
함수가 호출된다. - 백 스택을 사용하려면
FragmentTransaction
의addToBackStack()
함수를 이용해야 한다.

🌼리사이클러 뷰 - 목록 화면 구성
💡리사이클러 뷰 기본 사용법
- 리사이클러 뷰는 카톡방 목록처럼 여러 가지 항목을 나열하는 목록 화면을 만들 때 사용한다. 구성요소는 다음과 같다.
ViewHolder
(필수) : 항목에 필요한 뷰 객체를 가진다.Adaptor
(필수) : 항목을 구성한다.LayoutManager
(필수) : 항목을 배치한다.ItemDecoration
(옵션) : 항목을 꾸민다.
- 뷰 홀더는 각 항목을 구성하는 뷰 객체(이미지 뷰, 텍스트 뷰 등)를 가진다. 그리고 어댑터는 뷰 홀더에 있는 뷰 객체에 적절한 데이터를 대입해 항목을 완성한다. 그 다음 레이아웃 매니저는 어댑터가 만든 항목들을 어떻게 배치할지 결정하여 리사이클러 뷰에 출력한다.
목록 화면은 리스트 뷰로도 만들 수 있지만, 리사이클러 뷰는 리스트 뷰로 만들기 어렵거나 불가능한 목록 화면을 쉽게 만들 수 있다. 따라서 리사이클러 뷰를 사용하는 것이 좋다.
- 먼저 리사이클러 뷰를 레이아웃 XML파일에 등록한다. 그 다음 목록에 표시할 항목을 디자인한 레이아웃 XML도 필요하다.
// 리사이클러 뷰 등록
<androidx.recyclerview.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/recyclerView"
(...생략...) />
// 목록에 표시할 항목을 디자인한 레이아웃 XML
<LinearLayout
android:id="@+id/item_root"
(...생략...)>
<TextView
android:id="@+id/item_data"
(...생략...) />
</LinearLayout>
- 각 항목에 해당하는 뷰 객체를 가지는 뷰 홀더는
RecyclerView.ViewHolder
를 상속받아서 작성한다.
// 뷰 홀더 준비
class MyViewHolder(val binding: ItemMainBinding): RecyclerView.ViewHolder(binding.root)
- 어댑터는
RecyclerView.Adaptor
를 상속받아 작성한다.
// 어댑터 준비
class MyAdaptor(val datas: MutableList<String>):
RecyclerView.Adaptor<RecyclerView.ViewHolder>(){
override fun getItemCount(): Int{
TODO("Not yet implemented")
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder{
TODO("Not yet implemented")
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int){
TODO("Not yet implemented")
}
}
- 어댑터 생성자의 매개변수는 액티비티에서 전달받는 항목 구성용 데이터다. 어댑터에서 재정의해야 하는 함수는 다음과 같다.
getItemCount()
: 항목 개수를 판단하려고 자동으로 호출된다.onCreateViewHolder()
: 항목의 뷰를 가지는 뷰 홀더를 준비하려고 자동으로 호출된다.onBindViewHolder()
: 뷰 홀더의 뷰에 데이터를 출력하려고 자동으로 호출된다.
// 항목의 개수 구하기
override fun getItemCount(): Int = datas.size
// 항목 구성에 필요한 뷰 홀더 객체 준비
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder =
MyViewHolder(ItemMainBinding.inflate(LayoutInflater.from(parent.context), parent, false))
// 뷰에 데이터 출력
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int){
Log.d("kkang", "onBindViewHolder: $position")
val binding = (holder as MyViewHolder).binding
// 뷰에 데이터 출력
binding.itemData.text = datas[position]
// 뷰에 이벤트 추가
binding.itemRoot.setOnClickListener{
Log.d("kkang","item root click: $position")
}
}
- 마지막으로 리사이클러 뷰에 어댑터와 레이아웃 매니저를 등록해 화면에 출력한다.
// 리사이클러 뷰 출력
class RecyclerViewActivity : AppCompatActivity(){
override fun onCreate(savedInstanceState: Bundle?){
super.onCreate(savedInstanceState)
val binding = ActivityRecyclerViewBinding,inflate(layoutInflater)
setContentView(binding.root)
val datas = mutableListof<String>()
for(i in 1..10){
datas.add("Item $i")
}
binding.recyclerView.layoutManager = LinearLayoutManager(this)
binding.recyclerView.adapter = MyAdapter(datas)
binding.recyclerView.addItemDecoration(DividerItemDecoration(this, LinearLayoutManager.VERTICAL))
}
}
- 리사이클러 뷰에 항목이 출력된 후 동적으로 새로운 항목을 추가하거나 화면에 보이는 항목을 제거해야 할 경우,
notifyDataSetChanged()
함수를 호출하면 된다.
// 항목 추가
datas.add("new data")
adapter.notifyDataSetChanged()
💡레이아웃 매니저
- 레이아웃 매니저는 어댑터로 만든 항목을 리사이클러 뷰에 배치한다.
RecyclerView.LayoutManager
를 상속받은 클래스로, 다음과 같은 기능을 제공한다. LinearLayoutManager
: 항목을 가로나 세로 방향으로 배치한다.GridLayoutManager
: 항목을 그리드로 배치한다.StaggeredGridLayoutManager
: 항목을 높이가 불규칙한 그리드로 배치한다.
// 항목을 세로로 배치
binding.recyclerView.layoutManager = LinearLayoutManager(this)
// 항목을 가로로 배치
val layoutManager = LinearLayoutManager(this)
layoutManager.orientation = LinearLayoutManager.HORIZONTAL
binding.recyclerView.layoutManager = layoutManager
// 항목을 그리드로 배치
val layoutManager = GridLayoutManager(this, 2)
binding.recyclerView.layoutManager = layoutManager
// 그리드에서 항목을 가로로 배치
val layoutManager = GridLayoutManager(this, 3, GridLayoutManager.HORIZONTAL, false)
binding.recyclerView.layoutManager = layoutManager
// 그리드에서 항목을 오른쪽부터 배치
val layoutManager = GridLayoutManager(this, 3, GridLayoutManager.HORIZONTAL, true)
binding.recyclerView.layoutManager = layoutManager
// 지그재그 그리드 형태로 배치
val layoutmanager = StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL)
binding.recyclerView.layoutManager = layoutManager
💡아이템 데커레이션
- 아이템 데커레이션은 리사이클러 뷰를 다양하게 꾸밀 때 사용한다.
- 라이브러리에서 제공하는 아이템 데커레이션은 항목의 구분선을 출력해 주는
DividerItemDecoration
뿐이다. 따라서ItemDecoration
을 상속받는 개발자 클래스를 만들고 해당 클래스에서 다양한 꾸미기 작업을 한다. - 아이템 데커레이션은 다음 꾸미기 작업을 하는 함수 3개를 제공한다.
onDraw()
: 항목이 배치되기 전에 호출된다.onDrawOver()
: 항목이 모두 배치된 후 호출된다.getItemOffsets()
: 개별 항목을 꾸밀 때 호출된다. 매개변수로 전달되는Rect
객체는 각 항목을 화면에 출력할 때 필요한 사각형 정보다.left, top, right, bottom
의 여백을 설정할 수 있다.
// 아이템 데커레이션 구현
class MyDecoration(val context: Context): RecyclerView.ItemDecoration(){
override fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State){
super.onDraw(c, parent, state)
}
override fun onDrawOver(c: Canvas, parent: RecyclerView, state: RecyclerView.State){
super.onDrawOver(c, parent, state)
}
override fun getItemOffsets(
outRect: Rect,
view: View,
parent: RecyclerView,
state: RecyclerView.State
){
super.getItemOffsets(outRect, view, parent, state)
}
}
addItemDecoration()
함수를 이용한다.// 리사이클러 뷰에 아이템 데커레이션 적용
binding.recyclerView.addItemDecoration(MyDecoration(this))
🌼뷰 페이저2 - 스와이프로 넘기는 화면 구성
💡뷰 페이저2
- 뷰 페이저는 스와이프 이벤트로 화면을 전환할 때 사용한다.
- 뷰 페이저는 플랫폼 API에서 제공하지 않으므로
androidx
라이브러리를 이용해 개발해야 한다. 2019년에 viewPager2가 제공되며 라이브러리의 기능이 더 많아졌으므로 뷰페이저2를 사용하는 것이 좋다.
- 먼저 뷰페이저2 라이브러리를 레이아웃 XML 파일에 추가한다.
<androidx.viewPager2.widget.ViewPager2
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/viewPager"
(...생략...) />
- 리사이클러 뷰 어댑터를 이용해서 적용한다. 화면 3개를 뷰 페이저2로 제공하는 어댑터다. 각 화면을 구성하는 레이아웃 XML 파일에는 텍스트 뷰가 하나 선언되었다고 가정한 것이다.
// 뷰 페이저2 구현 - 리사이클러 어댑터 이용
class MyPagerViewHolder(val binding: ItemPagerBinding):
RecyclerView.VieHolder(binding.root)
class MyPagerAdaptor(val datas: MutableList<String>):
RecyclerView.Adaptor<RecyclerView.ViewHolder>(){
override fun getItemCount(): Int{
return datas.size
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int):
RecyclerView.ViewHolder = MypagerViewHolder(ItemPagerBinding.inflate(LayoutInflater.from(
parent.context), parent, false))
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int){
val binding = (holder as MyPagerViewHolder).binding
// 뷰에 데이터 출력
binding.itemPagerTextView.text = datas[position]
when(position%3){
0 -> binding.itemPagerTextView.setBackgroundColor(Color.RED)
1 -> binding.itemPagerTextView.setBackgroundColor(Color.BLUE)
2 -> binding.itemPagerTextView.setBackgroundColor(Color.GREEN)
}
}
}
- 위 어댑터를 뷰 페이저2에 적용하면 된다.
// 뷰 페이저2 어댑터에 적용
binding.viewpager.adaptor = MyPagerAdaptor(datas)
- 리사이클러 뷰 어댑터를 이용해서 뷰 페이저2를 구현할 수도 있지만 대부분 각 항목은 복잡하게 작성된다. 따라서 각 항목의 내용은 보통 프래그먼트로 작성한다. 이 경우
FragmentStateAdapto
로 뷰 페이저 2를 구현한다.
// 뷰 페이저2 구현 - 프래그먼트 어댑터 이용
class MyFragmentPagerAdaptor(activity: FragmentActivity): FragmentStateAdaptor(activity){
val fragments: List<Fragment>
init{
fragments= listof(OneFragment(), TwoFragment(), ThreeFragment())
Log.d("kkang","fragments size : ${fragments.size}")
}
// 항목의 개수를 구함
override fun getItemCount(): Int = fragments.size
// 항목을 구성하는 프래그먼트 객체를 얻고, 반환하는 객체를 각 항목에 출력
override fun createFragment(position: Int): Fragment = fragments[position]
}
- 뷰 페이저2 에서는 화면 방향도 설정할 수 있다. 기본은 가로 방향이며, 세로로 나오게 하려면 다음 속성을 변경한다.
// 뷰 페이저2를 세로로 적용
binding.viewpager.orientation = ViewPager2.ORIENTATION_VERTICAL
🌼드로어 레이아웃 - 옆에서 열리는 화면 구성
💡드로어 레이아웃
- 드로어 레이아웃은 액티비티 화면에 보이지 않던 내용이 왼쪽이나 오른쪽에서 손가락의 움직임에 따라 밀려나오는 기능이다.
androidx
의DrawerLayout
으로 구현한다. DrawerLayout
의 하위 태그는 2개여야 한다. 이렇게 XML을 설정만 해도 첫 태그에 해당하는 화면이 알아서 나오고 사용자가 화면 끝을 밀면 두 번째 태그에 해당하는 화면이 나타난다.
// 드로어 레이아웃 구성
<androidx.drawerlayout.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drawer"
(...생략...) >
<LinearLayout
(...생략...) >
</LinearLayout>
<TextView
android:layout_gravity="start"/>
</<androidx.drawerlayout.widget.DrawerLayout>
- 레이아웃 XML만으로 드로어 레이아웃을 이용할 수 있는데, 대부분 툴바 영역에 토글 버튼을 함께 제공한다. 드로어 토글 버튼은
ActionBarDrawerToggle
클래스에서 제공한다.
// 드로어 메뉴 토글 버튼 적용
class DrawerActivity: AppCompatActivity(){
lateinit var toggle: ActionBarDrawerToggle
override fun onCreate(savedInstanceState: Bundle?){
(...생략...)
// ActionBarDrawerToggle 버튼 적용(두 번째: 드로어 객체, 세 번째, 네 번째: 상태를 표현한 문자열)
toggle = ActionBarDrawerToggle(this, binding.drawer, R.string.drawer_opened, R.string.drawer_closed)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
toggle.syncState()
}
override fun onOptionItemSelected(item: MenuItem): Boolean{
// 이벤트가 토글 버튼에서 발생하면
if(toggle.onOptionItemSelected(item: MenuItem): Boolean{
return true
}
return super.onOptionItemSelected(item)
}
}
🏁결론
안드로이드 앱 프로그래밍에서 제트팩 라이브러리, 리사이클러 뷰, 뷰 페이저2, 드로어 레이아웃의 사용법을 정리했다. 제트팩 라이브러리는 프래그먼트의 동적 제어와 생명주기를 다루며, 리사이클러 뷰는 목록 화면을 구성하는 방법을 설명한다. 뷰 페이저2는 스와이프로 화면을 전환하는 기능을 제공하며, 드로어 레이아웃은 화면의 옆에서 열리는 기능을 구현한다. 각 섹션은 코드 예제와 함께 상세한 구현 방법을 제공한다.
Share article