์ค์ ํ๋ก์ ํธ
์ค์ต - ์์ ๋ฑ
์ฃผ์๊ตฌ์ฑ
- ๊ฐ๋กํ๋ฉด์ผ๋ก ๊ณ ์ ๋ ํ ์กํฐ๋นํฐ์ ๋, ๋ , ๋ฏธ, ํ, ์, ๋ผ, ์, ๋ ์ํ์ด ์์
- ์ํ์ ๋๋ฅด๋ฉด ํด๋น ์์ด ์ฌ์๋จ
- ์ํ์ ํ ์คํธ ๋ทฐ ์์ฑ์ ์์ ํ๊ณ , ์๋ฆฌ๋ SoundPool ํด๋์ค๋ฅผ ์ฌ์ฉํ์ฌ ์ฌ์ํจ
- SoundPool์ ์๋๋ก์ด๋ 5.0๋ถํฐ ์ฌ์ฉ๋ฒ์ด ๋ฌ๋ผ์ง
- ๊ตฌ ๋ฒ์ ๊ณผ ์ ๋ฒ์ ๊ธฐ๊ธฐ์์ ๋ชจ๋ ์ ๋์ํ๋๋ก ๋ฒ์ ๋ถ๊ธฐ๋ฅผ ์ ์ฉํจ
1. ๋ ์ด์์ ์์ฑ
๊ฐ๋ก ๋ชจ๋๋ก ๊ณ ์ ํ๊ธฐ
๋ฐฉ๋ฒ1) MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
// ํ๋ฉด์ด ๊ฐ๋ก ๋ชจ๋๋ก ๊ณ ์ ๋๊ฒ ํ๊ธฐ ์ฒซ๋ฒ์งธ ๋ฐฉ๋ฒ
//requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
๋ฐฉ๋ฒ2) AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application
...
<activity
android:name=".MainActivity"
android:exported="true"
android:screenOrientation="landscape">
...
</activity>
</application>
</manifest>
๊ฐ๋ก ๋ชจ๋๋ก ๊ณ ์ ํ๊ธฐ
- ๋ ์ด์์ ์๋ํฐ์์ ๋ฏธ๋ฆฌ๋ณด๊ธฐ๋ฅผ ๊ฐ๋ก ๋ชจ๋๋ก ๋ณ๊ฒฝํด์ผ ํจ
- activity_main.xml ํ์ผ์ ์ด๊ณ ๋ ์ด์์ ์๋ํฐ๋ฅผ ๊ฐ๋ก ๋ชจ๋๋ก ์์ ํ ์ ์๋๋ก โ Orientation for Preview๋ฅผ ํด๋ฆญํ์ฌ โก Landscape๋ฅผ ์ ํํจ
ํ์ด๋ธ ๋ฐ ์์ ๊ธฐ
- AndoridManifest.xml : ํ ๋ง(theme)๊ฐ ๋ชจ์ ๊ฒฐ์
android:theme="@style/Theme.Xylophone"
- Res/values/themes/themes.xml → .noActionBar
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Base.Theme.Xylophone" parent="Theme.Material3.DayNight.NoActionBar">
<!-- Customize your light theme here. -->
<!-- <item name="colorPrimary">@color/my_light_primary</item> -->
</style>
<style name="Theme.Xylophone" parent="Base.Theme.Xylophone" />
</resources>
ํ ์คํธ ๋ทฐ๋ก ์ํ ๋ง๋ค๊ธฐ
2. ์๋ฆฌ ์ฌ์ํ๊ธฐ
์ค๋กํฐ ์๋ฆฌ ํ์ผ ์ค๋นํ๊ธฐ
- ์ค๋กํฐ ์๋ฆฌ ํ์ผ์ http://bit.ly/2K9dQjo ์์ ๋ค์ด๋ก๋๋ฐ์ 03 STEP
raw ๋ฆฌ์์ค ๋๋ ํ ๋ฆฌ ์ถ๊ฐ
- Resource type ๋๋กญ๋ค์ด ๋ฆฌ์คํธ๋ฅผ ํด๋ฆญํ์ฌ raw๋ฅผ ์ ํํ๊ณ OK๋ฅผ ํด๋ฆญํจ
raw ๋ฆฌ์์ค ๋๋ ํ ๋ฆฌ ์ถ๊ฐ
- ํ๋ก์ ํธ ์ฐฝ์์ raw ๋๋ ํฐ๋ฆฌ๋ฅผ ์ ํํ๊ณ ๋จ์ถํค ๋ฅผ ๋๋ฆ
- ๋ถ์ฌ๋ฃ์ ํ์ผ ์ด๋ฆ์ ์์ ํ๋ ํ๋ฉด์ด ํ์๋๋๋ฐ ์ฌ๊ธฐ์๋ ๊ทธ๋๋ก OK๋ฅผ ํด๋ฆญํจ
- raw ๋๋ ํฐ๋ฆฌ์ ์ค๋กํฐ ์๋ฆฌ ํ์ผ์ ๋ถ์ฌ๋ฃ๊ธฐ๋ง ํ๋ฉด ์ค๋น๊ฐ ์๋ฃ๋จ
์๋๋ก์ด๋์์ ์๋ฆฌ๋ฅผ ์ฌ์ํ๋ ๋ฐฉ๋ฒ
- MediaPlayer ํด๋์ค์ SoundPool ํด๋์ค๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ด ์์
- MediaPlayer ํด๋์ค๋ ์ผ๋ฐ์ ์ผ๋ก ์๋ฆฌ๋ฅผ ํ ๋ฒ๋ง ์ฌ์ํ๋ ๊ฒฝ์ฐ ๋๋ ๋ ธ๋๋ ๋ฐฐ๊ฒฝ์๊ณผ ๊ฐ์ ๊ฒฝ์ฐ์๋ ์ ์ฉํจ
- SoundPool์ ๋ค์๊ณผ ๊ฐ์ด ์ฌ์ฉํจ
- load ( ) ๋ฉ์๋์ play ( ) ๋ฉ์๋์ ์ํ์ ๋ค์๊ณผ ๊ฐ์
SoundPool ์ด๊ธฐํ ๋ฒ์ ๋ถ๊ธฐ
- MainActivity ํ์ผ์ ์ด๊ณ SoundPool ๊ฐ์ฒด๋ฅผ ์ด๊ธฐํํ๋ ์ฝ๋ ์ถ๊ฐ
class MainActivity : AppCompatActivity() {
private val soundPool = SoundPool.Builder().setMaxStreams(8).build() // SoundPool ๊ฐ์ฒด๋ฅผ ์ด๊ธฐํ
...
}
์ํ์ ๋์ ์ผ๋ก ํด๋ฆญ ์ด๋ฒคํธ ์ ์ํ๊ธฐ
- ๋จผ์ listOf ( ) ํจ์๋ฅผ ์ฌ์ฉํ์ฌ ํ ์คํธ ๋ทฐ์ ID์ ์์ ํ์ผ์ ๋ฆฌ์์ค ID๋ฅผ ์ฐ๊ด ์ง์ Pair ๊ฐ์ฒด 8๊ฐ๋ฅผ ๋ฆฌ์คํธ ๊ฐ์ฒด sounds๋ก ๋ง๋ฆ
- Pair ํด๋์ค๋ ๋ ๊ฐ์ ์ฐ๊ด๋ ๊ฐ์ฒด๋ฅผ ์ ์ฅํจ
- Pair(first, second) : first์ second, ๊ฐ๊ฐ์ ๊ฐ์ฒด๋ฅผ ์ฐ๊ฒฐํด ํ ์์ผ๋ก ๋ง๋ค์ด์ค
class MainActivity : AppCompatActivity() {
private val soundPool = SoundPool.Builder().setMaxStreams(8).build() // SoundPool ๊ฐ์ฒด๋ฅผ ์ด๊ธฐํ
private val sounds = listOf( // ์ฌ์ฉํ ์์๋ค์ ๋ฆฌ์คํธ๋ก ๋ง๋ค๊ธฐ
Pair(R.id.do1, R.raw.do1), // (์์ ฏ ์์ด๋, ์ฌ์ฉํ ์์)
Pair(R.id.re, R.raw.re),
Pair(R.id.mi, R.raw.mi),
Pair(R.id.fa, R.raw.fa),
Pair(R.id.sol, R.raw.sol),
Pair(R.id.la, R.raw.la),
Pair(R.id.si, R.raw.si),
Pair(R.id.do2, R.raw.do2)
)
...
}
์ํ์ ๋์ ์ผ๋ก ํด๋ฆญ ์ด๋ฒคํธ ์ ์ํ๊ธฐ
- sounds ๋ฆฌ์คํธ๋ฅผ forEach ( ) ํจ์๋ฅผ ์ฌ์ฉํ์ฌ ์์๋ฅผ ํ๋์ฉ ๊บผ๋ด์ tune( ) ๋ฉ์๋์ ์ ๋ฌํจ
์ํ์ ๋์ ์ผ๋ก ํด๋ฆญ ์ด๋ฒคํธ ์ ์ํ๊ธฐ
- tune ( ) ๋ฉ์๋๋ Pair ๊ฐ์ฒด๋ฅผ ๋ฐ์์ load ( ) ๋ฉ์๋๋ก ์์์ ID๋ฅผ ์ป๊ณ , findViewById( ) ๋ฉ์๋๋ก ํ ์คํธ ๋ทฐ์ ID์ ํด๋นํ๋ ๋ทฐ๋ฅผ ์ป๊ณ , ํ ์คํธ ๋ทฐ๋ฅผ ํด๋ฆญํ์๋ ์์์ ์ฌ์ํจ
- ์ฑ์ ์ข ๋ฃํ ๋๋ ๋ฐ๋์ release ( ) ๋ฉ์๋๋ฅผ ํธ์ถํ์ฌ SoundPool ๊ฐ์ฒด์ ์์์ ํด์ ํจ
class MainActivity : AppCompatActivity() {
...
override fun onCreate(savedInstanceState: Bundle?) {
// ํ๋ฉด์ด ๊ฐ๋ก ๋ชจ๋๋ก ๊ณ ์ ๋๊ฒ ํ๊ธฐ ์ฒซ๋ฒ์งธ ๋ฐฉ๋ฒ
//requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
sounds.forEach { turn(it) }
}
private fun turn(pair: Pair<Int, Int>) {
// ํ๋ ์ด ์ soundPool ๊ฐ์ฒด load
val soundId = soundPool.load(this, pair.second, 1) // pair์ ๋๋ฒ์งธ(์์), 1: ์ฐ์ ์์
// ํด๋ฆญ ์ ํ๋ ์ดํ๊ธฐ (Pair์ ์ฒซ๋ฒ์งธ -> ์์ด๋์ด๋ฏ๋ก ๋ฐ๋ก ๋ถ๋ฌ ์์ ์ฌ์ฉ)
findViewById<TextView>(pair.first).setOnClickListener {
soundPool.play(soundId, 1.0f, 1.0f, 0, 0, 1.0f) // (์ด๋ค id, ์ผ์ชฝ๋ณผ๋ฅจ, ์ค๋ฅธ์ชฝ๋ณผ๋ฅจ, ์ฐ์ ์์, ๋ฐ๋ณต, ์๋)
}
}
override fun onDestroy() { // ์ฑ ์ข
๋ฃ ์ ์๋์ผ๋ก ๊ฐ์ฒด ์๋ฉธ
super.onDestroy()
soundPool.release()
}
}
์ต์ข
package com.example.xylophone
import android.media.SoundPool
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.TextView
class MainActivity : AppCompatActivity() {
private val soundPool = SoundPool.Builder().setMaxStreams(8).build() // SoundPool ๊ฐ์ฒด๋ฅผ ์ด๊ธฐํ
private val sounds = listOf( // ์ฌ์ฉํ ์์๋ค์ ๋ฆฌ์คํธ๋ก ๋ง๋ค๊ธฐ
Pair(R.id.do1, R.raw.do1), // (์์ ฏ ์์ด๋, ์ฌ์ฉํ ์์)
Pair(R.id.re, R.raw.re),
Pair(R.id.mi, R.raw.mi),
Pair(R.id.fa, R.raw.fa),
Pair(R.id.sol, R.raw.sol),
Pair(R.id.la, R.raw.la),
Pair(R.id.si, R.raw.si),
Pair(R.id.do2, R.raw.do2)
)
override fun onCreate(savedInstanceState: Bundle?) {
// ํ๋ฉด์ด ๊ฐ๋ก ๋ชจ๋๋ก ๊ณ ์ ๋๊ฒ ํ๊ธฐ ์ฒซ๋ฒ์งธ ๋ฐฉ๋ฒ
//requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
sounds.forEach { turn(it) }
}
private fun turn(pair: Pair<Int, Int>) {
// ํ๋ ์ด ์ soundPool ๊ฐ์ฒด load
val soundId = soundPool.load(this, pair.second, 1) // pair์ ๋๋ฒ์งธ(์์), 1: ์ฐ์ ์์
// ํด๋ฆญ ์ ํ๋ ์ดํ๊ธฐ (Pair์ ์ฒซ๋ฒ์งธ -> ์์ด๋์ด๋ฏ๋ก ๋ฐ๋ก ๋ถ๋ฌ ์์ ์ฌ์ฉ)
findViewById<TextView>(pair.first).setOnClickListener {
soundPool.play(soundId, 1.0f, 1.0f, 0, 0, 1.0f) // (์ด๋ค id, ์ผ์ชฝ๋ณผ๋ฅจ, ์ค๋ฅธ์ชฝ๋ณผ๋ฅจ, ์ฐ์ ์์, ๋ฐ๋ณต, ์๋)
}
}
override fun onDestroy() { // ์ฑ ์ข
๋ฃ ์ ์๋์ผ๋ก ๊ฐ์ฒด ์๋ฉธ
super.onDestroy()
soundPool.release()
}
}
์ ๋ฆฌ
- ์๋ฆฌ๋ฅผ ์ฌ์ํ๋ ค๋ฉด MediaPlayer ๋๋ SoundPool ํด๋์ค๋ฅผ ์ฌ์ฉํจ
- ์ผ๋ฐ์ ์ธ ๊ฒฝ์ฐ MediaPlayer ํด๋์ค๊ฐ ๊ฐํธํ์ง๋ง ์ฐ์์ผ๋ก ์๋ฆฌ๋ฅผ ์ฌ์ํ๋ ๊ฒฝ์ฐ์๋ SoundPool ํด๋์ค๋ฅผ ์ฌ์ฉํจ
- ๋ทฐ๊ฐ ์ฌ๋ฌ ๊ฐ์ผ ๋๋ forEach{ } ๋ฑ์ ์ฌ์ฉํ์ฌ ๋์ ์ผ๋ก ํด๋ฆญ ์ด๋ฒคํธ๋ฅผ ๊ตฌํํ ์ ์์
์ฑ ์์์ ๋ฐฐ๊ฒฝ์์ - MusicPlayer
๋๋ง์ ํ๋ ์ด๋ฆฌ์คํธ - ์์ ์ฐ๊ฒฐํด์ ๋ฒํผ ๋๋ฅด๋ฉด ์์ ์ฌ์