티스토리 뷰

Android/Kotlin

[Kotlin] Navigation

혀가 길지 않은 개발자 2021. 5. 23. 23:09

프레그먼트 간 이동을 관리


FragmentContainerView

nav_host

androidx.navigation.fragment.NavHostFragment

defaultNavHost

navGraph


build.gradle (Project)

buildscript {
    dependencies {
    	// safeArgs
        classpath "android.arch.navigation:navigation-safe-args-gradle-plugin:1.0.0"
    }
}

 

 

build.gradle (Module:app)

plugins {
    id 'dagger.hilt.android.plugin'             // hilt
    id 'androidx.navigation.safeargs.kotlin'	// safeArgs
}

dependencies {
    implementation 'androidx.navigation:navigation-fragment-ktx:2.3.5'
    implementation 'androidx.navigation:navigation-ui-ktx:2.3.5'
}

 

 


activity_garden.xml

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <androidx.fragment.app.FragmentContainerView
        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_garden" />

</layout>

 

GardenActivity.kt

package com.example.sunflowerexample

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.databinding.DataBindingUtil.setContentView
import com.example.sunflowerexample.databinding.ActivityGardenBinding
import dagger.hilt.android.AndroidEntryPoint

@AndroidEntryPoint
class GardenActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView<ActivityGardenBinding>(this, R.layout.activity_garden)
    }
}

 

HomeViewPagerFragment.kt (xml에 버튼 하나 있음)

package com.example.sunflowerexample

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController
import com.example.sunflowerexample.databinding.FragmentViewPagerBinding
import dagger.hilt.android.AndroidEntryPoint

@AndroidEntryPoint
class HomeViewPagerFragment : Fragment() {

    lateinit var binding: FragmentViewPagerBinding

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        binding = FragmentViewPagerBinding.inflate(inflater, container, false)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        binding.btViewPager.setOnClickListener {
            findNavController().navigate(HomeViewPagerFragmentDirections.actionViewPagerFragmentToPlantDetailFragment("plantId"))
        }
    }
}

 

PlantDetailFragment.kt (xml에 버튼 하나 있음)

package com.example.sunflowerexample

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController
import com.example.sunflowerexample.databinding.FragmentPlantDetailBinding
import dagger.hilt.android.AndroidEntryPoint

@AndroidEntryPoint
class PlantDetailFragment : Fragment() {

    lateinit var binding: FragmentPlantDetailBinding

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        binding = FragmentPlantDetailBinding.inflate(inflater, container, false)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        binding.btPlantDetail.setOnClickListener {
            findNavController().navigate(PlantDetailFragmentDirections.actionPlantDetailFragmentToGalleryFragment("plantName"))
        }
    }
}

 

 

GalleryFragment.kt (xml에 버튼 하나 있음)

package com.example.sunflowerexample

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import com.example.sunflowerexample.databinding.FragmentGalleryBinding
import dagger.hilt.android.AndroidEntryPoint

@AndroidEntryPoint
class GalleryFragment : Fragment()  {

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val binding = FragmentGalleryBinding.inflate(inflater, container, false)
        return binding.root
    }

}

nav_garden.xml

nav_garden.xml 생성 절차 1
nav_garden 생성 절차 2

 

<?xml version="1.0" encoding="utf-8"?>
<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/nav_garden"
    app:startDestination="@id/view_pager_fragment">

    <fragment
        android:id="@+id/view_pager_fragment"
        android:name="com.example.sunflowerexample.HomeViewPagerFragment"
        tools:layout="@layout/fragment_view_pager">

        <action
            android:id="@+id/action_view_pager_fragment_to_plant_detail_fragment"
            app:destination="@+id/plant_detail_fragment" />
    </fragment>


    <fragment
        android:id="@+id/plant_detail_fragment"
        android:name="com.example.sunflowerexample.PlantDetailFragment"
        android:label="@string/plant_details_title"
        tools:layout="@layout/fragment_gallery">

        <action
            android:id="@+id/action_plant_detail_fragment_to_gallery_fragment"
            app:destination="@+id/gallery_fragment" />

        <argument
            android:name="plantId"
            app:argType="string" />
    </fragment>

    <fragment
        android:id="@+id/gallery_fragment"
        android:name="com.example.sunflowerexample.GalleryFragment"
        android:label="@string/plant_details_title"
        tools:layout="@layout/fragment_gallery">

        <argument
            android:name="plantName"
            app:argType="string" />
    </fragment>

</navigation>

실행 결과


프레그먼트가 바뀌는데 밋밋하다?

애니메이션 추가 ㄱㄱ


애니메이션 생성 절차 1

 

애니메이션 생성 절차 2

 

anim.xml (/res/values)

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <integer name="slide">200</integer>
</resources>

slide_in_left.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate android:fromXDelta="-100%" android:toXDelta="0%"
        android:fromYDelta="0%" android:toYDelta="0%"
        android:duration="@integer/slide" />
</set>

slide_out_left.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate android:fromXDelta="0%" android:toXDelta="-100%"
        android:fromYDelta="0%" android:toYDelta="0%"
        android:duration="@integer/slide" />
</set>

slide_in_right.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate android:fromXDelta="100%" android:toXDelta="0%"
        android:fromYDelta="0%" android:toYDelta="0%"
        android:duration="@integer/slide" />
</set>

slide_in_right.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate android:fromXDelta="100%" android:toXDelta="0%"
        android:fromYDelta="0%" android:toYDelta="0%"
        android:duration="@integer/slide" />
</set>

 

duration : 실행 시간

fromXDelta : 시작 X축 값 (0% = 처음 자리)

toXDelta : 끝 X축 값 (100% = 오른쪽으로 100%만큼 이동) (-100% = 왼쪽으로 100%만큼 이동)

fromYDelta : 시작 Y축 값 (0% = 처음 자리)

toYDelta : 끝 Y축 값 (200% = 아래쪽으로 200%만큼 이동) (-200% = 위쪽으로 200%만큼 이동)


nav_garden.xml

<?xml version="1.0" encoding="utf-8"?>
<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/nav_garden"
    app:startDestination="@id/view_pager_fragment">

    <fragment
        android:id="@+id/view_pager_fragment"
        android:name="com.example.sunflowerexample.HomeViewPagerFragment"
        tools:layout="@layout/fragment_view_pager">

        <action
            android:id="@+id/action_view_pager_fragment_to_plant_detail_fragment"
            app:destination="@+id/plant_detail_fragment"
            app:exitAnim="@anim/slide_out_left"
            app:enterAnim="@anim/slide_in_right"
            app:popEnterAnim="@anim/slide_in_left"
            app:popExitAnim="@anim/slide_out_right" />
    </fragment>


    <fragment
        android:id="@+id/plant_detail_fragment"
        android:name="com.example.sunflowerexample.PlantDetailFragment"
        android:label="@string/plant_details_title"
        tools:layout="@layout/fragment_gallery">

        <action
            android:id="@+id/action_plant_detail_fragment_to_gallery_fragment"
            app:destination="@+id/gallery_fragment"
            app:enterAnim="@anim/slide_in_right"
            app:exitAnim="@anim/slide_out_left"
            app:popEnterAnim="@anim/slide_in_left"
            app:popExitAnim="@anim/slide_out_right" />

        <argument
            android:name="plantId"
            app:argType="string" />
    </fragment>

    <fragment
        android:id="@+id/gallery_fragment"
        android:name="com.example.sunflowerexample.GalleryFragment"
        android:label="@string/plant_details_title"
        tools:layout="@layout/fragment_gallery">

        <argument
            android:name="plantName"
            app:argType="string" />
    </fragment>

</navigation>

 

app:enterAnim : A -> B로 Action할 때 들어오는 UI 대상의 Animation(B의 Animation)

app:exitAnim : A -> B로 Action할 때 나가는 UI 대상의 Animation(A의 Animation)

app:popEnterAnim : B -> A로 Pop할 때 들어오는 UI 대상의 Animation(A의 Animation)

app:popExitAnim : B -> A로 Pop할 때 나가는 UI 대상의 Animation(B의 Animation)

 

실행 결과


 

 

 

 

 

 

참고.

https://github.com/android/sunflower

 

android/sunflower

A gardening app illustrating Android development best practices with Android Jetpack. - android/sunflower

github.com

 

'Android > Kotlin' 카테고리의 다른 글

[Kotlin] CoordinatorLayout  (0) 2021.05.24
[Kotlin] CollapsingToolbarLayout  (0) 2021.05.24
[Kotlin] Hilt  (0) 2021.05.23
[Kotlin] Compose  (0) 2021.05.22
[Kotlin] SpannableStringBuilder  (0) 2021.05.22
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함