외로운 Nova의 작업실
안드로이드 앱 프로그래밍 - 12(제트팩 라이브러리 - appcompat) 본문
- 제트팩
제트팩이란 안드로이드 플랫폼이 기본적으로 제공하는 플랫폼 API외에 따로 추가된 라이브러리입니다. 플랫폼 API란 android.App.Activity와 같은것입니다. 제트팩은 androidx로 시작하는 패키지명을 사용합니다. 제트팩은 크게 다음 3가지 목적으로 제공됩니다.
- 앱을 개발하는 데필요한 권장 아키텍처를 제공합니다.
- API레벨의 호환성 문제를 해결합니다.
- 플랫폼 API에서 제공하지 않는 다양한 기능을 제공합니다.
호환성 문제를 해결해주기때문에 플랫폼 API에서 지원하는 것을 제트팩에서도 지원한다면 제트팩을 많이 사용합니다. 제트팩의 화면 구성과 관련된 라이브러리를 소개하면 다음과 같습니다.
- androidx.appcompat : 앱의 API 레벨 호환성을 해결합니다.
- androidx.recycleview : 목록 화면을 구성합니다.
- androidx.viewpager2 : 스와이프로 넘기는 화면을 구성합니다.
- androidx.fragement : 액티비티처럼 동작하는 뷰를 제공합니다.
- androidx.drawrlayout : 옆에서 서랖처럼 열리는 화면을 구성합니다.
- appcompat 라이브러리
먼저 appcompat 라이브러리를 사용하려면 그래들 파일의 dependencies 항목에 다음처럼 라이브러리 선언을 해줘야합니다. 하지만 이 선언은 안드로이드스튜디오가 모듈을 만들때 자동으로 추가해줍니다.
implementation 'adroidx.appcompat:appcompat:1.2.0'
appcompt 라이브러리를 사용해서 액티비티를 만들때는 플랫폼 API의 Activity가 아니라 다음처럼 appcompat의 AppCompatActivity 클래스를 상속받아 작성합니다.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = ActivityMainBinding.inflate(layoutInflater)
}
- 액션바
액티비티의 구성요소인 액션바는 화면 위쪽 타이틀 문자열이 출력되는 영역을 의미합니다.
<액션바 색상 설정>
액션바의 색상은 앱에 적용되는 테마에서 결정됩니다. 매니페스트 파일에 가보면 테마를 알 수 있습니다.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<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/Theme.AndroidLab">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data
android:name="android.app.lib_name"
android:value="" />
</activity>
</application>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.VIBRATE"/>
</manifest>
android:theme="@style/Theme.AndroidLab" 테마를 사용하는 것으로 확인됩니다. 테마는 res>values>themes.xml 파일에 선언되었습니다.
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.AndroidLab" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
<!-- Primary brand color. -->
<item name="colorPrimary">@color/purple_500</item>
<item name="colorPrimaryVariant">@color/purple_700</item>
<item name="colorOnPrimary">@color/white</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/teal_200</item>
<item name="colorSecondaryVariant">@color/teal_700</item>
<item name="colorOnSecondary">@color/black</item>
<!-- Status bar color. -->
<item name="android:statusBarColor" tools:targetApi="21">?attr/colorPrimaryVariant</item>
<!-- Customize your theme here. -->
</style>
</resources>
각 item의 종류는 아래와 같습니다.
<액션바 숨기기>
액션바를 숨기는건 thems 파일에서수정할 수 있습니다.
<style name="Theme.AndroidLab" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
위코드를 아래와 같이 변경합니다.
<style name="Theme.AndroidLab" parent="Theme.MaterialComponents.DayNight.NoActionBar">
그러면 아래와같이 액션바가 사라집니다.
- 액션바의 뒤로가기 버튼(업버튼)
<매니페스트파일을 활용한 액션바의 업설정>
액션바에 업버튼은 뒤로가기 버튼입니다. 이버튼을 나오게 하려면 매니페스트파일에서 업버튼을 설정할 수 있고 액티비티 코드에서 설정할 수 있습니다. 단순히 뒤로가기 기능이라면 매니페스트파일에서, 뒤로가기 기능을 포함하여 또다른 코드를 실행하려면 액티비티 코드에서 설정하는 것이 좋습니다. 먼저 매니페스트 파일에서 업버튼을 설정해보겠습니다.
<activity
android:name=".MainActivity"
android:exported="true"
android:parentActivityName=".MainActivity2">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data
android:name="android.app.lib_name"
android:value="" />
</activity>
android:parentActivityName=".MainActivity2" 코드로 뒤로가기버튼을 눌렀을때 돌아갈 액티비티를 선택해주면됩니다.
<액티비티를 활용한 액션바의 업설정>
이번에는 액티비티에서 액션바의 업버튼을 설정해보겠습니다. 먼저 앞서 메니페스트 부분의 코드를 삭제해준후 시작합니다. 업버튼 생성은 액티비티내에서 아래의 구문으로 생성합니다.
supportActionBar?.setDisplayHomeAsUpEnabled(true)
이후 업버튼 클릭시 자동으로 호출되는 함수가 있는데 바로 onSupportNavigateUp()함수입니다. 이 함수를 오버라이딩하여 우리가 원하는 동작을 실행시킬 수 있습니다.
override fun onSupportNavigateUp(): Boolean {
Log.d("log", "버튼이 눌렸습니다")
return super.onSupportNavigateUp()
아래는 전체코드입니다.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = ActivityMainBinding.inflate(layoutInflater)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
}
override fun onSupportNavigateUp(): Boolean {
Log.d("log", "버튼이 눌렸습니다")
return super.onSupportNavigateUp()
}
}
- 메뉴
메뉴는 액션바의 중요한 구성요소로 액티비티 화면에서 사용자 이벤트를 활용할 수 있도록 합니다. 메뉴의 구성은 아래와 같습니다.
액티비티에 액션바에 메뉴를 추가하고 싶다면 아래 함수를 사용할 수 있습니다.
onCreateOptionsMenu() //액티비티가 실행되면서 처음 한번만 호출됩니다.
onPrepareOptionsMenu() //오버플로 메뉴가 나타날때마다 반복해서 호출됩니다.
우리는 보통 onCreateOptionsmenu()함수를 사용하여 메뉴를 나타나게합니다. 그럼 한번 menu1, menu2가 오버플로되는 메뉴를 만들어보겠습니다.
override fun onCreateOptionsMenu(menu: Menu?): Boolean { //메뉴 만드는 함수
val menuItme1: MenuItem? = menu?.add(0, 0, 0, "menu1") //오버플로시 메뉴1 추가
val menuItem2: MenuItem? = menu?.add(0, 1, 0, "menu2") //오버플로시 메뉴2추가
return super.onCreateOptionsMenu(menu)
}
add함수의 원형은 아래와 같습니다.
fun add(groupID: INT, itemID: Int, order: Int, title: Charsequence!): MenuItem!
메뉴가 만들어졌다면, 사용자가 menu1을 눌러서 이벤트를 발생시킬 수 있습니다. 또한 이 이벤트를 처리하는 구문을 추가해줄 필요가 있습니다. 이벤트를 처리하는 건 onOptionItemSelected()를 통해 처리할 수 있습니다. 어떤 부분이 눌렸는지는 itemID 값을 통해서 구분합니다.
override fun onOptionsItemSelected(item: MenuItem): Boolean { //메뉴이벤트 처리시 콜백되는 함수
when(item.itemId){
0 -> { //menu1버튼 클릭시
Log.d("log", "selected menu1")
true
}
1 -> { //menu2 버튼 클릭시
Log.d("log", "selected menu2")
true
}
}
return super.onOptionsItemSelected(item)
}
완성된 코드는 아래와 같습니다.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = ActivityMainBinding.inflate(layoutInflater)
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean { //메뉴 만드는 함수
val menuItme1: MenuItem? = menu?.add(0, 0, 0, "menu1") //오버플로시 메뉴1 추가
val menuItem2: MenuItem? = menu?.add(0, 1, 0, "menu2") //오버플로시 메뉴2추가
return super.onCreateOptionsMenu(menu)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean { //메뉴이벤트 처리시 콜백되는 함수
when(item.itemId){
0 -> { //menu1버튼 클릭시
Log.d("log", "selected menu1")
true
}
1 -> { //menu2 버튼 클릭시
Log.d("log", "selected menu2")
true
}
}
return super.onOptionsItemSelected(item)
}
}
<리소스로 메뉴 구현>
액티비티메뉴는 대부분 정적으로 제공되므로 코드가 아니라 리소스 XML파일로 구성합니다. 한번 XML 파일을 메뉴에 적용시켜보겠습니다. 먼저 메뉴 폴더를 res 폴더 밑에 만들어줍니다. res>오른쪽마우스버튼>new>android resource directory
메뉴 폴더에 menu_main.xml파일을 만들어줍니다.
<?xml version="1.0" encoding="utf-8"?>
<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:title="menu2"
app:showAsAction="always"
android:icon="@android:drawable/ic_menu_add"/>
<item
android:id="@+id/menu3"
android:title="menu3"
app:showAsAction="ifRoom"
android:icon="@android:drawable/ic_menu_search"/>
</menu>
app:showAsAction의 속성값의 의미는 아래와 같습니다.
- never(기본값) : 항상 오버플로 메뉴로 출력합니다.
- always : 항상 액션 아이템으로 출력합니다.
- ifRoom : 만약 액션바에 공간이 있다면 액션 아이템으로, 없다면 오버플로 메뉴로 출력합니다.
이제 XML파일을 메뉴생성구문에 추가해줍니다.
override fun onCreateOptionsMenu(menu: Menu?): Boolean { //메뉴 만드는 함수
menuInflater.inflate(R.menu.menu_main, menu)
return super.onCreateOptionsMenu(menu)
}
아래는 전체코드입니다.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = ActivityMainBinding.inflate(layoutInflater)
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean { //메뉴 만드는 함수
menuInflater.inflate(R.menu.menu_main, menu)
return super.onCreateOptionsMenu(menu)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean { //메뉴이벤트 처리시 콜백되는 함수
when(item.title){
"menu1" -> { //menu1버튼 클릭시
Log.d("log", "selected menu1")
true
}
"menu2" -> { //menu2 버튼 클릭시
Log.d("log", "selected menu2")
true
}
}
return super.onOptionsItemSelected(item)
}
}
- 툴바
툴바를 사용하는 목적은 액션바와 같습니다. 하지만 툴바는 개발자가 직접 제어하는 뷰라는데 차이점이 있습니다. 툴바를 직접 만들고 사용해보겠습니다. 먼저 툴바의 xml 코드를 Activity_main.xml에 넣어줍니다.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#FFAC07"
android:id="@+id/toolbar"/>
</LinearLayout>
툴바를 준비했다면 이제 툴바가 출력되게 해줘야합니다. 먼저 themes.xml 파일에 가서 액션바를 없애줍니다. themes.xml (night)는 다크모드의 thems를 의미합니다.
<style name="Theme.AndroidLab" parent="Theme.MaterialComponents.DayNight.NoActionBar">
메인 액티비티에 아래와 같은 코드를 넣어줍니다.
setSupportActionBar(binding.toolbar)
완성된 코드입니다.
package com.example.stopwatch
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.example.stopwatch.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
setSupportActionBar(binding.toolbar)
}
}
이렇게 한후 실행시켜주면
맨위 보라색도 변경하고싶다면 themes.xml파일에서 statusColor을 수정해줍니다.
<item name="android:statusBarColor" tools:targetApi="21">#FFAC07</item>
이후 실행하면
'Programming > Kotlin - Android' 카테고리의 다른 글
안드로이드 앱 프로그래밍 - 14(제트팩 라이브러리 - 리사이클러뷰) (0) | 2023.01.19 |
---|---|
안드로이드 앱 프로그래밍 - 13(제트팩 라이브러리 - 프래그먼트) (0) | 2023.01.19 |
안드로이드 앱 프로그래밍 - 11(소리와 진동알림, 알림) (0) | 2023.01.17 |
안드로이드 앱 프로그래밍 - 10(다양한 다이얼로그) (0) | 2023.01.17 |
안드로이드 앱 프로그래밍 - 9(퍼미션 설정하기) (0) | 2023.01.16 |