[Android] ActionBar ์ •๋ฆฌ

Minjun Kimยท2023๋…„ 8์›” 28์ผ
0

Android

๋ชฉ๋ก ๋ณด๊ธฐ
25/47
post-thumbnail

๐Ÿ“ SeSAC์˜ 'JetPack๊ณผ Kotlin์„ ํ™œ์šฉํ•œ Android App ๊ฐœ๋ฐœ' ๊ฐ•์ขŒ๋ฅผ ์ •๋ฆฌํ•œ ๊ธ€ ์ž…๋‹ˆ๋‹ค.


๐Ÿ“‡ ActionBar ๊ฐœ์š”

๐Ÿ“š ์•กํ‹ฐ๋น„ํ‹ฐ์˜ ๊ตฌ์กฐ

์•กํ‹ฐ๋น„ํ‹ฐ๊ฐ€ ์ถœ๋ ฅํ•˜๋Š” ์ „์ฒด ํ™”๋ฉด์„ Window ๋ผ๊ณ  ํ•˜๊ณ , ActionBar ์™€ Content ๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ๋‹ค.

์—ฌ๊ธฐ์„œ ActionBar ๋Š” ํ™”๋ฉด ์ƒ๋‹จ์˜ ํƒ€์ดํ‹€ ๋ฌธ์ž์—ด์ด ์ถœ๋ ฅ๋˜๋Š” ์˜์—ญ์ด๋‹ค.

์šฐ๋ฆฌ๊ฐ€ kt ํŒŒ์ผ์—์„œ setContentView ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์˜๋ฏธ๋ฅผ ์—ฌ๊ธฐ์„œ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

setContentView ๋กœ Content ์˜์—ญ์„ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ž„์˜๋กœ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด๋‹ค.

ActionBar ๋Š” ๋”ฐ๋กœ ๋ช…๋ น์„ ๋‚ด๋ฆฌ์ง€ ์•Š์•„๋„ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ถœ๋ ฅ๋œ๋‹ค. ์ด ๊ฒฝ์šฐ ํƒ€์ดํ‹€ ๋ฌธ์ž์—ด์ด ์ถœ๋ ฅ๋œ๋‹ค.

๋ฌผ๋ก  ๊ฐœ๋ฐœ์ž๊ฐ€ ๊ตฌ์„ฑ์š”์†Œ๋ฅผ ์ถ”๊ฐ€ ํ•  ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ“Œ ActionBar ์˜ ๊ตฌ์„ฑ์š”์†Œ

ํƒ€์ดํ‹€ ๋ฌธ์ž์—ด, ๋„ค๋น„๊ฒŒ์ด์…˜ ์•„์ด์ฝ˜, ์•ก์…˜ ์•„์ดํ…œ, ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ ๋ฉ”๋‰ด ๋“ฑ

  • Navigation Icon ์— ์œ„์น˜ํ•˜๋Š” <- (๋’ค๋กœ๊ฐ€๊ธฐ) ๋ฒ„ํŠผ์˜ ๋ช…์นญ์€ HomeAsUp ์ด๋‹ค.

โ“ ์–ด๋–ป๊ฒŒ ๊ตฌ์„ฑํ• ๊นŒ?

๊ธฐ๋ณธ์ ์œผ๋กœ ์•ˆ๋“œ๋กœ์ด๋“œ ํ”Œ๋žซํผ์—์„œ ์ œ๊ณตํ•˜๋Š” API๋กœ ์ž‘์„ฑ ๊ฐ€๋Šฅํ•˜๋‹ค. ํ•˜์ง€๋งŒ ์ผ๋ฐ˜์ ์œผ๋กœ androidx์—์„œ ์ œ๊ณตํ•˜๋Š” appcompat ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ด์šฉํ•œ๋‹ค.

appcompat ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์˜์กด์„ฑ์ด ์ถ”๊ฐ€๋˜์–ด ์žˆ๋‹ค. ๊ทธ ์ •๋„๋กœ ๊ธฐ๋ณธ์ด๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ๊ฒ ๋‹ค.

์›๋ก ์ ์œผ๋กœ appcompat ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ์ œ๊ณต ๋ชฉ์ ์€ '์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ ๊ด€๋ จ๋˜์–ด ์žˆ๋Š” ๊ฐ€์žฅ ๊ธฐ์ดˆ์ ์ธ ๊ธฐ๋Šฅ๋“ค์„ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•จ' ์ด๋‹ค.

Activity๋ฅผ ์ž‘์„ฑํ•  ๋•Œ Activity ๊ฐ€ ์•„๋‹Œ AppCompatActivity ๋ฅผ ์ƒ์† ๋ฐ›์•„ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ๋งŒ ๋ณด๋”๋ผ๋„ ์•Œ ์ˆ˜ ์žˆ๋Š” ๋ถ€๋ถ„์ด๋‹ค.

class MainActivity : AppCompatActivity() {
	private val binding by lazy { ActivityDetailBinding.inflate(layoutInflater) }
	
    override fun onCreate(savedInstanceState: Bundle?) {
		super.onCreate(savedInstanceState)
		setContentView(binding.root)
  • AppCompatActivity() ์ด appcompat ์—์„œ ์ œ๊ณต๋˜๋Š” ํด๋ž˜์Šค์ด๋‹ค.

๐Ÿงฉ ActionBar ํ…Œ๋งˆ

ActionBar์˜ ์ƒ‰์ƒ์€ ๊ธฐ๋ณธ์ ์œผ๋กœ theme.xml ํŒŒ์ผ์— ์ •์˜๋˜์–ด ์žˆ๋Š” ์ƒ‰์ƒ์œผ๋กœ ์ถœ๋ ฅ๋œ๋‹ค.

๋งŒ์•ฝ ActionBar์˜ ์ƒ‰์„ ๋ณ€๊ฒฝํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด colorPrimary ์˜ต์…˜์„ ์ˆ˜์ •ํ•˜๋ฉด๋œ๋‹ค.

  • theme.xml
<resources xmlns:tools="http://schemas.android.com/tools">
    <!-- Base application theme. -->
    <style name="Base.Theme.AndroidLab" parent="Theme.Material3.DayNight.NoActionBar">
        <item name="colorPrimary">@android:color/holo_purple</item>
        
    </style>
    <style name="Theme.AndroidLab" parent="Base.Theme.AndroidLab" />
</resources>

์ด ์™ธ์—๋„ ์ƒ‰์ƒ์„ ์ œ์–ดํ•˜๋Š” ํ‚ค์›Œ๋“œ๊ฐ€ ์žˆ๋‹ค.

<resources xmlns:tools="http://schemas.android.com/tools">
    <!-- Base application theme. -->
    <style name="Base.Theme.AndroidLab" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
        <!-- Primary brand color. -->
        <item name="colorPrimary">#FF0000</item>
        <item name="colorPrimaryVariant">#FFFF99</item>
        <item name="colorOnPrimary">@color/white</item>
        <!-- Secondary brand color. -->
        <item name="colorSecondary">#00FF00</item>
        <item name="colorSecondaryVariant">#F999F0</item>
        <item name="colorOnSecondary">@color/black</item>
        <!-- Status bar color. -->
        <item name="android:statusBarColor" tools:targetApi="l">?attr/color</item>
        <!-- Customize your light theme here. -->
        <!-- <item name="colorPrimary">@color/my_light_primary</item> -->
    </style>

    <style name="Theme.AndroidLab" parent="Base.Theme.AndroidLab" />
</resources>

๐Ÿ“‡ Menu

ActionBar ์šฐ์ธก์„ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

Overflow Menu ์˜ ํ•ญ๋ชฉ์„ ์ถ”๊ฐ€ํ•˜๋ฉด ์ž๋™์œผ๋กœ Overflow Button (์  3๊ฐœ) ์ด ์ถœ๋ ฅ๋œ๋‹ค.

๐Ÿงฉ ๊ตฌ์„ฑ ๋ฐฉ๋ฒ•

๊ตฌ์„ฑ ๋ฐฉ๋ฒ•์€ ์‰ฝ๋‹ค.

์•กํ‹ฐ๋น„ํ‹ฐ ํ•จ์ˆ˜๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋“œ ๋ฐ›์•„์„œ ์ž‘์„ฑํ•ด ๋†“์œผ๋ฉด, ๋ฉ”๋‰ด๋ฅผ ๊ตฌ์„ฑํ•˜๊ธฐ ์œ„ํ•ด์„œ ์ž๋™ ํ˜ธ์ถœ ๋œ๋‹ค.

๐Ÿ“Œ Menu ์ถ”๊ฐ€

๊ทธ ์ž๋™ ํ˜ธ์ถœ๋˜๋Š” ํ•จ์ˆ˜๊ฐ€ onCreateOptionsMenu() ์ด๋‹ค.

override fun onCreateOptionsMenu(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)
}
  • ์ฆ‰, onCreateOptionsMenu() ์€ ์•กํ‹ฐ๋น„ํ‹ฐ ํ•จ์ˆ˜์ด๋ฉฐ ๋ฉ”๋‰ด ๊ตฌ์„ฑ์„ ์œ„ํ•ด ์ž๋™ ์ฝœ ๋œ๋‹ค.

  • ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ Menu ๋ฅผ ๋ฐ›๋Š”๋ฐ, ์ด๋ฅผ ๋ฉ”๋‰ด๋ฐ” ์ •๋„๋กœ ์ƒ๊ฐํ•˜๋ฉด ๋œ๋‹ค.
    ์šฐ๋ฆฌ๋Š” ๊ทธ์ € ๋ฉ”๋‰ด๋ฐ”์— Menu ๋ฅผ ์—ด์‹ฌํžˆ add ํ•˜๋ฉด ๋œ๋‹ค.

  • menu ์˜ ๋‘ ๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์‹๋ณ„์ž์ด๋‹ค. ๋ฉ”๋‰ด์˜ ์•„์ด๋””๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋œ๋‹ค.
    ์ˆซ์ž๊ฐ’์œผ๋กœ ์ง€์ •ํ•˜๊ณ , ์ด๊ฒƒ์œผ๋กœ ์–ด๋–ค ๋ฉ”๋‰ด๊ฐ€ ํด๋ฆญ ๋˜์—ˆ๋Š”์ง€ ๊ตฌ๋ถ„ํ•œ๋‹ค.

๐Ÿ“Œ Menu ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ

onOptionsItemSelected() ๋ผ๋Š” ํ•จ์ˆ˜๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋“œ ๋ฐ›์•„ ์ž‘์„ฑํ•˜๋ฉด ๋œ๋‹ค.

์œ ์ €๊ฐ€ ๋ฉ”๋‰ด๋ฅผ ์„ ํƒ ์‹œ ํ•ด๋‹น ํ•จ์ˆ˜๊ฐ€ ์ž๋™ ์ฝœ ๋œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์„ ํƒํ•œ ๋ฉ”๋‰ด๊ฐ€ ์ „๋‹ฌ๋œ๋‹ค.

override fun onOptionsItemSelected(item: MenuItem): Boolean = when (item.ItemId) {
		0 -> {
			true
		}
		1 -> {
			true
		}
		else -> super.onOptionsItemSelected(item)
	}

๐Ÿงฉ ์‹ค์Šต ์˜ˆ์ œ

  • MainActivity.kt
package com.kotdev99.android.c37

class MainActivity : AppCompatActivity() {
	override fun onCreate(savedInstanceState: Bundle?) {
		super.onCreate(savedInstanceState)
		setContentView(R.layout.activity_main)
	}

	// Menu ๊ตฌ์„ฑ
	override fun onCreateOptionsMenu(menu: Menu?): Boolean {
		menu?.add(0, 0, 0, "menu1")
		menu?.add(0, 1, 0, "menu2")
		return super.onCreateOptionsMenu(menu)
	}

	// Menu ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ
    // item.itemId ๋กœ ๋ฉ”๋‰ด๋ฅผ ๊ตฌ๋ถ„ํ•œ๋‹ค
	override fun onOptionsItemSelected(item: MenuItem): Boolean = when (item.itemId) {
		0 -> {
			Toast.makeText(this, "menu1 click", Toast.LENGTH_SHORT).show()
			true
		}
		1 -> {
			Toast.makeText(this, "menu2 click", Toast.LENGTH_SHORT).show()
			true
		}
		else -> super.onOptionsItemSelected(item)
	}
}

๐Ÿ“ฒ ๊ฒฐ๊ณผ


๐Ÿ“‡ MenuInflater

Menu๋ฅผ ๋ฆฌ์†Œ์Šค๋กœ์จ XML ๋กœ ์ •์˜

์ƒ๊ฐํ•ด ๋ณด๋ฉด ๋ฉ”๋‰ด๋ผ๋Š” ๊ฒƒ์ด ์ •์ ์ธ ๊ตฌ์„ฑ์ด ๋Œ€๋ถ€๋ถ„์ด๋‹ค. ๋•Œ๋ฌธ์— XML ๋กœ ์ •์˜ํ•˜๋Š” ๊ฒƒ์ด ์ผ๋ฐ˜์ ์ด๋‹ค.

๐Ÿ“Œ ์‚ฌ์šฉ ๋ฐฉ๋ฒ•

res/menu ํ•˜์œ„์— menu.xml ํŒŒ์ผ ์ƒ์„ฑ


item ํƒœ๊ทธ๋กœ Menu ๋ฅผ ์ถ”๊ฐ€

  • menu_main.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/menu1"
        android:title="menu1" />

    <item
        android:id="@+id/menu2"
        android:title="menu2" />
</menu>
  • ๊ธฐ๋ณธ์ ์œผ๋กœ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ ์‹œ ํ•„์š”ํ•œ ์•„์ด๋””์™€ ๋ฉ”๋‰ด์— ์ถœ๋ ฅ ๋  ๋ฌธ์ž์—ด์ด ๋“ค์–ด๊ฐ„๋‹ค.

override fun onCreateOptionsMenu(menu: Menu?): Boolean {
	menuInflater.inflate(R.menu.menu_main, menu)
	return super.onCreateOptionsMenu(menu)
}

๐Ÿ“‡ Menu ์†์„ฑ

๐Ÿ“Œ Action Item

ActionBar์— ์•„์ด์ฝ˜์œผ๋กœ ์ถœ๋ ฅ๋˜๋Š” ๋ฉ”๋‰ด

showAsAction ์†์„ฑ์œผ๋กœ ์ง€์ •

<item
	android:id="@+id/menu2"
	android:icon="@android:drawable/ic_menu_add"
	android:title="menu2"
	app:showAsAction="always" />
  • never : ํ•ญ์ƒ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ ๋ฉ”๋‰ด๋กœ ์ถœ๋ ฅ (default)

  • ifRoom : ๋งŒ์•ฝ ์•ก์…˜๋ฐ”์— ๊ณต๊ฐ„์ด ์žˆ๋‹ค๋ฉด ์•ก์…˜ ์•„์ดํ…œ์œผ๋กœ, ์—†๋‹ค๋ฉด ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ ๋ฉ”๋‰ด๋กœ ์ถœ๋ ฅ

  • always : ํ•ญ์ƒ ์•ก์…˜ ์•„์ดํ…œ์œผ๋กœ ์ถœ๋ ฅ

๐Ÿ“Œ ActionView

ActionBar์˜ ๋‚ด์žฅ ๋ทฐ

๋ทฐ๋Š” ๋ทฐ์ธ๋ฐ Content ๋ถ€๋ถ„์— ์ถœ๋ ฅ๋˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์•ก์…˜๋ฐ”์— ๋‚ด์žฅ๋˜์–ด ์žˆ๋Š” ๋ทฐ

๊ทธ๋Ÿฐ๋ฐ ๋ฉ”๋‰ด ๊ธฐ๋ฒ•์œผ๋กœ ์„ค์ •ํ•ด ์ค˜์•ผ ์ถœ๋ ฅ๋œ๋‹ค. actionViewClass ์†์„ฑ์œผ๋กœ ์ง€์ •ํ•œ๋‹ค.

<item
	android:id="@+id/menu_search"
	android:title="search"
	app:showAsAction="always"
    app:actionViewClass="androidx.appcompat.widget.SearchView" />
  • actionViewClass ์†์„ฑ์— ์•ก์…˜๋ฐ”์— ๋‚ด์žฅ๋˜์–ด ์žˆ๋Š” ๋ทฐ ํด๋ž˜์Šค๋ช…์„ ์ฃผ๋ฉด ๋œ๋‹ค.

๐Ÿงฉ ์‹ค์Šต ์˜ˆ์ œ

res/menu ํ•˜์œ„์— Menu ๋ฆฌ์†Œ์Šค XML ํŒŒ์ผ ์ •์˜

  • 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:icon="@android:drawable/ic_menu_add"
        android:title="menu2"
        app:showAsAction="always" />
    <item
        android:id="@+id/menu3"
        android:icon="@android:drawable/ic_menu_search"
        android:title="menu3"
        app:actionViewClass="androidx.appcompat.widget.SearchView"
        app:showAsAction="always" />
</menu>

MenuInflater ๋กœ ๋ฉ”๋‰ด XML ํŒŒ์ผ์„ ์ ์šฉ

  • MainActivity.kt
package com.kotdev99.android.c38

class MainActivity : AppCompatActivity() {
	override fun onCreate(savedInstanceState: Bundle?) {
		super.onCreate(savedInstanceState)
		setContentView(R.layout.activity_main)
	}

	override fun onCreateOptionsMenu(menu: Menu?): Boolean {
		menuInflater.inflate(R.menu.menu_main, menu)
		return super.onCreateOptionsMenu(menu)
	}
}

๐Ÿ“ฒ ๊ฒฐ๊ณผ

profile
์‘์•  ๋‚˜ ์•„๊ธฐ ๋‰ด๋น„

0๊ฐœ์˜ ๋Œ“๊ธ€