๊ตฌ๊ธ์์ ์ ๊ณตํ๋ ๊ต์ก์๋ฃ๋ฅผ ์ ๋ฆฌํ๊ธฐ ์ํ ํฌ์คํธ์ ๋๋ค.
์ฑ ๊ธฐ๋ฅ์ด ์ฌ๋ฌ ํ๋ฉด์ผ๋ก ๋ถ๋ฆฌ๋ ์ ์์ต๋๋ค.
๋ค๋ฅธ Activity
์ ๊ฐ์ด ๋ค๋ฅธ ์ฑ component
์์ ์์
์ ์์ฒญํฉ๋๋ค.
Intent
์๋ ์ผ๋ฐ์ ์ผ๋ก ๋ ๊ฐ์ง ๊ธฐ๋ณธ ์ ๋ณด๊ฐ ์์ต๋๋ค.Activity
๋ก์ ์ ํ ์์ณฅ์ ์ง์ ํ๋๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.component
๋ฅผ ์ฌ์ฉํ์ฌ ์์ฒญ์ ์ดํActivity
์ ๋ด๋ถ์ ์ผ๋ก ์ด๋ํฉ๋๋ค.// ์ฑ ๋ด์ `Activity`๋ก์ ์ด๋
fun viewNoteDetail() {
val intent = Intent(this, NoteDetailActivity::class.java)
intent.putExtra(NOTE_ID, note.id)
startActivity(intent)
}
// ํน์ ์ธ๋ถ ์ฑ์ผ๋ก ์ด๋
fun openExternalApp() {
val intent = Intent("com.example.workapp.FILE_OPEN")
if (intent.resolveActivity(packageManager) != null) {
startActivity(intent)
}
}
// ํด๋น Intent์ ๊ธฐ์ค๊ณผ ์ผ์นํ๋ ๋ชจ๋ ์ฑ์ด ์ฒ๋ฆฌํฉ๋๋ค.
fun sendEmail() {
val intent = Intent(Intent.ACTION_SEND)
intent.type = "text/plain"
intent.putExtra(Intent.EXTRA_EMAIL, emailAddresses)
intent.putExtra(Intent.EXTRA_TEXT, "How are you?")
if (intent.resolveActivity(packageManager) != null) {
startActivity(intent)
}
}
menu items๋ XML menu resource์ ์ ์ํฉ๋๋ค. (res/menu ํด๋ ์์ ์์น)
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_settings"
android:orderInCategory="100"
android:title="@string/action_settings"
app:showAsAction="never" />
</menu>
<menu>
<group android:checkableBehavior="single">
<item
android:id="@+id/nav_home"
android:icon="@drawable/ic_menu_camera"
android:title="@string/menu_home" />
<item
android:id="@+id/nav_gallery"
android:icon="@drawable/ic_menu_gallery"
android:title="@string/menu_gallery" />
<item
android:id="@+id/nav_slideshow"
android:icon="@drawable/ic_menu_slideshow"
android:title="@string/menu_slideshow" />
</group>
</menu>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/action_intent"
android:title="@string/action_intent" />
<item
android:id="@+id/action_settings"
android:orderInCategory="100"
android:title="@string/action_settings"
app:showAsAction="never" />
</menu>
orderInCategory: ๊ทธ๋ฃน ๋ด ํญ๋ชฉ์ ์ค์๋ ์์
showAsAction = never: ์ด ํญ๋ชฉ์ App bar์ ๋ฐฐ์นํ์ง ์๊ณ ๋๋ณด๊ธฐ ๋ฉ๋ด ํญ๋ชฉ์ ๋์ดํฉ๋๋ค.
์์ธํ ๋ด์ฉ
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.main, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.action_intent -> {
val intent = Intent(Intent.ACTION_WEB_SEARCH)
intent.putExtra(SearchManager.QUERY, "pizza")
if (intent.resolveActivity(packageManager) != null) {
startActivity(intent)
}
}
else -> Toast.makeText(this, item.title, Toast.LENGTH_LONG).show()
...
Activity
์์ UI์ ์ผ๋ถ๋ถ ๋๋ ๋์์ ๋ํ๋
๋๋ค.Activity
๊ฐ ํธ์คํ
๋์ด์ผ ํฉ๋๋ค.Activity
์ ์๋ช
์ฃผ๊ธฐ์ ์ฐ๊ฒฐ๋ฉ๋๋ค.AndroidX ๋ฒ์ ์ Fragment ํด๋์ค๋ฅผ ์ฌ์ฉํฉ๋๋ค.
(androidx.fragment.app.Fragment)
์ง์ ์ค๋จ๋ ํ๋ซํผ ๋ฒ์ ์ Fragment ํด๋์ค๋ฅผ ์ฌ์ฉํ์ง ์์ต๋๋ค.
(android.app.Fragment)
Fragment
๋์์ด ์๊ณ , ํ๋์ Activity
๋ก ๊ฐ์ ํฉ๋๋ค.build.gradle์ dependencies ๋ถ๋ถ์ ์ถ๊ฐํฉ๋๋ค.
implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
implementation "androidx.navigation:navigation-ui-ktx:$nav_version"
Activity
์ XML์ ์ ์ธํฉ๋๋ค.
<fragment
android:id="@+id/nav_host"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/nav_graph_name"/>
res/navigation ๋๋ ํ ๋ฆฌ์ ์์นํฉ๋๋ค.
Fragment
ํด๋์ค๋ฅผ extend ํฉ๋๋ค.onCreateView()
๋ฅผ override ํฉ๋๋ค.Fragment
์ ๋ ์ด์์์ inflate ํฉ๋๋ค.class DetailFragment : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.detail_fragment, container, false)
}
}
action_<sourceFragment>_to_<destinationFragment>
ํ์์ ์ทจํฉ๋๋ค.<fragment
android:id="@+id/welcomeFragment"
android:name="com.example.android.navigation.WelcomeFragment"
android:label="fragment_welcome"
tools:layout="@layout/fragment_welcome" >
<action
android:id="@+id/action_welcomeFragment_to_detailFragment"
app:destination="@id/detailFragment" />
</fragment>
NavController๋ navigation host์์ UI ํ์์ ๊ด๋ฆฌํฉ๋๋ค.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
...
val navController = findNavController(R.id.myNavHostFragment)
}
fun navigateToDetail() {
navController.navigate(R.id.action_welcomeFragment_to_detailFragment)
}
}
Safe Args ์ฌ์ฉ
argument
๊ฐ ์ ํจํ type์ ๊ฐ์ง๋ ๊ฒ์ ๋ณด์ฅํฉ๋๋ค.<SourceDestination>Directions class
๊ฐ๋ฅผ ์์ฑํฉ๋๋ค.argument
๋ฅผ ์ค์ ํ๋ ํด๋์ค๋ฅผ ์์ฑํฉ๋๋ค.argument
์ ๋ํ ์์ธ์ค๋ฅผ ์ ๊ณตํ๋ <TargetDestination>Args
ํด๋์ค๋ฅผ ์์ฑํฉ๋๋ค.ํ๋ก์ ํธ ์์ค์ build.grdle
buildscript {
repositories {
google()
}
dependencies {
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"
}
}
์ฑ ์์ค์ build.gradle
apply plugin: "androidx.navigation.safeargs.kotlin"
fragment
์ด ์์ํ๋ argument
๋ฅผ ๋ง๋ญ๋๋ค.<Source>FragmentDirections
์ action ๋ฉ์๋์ argument
๋ฅผ ์ค์ ํฉ๋๋ค.fragment
์์ argument
๋ฅผ ๊ฒ์ํฉ๋๋ค.nav_graph.xml
์์ argument
๋ก ๋ฐ์ data๋ฅผ ์ ์ํฉ๋๋ค.
<fragment
android:id="@+id/multiplyFragment"
android:name="com.example.arithmetic.MultiplyFragment"
android:label="MultiplyFragment" >
<argument
android:name="number1"
app:argType="float"
android:defaultValue="1.0" />
<argument
android:name="number2"
app:argType="float"
android:defaultValue="1.0" />
</fragment>
nav_graph.xml
์์ source ๋์์์ ๋ค๋ฅธ ๋์์ผ๋ก ๋ณด๋ผ action์ ์ ์ํฉ๋๋ค.
<fragment
android:id="@+id/fragment_input"
android:name="com.example.arithmetic.InputFragment">
<action
android:id="@+id/action_to_multiplyFragment"
app:destination="@id/multiplyFragment" />
</fragment>
InputFragment.kt
์์ ์ง์ ํ action์ button ํด๋ฆญ ์ ํธ์ถํฉ๋๋ค.
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.button.setOnClickListener {
val n1 = binding.number1.text.toString().toFloatOrNull() ?: 0.0
val n2 = binding.number2.text.toString().toFloatOrNull() ?: 0.0
val action = InputFragmentDirections.actionToMultiplyFragment(n1, n2)
view.findNavController().navigate(action)
}
}
์ง์ ํ argument
๋ฅผ notnullํ๊ฒ ๋ฐ์์ฌ ์ ์์ต๋๋ค.
class MultiplyFragment : Fragment() {
val args: MultiplyFragmentArgs by navArgs()
lateinit var binding: FragmentMultiplyBinding
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val number1 = args.number1
val number2 = args.number2
val result = number1 * number2
binding.output.text = "${number1} * ${number2} = ${result}"
}
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
val navController = findNavController(R.id.nav_host_fragment)
return item.onNavDestinationSelected(navController) ||
super.onOptionsItemSelected(item)
}
<androidx.drawerlayout.widget.DrawerLayout
android:id="@+id/drawer_layout" ...>
<fragment
android:name="androidx.navigation.fragment.NavHostFragment"
android:id="@+id/nav_host_fragment" ... />
<com.google.android.material.navigation.NavigationView
android:id="@+id/nav_view"
app:menu="@menu/activity_main_drawer" ... />
</androidx.drawerlayout.widget.DrawerLayout>
DrawerLayout
์ navigation graph
์ ์ฐ๊ฒฐํฉ๋๋ค.
val appBarConfiguration = AppBarConfig(navController.graph, drawer)
NavController
๋ฅผ ์ฌ์ฉํด NavigationView
๋ฅผ ์ธํ
ํฉ๋๋ค.
val navView = findViewById<NavigationView>(R.id.nav_view)
navView.setupWithNavController(navController)
menu์ navtigation ์ฐ๊ฒฐ ์ฐธ๊ณ ๋งํฌ