와챠의 우당탕탕 코딩 일기장
[Android/Kotlin] FragmentContainerView 연습 Code with Joyce 본문
[Android/Kotlin] FragmentContainerView 연습 Code with Joyce
minWachya 2022. 3. 5. 19:39유튜브에서 Kotlin 강좌(Code with Joyce)를 보고 있는데 마지막 강의에서 Navigation에 대한 내용을 다루시길래 재밌어 보여서 나도 같이 만들어보고자 한다.
Navigation 궁금했음!! 더 잘 다르고 싶었음!
https://developer.android.com/guide/navigation/navigation-getting-started?hl=ko
1. dependencies에 아래 내용 추가
dependencies {
...
// Kotlin
def nav_version = "2.4.1"
implementation("androidx.navigation:navigation-fragment-ktx:$nav_version")
implementation("androidx.navigation:navigation-ui-ktx:$nav_version")
...
}
2. res>navigation 폴더 추가
type도 navigation이다.
3. navigation 폴더 우클릭>new>Navigation Resourse File>nav_graph.xml 생성
4. activity_main.xml(프레그먼트들 담을 액티비티의 xml)에 아래 코드 추가
위의 공식 문서에서 FragmentContainerView 부분을 복붙해주면 된다.
<?xml version="1.0" encoding="utf-8"?>
<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=".MainActivity">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:defaultNavHost="true"
app:navGraph="@navigation/nav_graph" />
</androidx.constraintlayout.widget.ConstraintLayout>
5. Fragment 생성 및 xml 꾸미기
+) 만들고자 하는 앱은 심리 테스트 앱이다. 생성된 프레그먼트를 소개하자면...
MainFragment: 심리 테스트 시작 화면
QuestionFragment: 질문 화면
SelectionFragment: 내 답변을 선택하는 화면
ResultFragment: 결과 화면
모든 화면 및 화면에 사용된 이미지 출처는 https://www.youtube.com/watch?v=M1e2tLnzVPo&t=1s
6. nav_graph.xml에 fragment들 추가 및 순서 지정
저 화면 추가 버튼을 눌러서 해당 액티비티 내에서 담을 프레그먼트들을 클릭한다.
시작 부분은 홈 표시가 되도록 하고, 화면 이동 순서대로 화살표를 죽죽 긋는다.
그냥 드래그 하면 된다..., 덜
+) 위의 화면애서 화살표 눌러 Navigation 애니메이션 설정 가능!!
<action
android:id="@+id/action_mainFragment_to_questionFragment"
app:destination="@id/questionFragment"
app:enterAnim="@anim/nav_default_pop_enter_anim"
app:exitAnim="@anim/nav_default_exit_anim"
app:popEnterAnim="@anim/nav_default_pop_enter_anim"
app:popExitAnim="@anim/nav_default_pop_exit_anim" />
7. Fragment 이동 코드 작성
MainFragment: 심리 테스트 시작 화면
private var _binding: FragmentMainBinding?= null
private val binding get() = _binding!!
class MainFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?,
): View {
_binding = FragmentMainBinding.inflate(inflater, container, false)
val view = binding.root
// 다음 프레그먼트로 이동
binding.btnNext.setOnClickListener {
findNavController().navigate(R.id.action_mainFragment_to_questionFragment)
}
return view
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}
QuestionFragment: 질문 화면
코드는 위와 비슷해서 생략... 버튼 눌러서 다름 화면으로 이동하는 거
SelectionFragment: 내 답변을 선택하는 화면: 선택한 옵션 정보를 다음 프레그먼트로 전달 + 뒤로가기
private const val TAG = "mmmMainFragment"
private var _binding: FragmentSelectionBinding?= null
private val binding get() = _binding!!
class SelectionFragment : Fragment(), View.OnClickListener {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?,
): View {
_binding = FragmentSelectionBinding.inflate(inflater, container, false)
val view = binding.root
// 옵션 클릭 리스너
binding.option1.setOnClickListener(this)
binding.option2.setOnClickListener(this)
binding.option3.setOnClickListener(this)
binding.option4.setOnClickListener(this)
// 뒤로가기 리스너
binding.btnBack.setOnClickListener(this)
return view
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
// 클릭 리스너
override fun onClick(view: View?) {
when(view?.id) {
// 옵션 클릭: 해당 인덱스 가지고 다음 프레그먼트로 이동
R.id.option1 -> navigationWithIndex(1)
R.id.option2 -> navigationWithIndex(2)
R.id.option3 -> navigationWithIndex(3)
R.id.option4 -> navigationWithIndex(4)
// 뒤로가기: pop
R.id.btn_back -> findNavController().popBackStack()
}
}
// 옵션 인덱스 가지고 다음 프레그먼트로 이동
private fun navigationWithIndex(index: Int) {
val bundle = bundleOf("index" to index)
findNavController().navigate(R.id.action_selectionFragment_to_resultFragment, bundle)
}
}
ResultFragment: 결과 화면
private var _binding: FragmentResultBinding?= null
private val binding get() = _binding!!
class ResultFragment : Fragment() {
var option = -1
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?,
): View {
_binding = FragmentResultBinding.inflate(inflater, container, false)
val view = binding.root
// 선택한 옵션 받아오기
option = arguments?.getInt("index") ?: -1
// 결과 보이기
setResult(option)
// 홈 프레그먼트로 이동
binding.btnHome.setOnClickListener { findNavController().navigate(R.id.action_resultFragment_to_mainFragment) }
return view
}
// 선택한 옵션에 맞는 결과 보여주기
private fun setResult(option: Int) {
when(option) {
1 -> {
binding.resultTitle.text = "1번"
binding.resultSubTitle.text = "1번을 선택하셨군요."
}
2 -> {
binding.resultTitle.text = "2번"
binding.resultSubTitle.text = "2번을 선택하셨군요."
}
3 -> {
binding.resultTitle.text = "3번"
binding.resultSubTitle.text = "3번을 선택하셨군요."
}
4 -> {
binding.resultTitle.text = "4번"
binding.resultSubTitle.text = "4번을 선택하셨군요."
}
}
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}
끝.. 입니다^^
털석... 이렇게나 쉽고 간단하고 아름답기까지 한 네비게이션 사용 방법이 있었다니...
그동안 난 대체 뭘 했던 것인가..
이거 완성하고 나서 이 기능이 넘 좋고 간편해서..... 약간 허무했음ㅋ
그래서 잠깐 산책도 다녀옴
아무튼 너무 쉽고 간단한 방법을 배워서 좋았다~
또 배운 것이 있는데
- Guideline 사용법(xml의 Design화면 우클릭>Add Helpers>Guideline)
- onCreate 안에서 onClickListener를 람다식으로 정의하는 게 아니라 클래스에 View.OnClickListener를 상속받는 방식으로 onClickListener를 처리한 것...
- ctrl+d는 해당 라인 복붙...
특히 2번 3번 배운 게 좋았다.
2번은... 맨날 고민했음
버튼 클릭 리스너같은 걸 onCreate에 쓰는 방식은 onCreate 내부가 지저분한 것 같다고 생각했음
새로운 방법을 배워서 기쁘다
3번도 맨날 마우스로 복붙 디립다 해왓는데 이렇게 편한 방법이..?
요새 단축키의 효율성을 깨닫는 중이다.
단축키 더 공부해야함
'코딩 일기장 > Android(Kotlin)' 카테고리의 다른 글
[Android/Kotlin]EditText scollbar custom/cursor color (0) | 2022.03.19 |
---|---|
[Android/Kotlin] TabLayout: unselected tab indicator/미선택된 탭의 이터레이터 색 설정/탭 밑줄/tab underline (0) | 2022.03.19 |
[Android/Kotlin]사진 최대 선택 개수 제한하기/limit the number of selected photo (0) | 2022.02.27 |
[Android/Kotlin]Custom Dialog (0) | 2022.02.26 |
[Android/Kotlin]BottomSheetDialog/round corner/아래에 뜨는 다이얼로그로 선택하는 스피너 (0) | 2022.02.19 |