외로운 Nova의 작업실

안드로이드 앱 프로그래밍 - 12(제트팩 라이브러리 - appcompat) 본문

Programming/Kotlin - Android

안드로이드 앱 프로그래밍 - 12(제트팩 라이브러리 - appcompat)

Nova_ 2023. 1. 18. 15:02

- 제트팩

제트팩이란 안드로이드 플랫폼이 기본적으로 제공하는 플랫폼 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>

이후 실행하면

Comments