-1- Navigation Library
- https://developer.android.com/kotlin/ktx?hl=ko
- https://developer.android.com/jetpack/androidx/releases/navigation?hl=ko
- build.gradle에 적용하는 Navigation Library에는 자체적인 ktx 버전이 있어서 dependencies에 추가하기전에 버전확인을 하면 좋을 것 같다. 현재 2.7.2 버전이 최근에 릴리즈된 버전이지만, API 34 레벨이상을 요구하므로 버전을 낮춰서 사용할 것이다. 추후에 target API 34이상의 앱을 만들게 될 경우에 추가할 예정이다.
Navigation Library
- Navigation Library란??
- Android 앱의 화면 전환을 관리하기 위한 Android Jetpack 라이브러리이다.
- Navigation Library의 장점
- 백 스택 관리
- Navigation 라이브러리는 백 스택을 자동으로 관리한다.
- 단일 Activity 아키텍쳐 지원
- 단일 Activity와 다수의 Fragment 연결이 가능하므로 앱 전반적인 구조가 단순화 되고 Fragment간의 통합이 쉽다.
- Animation 적용에 용이
- Navigation Library는 res/anim에서 생성한 animation을 res/navigation 의 navigation graph에서 적용할 수 있다.
- 디자인 그래프
- Navigation graph를 사용하여 앱 내에서 Fragment 전환 흐름을 시각화하여 관리할 수 있다
- 백 스택 관리
- supportFragmentManager.replace()를 통한 Fragment 전환과의 차이
- supportFragmentManager.replace().commit 을 통한 Fragment 전환은 Activity에서 Fragment 전환이 이루어짐으로 Fragment의 갯수가 많아지면 단일 Activity 아키텍쳐에서 Activity의 복잡성이 증가될 수 있다.
- Navigation Library는 build.gradle dependencies를 추가해야 하므로 앱 크기가 약간 증가한다.
매우 중요구글이 Navigation Library 이용을 권장한다
build.gradle
기본적으로 사용될 Fragment는 이미 생성된 것으로 간주한다 ( Fragment build.gradle등은 설명 X )
dependencies {
implementation("androidx.navigation:navigation-fragment-ktx:2.5.3")
implementation("androidx.navigation:navigation-ui-ktx:2.5.3")
...
}
res/menu 폴더안에 menu.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/bottom_btn_search"
android:title="@string/search"
android:icon="@drawable/ic_search_24"/>
<item
android:id="@+id/bottom_btn_favorite"
android:title="@string/favorite"
android:icon="@drawable/ic_favorite_24"/>
<item
android:id="@+id/bottom_btn_settings"
android:title="@string/settings"
android:icon="@drawable/ic_settings_24"/>
</menu>
res/navigation 폴더안에 navigation_graph.xml 를 생성해준다
- Navigation Graph의 Design 탭에서 Fragment를 추가해준다.
- home 모양의 아이콘으로 초기 화면에 띄워질 Fragment를 선택할 수 있다.
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/imagesearch_nav_graph"
app:startDestination="@id/bottom_btn_search">
<fragment
android:id="@+id/bottom_btn_search"
android:name="com.example.imagesearchapp.ui.view.SearchFragment"
android:label="@string/search"
tools:layout="@layout/fragment_search" />
<fragment
android:id="@+id/bottom_btn_favorite"
android:name="com.example.imagesearchapp.ui.view.FavoriteFragment"
android:label="@string/favorite"
tools:layout="@layout/fragment_favorite" />
<fragment
android:id="@+id/bottom_btn_settings"
android:name="com.example.imagesearchapp.ui.view.SettingsFragment"
android:label="@string/settings"
tools:layout="@layout/fragment_settings" />
</navigation>
- 이때, Navigation.xml에 id는 res/menu의 menu.xml에서 지정해준 id와 일치시켜주어야 한다.
activity_main.xml
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.view.MainActivity">
<FrameLayout
android:id="@+id/main_frameLayout"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="80dp"
app:layout_constraintBottom_toTopOf="@+id/bottomNavigationView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/imagesearch_nav_host_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="androidx.navigation.fragment.NavHostFragment"
app:defaultNavHost="true"
app:navGraph="@navigation/imagesearch_nav_graph"
/>
</FrameLayout>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottomNavigationView"
android:layout_width="0dp"
android:layout_height="56dp"
app:labelVisibilityMode="unlabeled"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/main_frameLayout"
app:menu="@menu/menu" />
</androidx.constraintlayout.widget.ConstraintLayout>
- Fragment를 띄울 UI Layout안에 FragmentContainerView를 만들어주고 res/navigation에서 생성해둔 xml을 navGraph로 설정해준다.
MainActivity.kt
- supporFragmentManager.replace()로 전환하는 코드가 더 직관적이지만 코드의 길이가 차이가 많다
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private lateinit var navController: NavController
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
setNavigation()
}
private fun setNavigation() {
val host = supportFragmentManager
.findFragmentById(R.id.imagesearch_nav_host_fragment) as NavHostFragment
navController = host.navController
binding.bottomNavigationView.setupWithNavController(navController)
}
// private fun setupBottomNavigationView() {
// binding.bottomNavigationView.setOnItemSelectedListener {
// when (it.itemId) {
// R.id.bottom_btn_search -> {
// supportFragmentManager.beginTransaction()
// .replace(R.id.main_frameLayout, SearchFragment())
// .commit()
// true
// }
// R.id.bottom_btn_favorite -> {
// supportFragmentManager.beginTransaction()
// .replace(R.id.main_frameLayout, FavoriteFragment())
// .commit()
// true
// }
// R.id.bottom_btn_settings -> {
// supportFragmentManager.beginTransaction()
// .replace(R.id.main_frameLayout, SettingsFragment())
// .commit()
// true
// }
// else -> false
//
// }
// }
// }
}
[오늘 복습한 내용]
1. API를 가져올 때 Base Url 과 Header, Parameter를 항상 신경쓰자
- 어제는 Parameter를 sidoName을 sideName으로 써서 고생했는데 오늘은 url로 고생했다
[오류,에러 등등]
1. BaseUrl은 /로 끝나야 하고, @Get Annotation과 중복되면 안된다.
- baseUrl은 전체 url에서 getMethod에 해당하는 부분을 중복시키면 안된다.
@Get에서 v2/search/image를 해놓고
BASE_URL 에서 v2/search/image를 또 넣어버렸다.
[느낀 점]
1. API를 가져올 때 Base Url 과 Header, Parameter를 항상 신경쓰자
2. 조금 더 부지런히 열심히 하자 ++ 선택과 집중
3. 코루틴, ViewModel Factory 등 배우는 건 많은데... 어떤 것 부터 이해하고 넘어가야 할 지 모르겠다
[Reference]
// navigation
https://developer.android.com/guide/navigation?hl=ko
// api
https://developers.kakao.com/docs/latest/ko/daum-search/dev-guide#search-image
'TIL' 카테고리의 다른 글
[TIL] Kotlin SQLite (0) | 2023.09.23 |
---|---|
[TIL] Kotlin Coroutine의 구조와 간단한 예제 (0) | 2023.09.22 |
[TIL] 공공 데이터 API 받아오기 / Retrofit2, OkHttp3 를 사용한 간단한 앱 (0) | 2023.09.19 |
[TIL] Kotlin GoogleMaps 만들기 - 2. Fragment에서 띄우기 / Geocoder (0) | 2023.09.18 |
[TIL] Kotlin GoogleMaps 만들기 - 1. Activity에서 띄우기, 현재 위치 받아오기 (0) | 2023.09.18 |