본문 바로가기
Android/꼼꼼한 리뷰

[Sunflower] Main Activity 기능 확인해보기(Navigation, Hilt, DataBinding)

by Taehyung Kim, dev 2020. 12. 30.
728x90

Sunflower 프로젝트를 본격적으로 리뷰하기 앞서 어떤 기준으로 리뷰해야 하는지 고민이 되었습니다.

 

고민 끝에 레이아웃을 기준으로 해당 레이아웃과 관련 있는 기능을 위주로 리뷰하기로 하였습니다.

 


전체 Layout

  • 전체 레이아웃을 위와 같이 구성되어 있습니다.
  • 구조만 보고 파악했을 때는 대략적으로 아래와 같이 구성되어있을 것이라 생각하였습니다.
    • activity_garden을 메인 Activity로 갖는다.
    • 메인 Activity 에서 navigation을 이용한 fragment 전환이 이루어진다.
    • RecyclerView와 같은 리스트 뷰를 사용한 3가지 아이템이 존재한다.
      • list_item_garden_planting.xml
      • list_item_photo.xml
      • list_item_plant.xml

 

대략적으로 생각한 것들이며 메인 Activity 인 activity_garden.xml을 먼저 살펴보기로 하였습니다.

 

 


activity_garden.xml

<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>
  • layout으로 쌓여 있는 것으로 보아 Data Binding을 사용하였음을 알 수 있습니다.
  • gradle을 확인해보니 아래와 같이 dataBinding을 사용하고 있음을 확인하였습니다.
    buildFeatures {
        dataBinding = true
    }

 

  • FragmentContatinerView 를 사용하고 있습니다.
  • 속성 navGraph에서 navigation의 nav_garden을 따르고 있음을 알 수 있습니다.
  • 개념에 대해서 간단하게 짚고 넘어가겠습니다.

FragmentContainerView

안드로이드 developer 에 아래와 같이 나와있습니다.

  • FragmentContainerView는 Fragments 용으로 특별히 설계된 사용자 정의된 레이아웃이다.
  • Fragment Transactions 을 안정적으로 처리할 수 있도록 Fragment Layout 을 확장하며 Fragment 동작에 맞춰 조정할 수 있는 추가 기능도 제공한다.

 

navigation 을 살펴보겠습니다.


navigation

 

<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"
    app:startDestination="@id/view_pager_fragment">

    <fragment
        android:id="@+id/view_pager_fragment"
        android:name="com.google.samples.apps.sunflower.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:enterAnim="@anim/slide_in_right"
                app:exitAnim="@anim/slide_out_left"
                app:popEnterAnim="@anim/slide_in_left"
                app:popExitAnim="@anim/slide_out_right" />
    </fragment>

    <fragment
        android:id="@+id/plant_detail_fragment"
        android:name="com.google.samples.apps.sunflower.PlantDetailFragment"
        android:label="@string/plant_details_title"
        tools:layout="@layout/fragment_plant_detail">

        <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.google.samples.apps.sunflower.GalleryFragment"
        android:label="@string/plant_details_title"
        tools:layout="@layout/fragment_gallery">
        <argument
            android:name="plantName"
            app:argType="string" />
    </fragment>

</navigation>

메인 소스에서 한번 더 살펴봐야할 것이라 생각이 되지만 지금 간단하게 훑어보고 지나가겠습니다.

간단하게 특징만 골라서 정리하면 아래와 같습니다.

 

이 navigation 의 첫 시작은 view_pager_fragment를 아이디로 갖는 fragment입니다.

각 fragment는 label을 가지고 있으면 해당 label 은 앱 바가 있을 경우 제목을 표시해줍니다.

(label을 표시해주는 NavigationUI 가 지원하는 상단 앱 바 유형은 1. Toolbar, 2. CollapsingToolbarLayout, 3. ActionBar이다.)

 

각 fragment의 특징을 정리해보겠습니다.

  1. view_pager_fragment
    1. HomeViewPagerFragment 클래스를 기반으로 작동한다.
    2. action을 취하면 plant_detail_fragment 아이디를 갖는 fragment로 이동한다.
    3. 이동 시 애니메이션을 각각 적용한다.
      1. enterAnim : action 수행 시 목적지 화면에 입장하는 애니메이션
      2. exitAnim : action 수행 시 현재 화면으로 입장하는 애니메이션
      3. popEnterAnim : 이전 화면으로 돌아갈 때 목적 화면에 대한 애니메이션
      4. popExitAnim : 이전 화면으로 돌아갈 때 종료되는 화면에 대한 애니메이션
  2. plant_detail_fragment
    1. PlantDetailFragment 클래스를 기반으로 작동한다.
    2. action 을 취하면 gallery_ragment 아이디를 갖는 fragment 로 이동한다.
    3. 이동 시 애니메이션을 각각 적용한다(위와 동일).
    4. argument : fragment 이동 시 데이터를 전달할 때 사용한다.
      1. plantId 이름으로 String 타입의 데이터
  3. gallery_fragment
    1. GalleryFragment 클래스를 기반으로 작동한다.
    2. argument
      1. plantName 이름으로 String 타입의 데이터

여기까지 navigation에 대해 간단하게 알아보았습니다.

위 fragment의 흐름에 대해서 어느 정도 눈에 보이기 시작했습니다.

 

이제 메인 Activity layout을 살펴보았고 이 layout을 보여주는 Activity를 살펴보겠습니다.

 


GardenActivity

package com.google.samples.apps.sunflower

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil.setContentView
import com.google.samples.apps.sunflower.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)
    }
}

이 프로젝트에는 해당 액티비티 단 한개만 존재합니다.

또한 내부의 기능은 Container 역할을 수행하는 것을 확인할 수 있습니다.

 

중요한 특징을 아래와 같이 정리해보았습니다.

  • setContentView에서 layout Binding을 타입으로 명시하였다.
  • DI(의존성 주입)를 사용하기 위해 Hilt의 @AndroidEntryPoint 어노테이션을 사용하였다.

 

@AndroidEntryPoint란

  • 해당 어노테이션을 설정한 클래스는 Android class lifecycle을 따르는 종속 container를 생성한다.
  • @Inject 어노테이션을 사용하기 위해서 클래스에 설정해야한다.

 

여기서 Hilt에 대해 간단하게 알아보도록 하겠습니다.


Hilt

Hilt란 무엇인가

  • DI(Dependencies Injection, 의존성 주입)를 관리하기 위한 DI Tool입니다.

왜 사용하는가

  • DI를 사용하면 유지관리, 테스트에 용이한 아키텍처를 구성하는데 도움이 됩니다.

어떻게 사용하는가

  • 각 속성과 역할에 맞는 어노테이션을 설정하여 사용한다.

각 어노테이션에 대한 설명은 아래를 참고하면 됩니다.

https://thkim-study.tistory.com/19

 

[Android] Hilt 의존성 주입(DI) gradle 버전, 각 어노테이션 설명

gradle.build(project) buildscript { ext.kotlin_version = '1.3.72' ext.hilt_version = '2.28-alpha' repositories { google() jcenter() } dependencies { classpath 'com.android.tools.build:gradle:4.0.0'..

thkim-study.tistory.com

Hilt에 대해 더 자세히 공부하고 싶다면 아래의 Example을 따라서 해보는 것을 추천합니다.

https://codelabs.developers.google.com/codelabs/android-hilt#0

 

Using Hilt in your Android app  |  Google Codelabs

In this codelab, you’ll build an Android app that uses Hilt to do Dependency Injection.

codelabs.developers.google.com

 

여기서 설명하는 방식으로는 Hilt가 이 프로젝트에 미치는 영향을 파악하기에 어려움이 있으므로 나중에 한번 더 언급할 예정입니다.

 


여기까지 메인 Activity와 layout에 대해 확인하였습니다.

 

다음으로는 메인 Activity에서 nav_graph에 지정되어 있는 Fragment를 따라서 확인해보겠습니다.

728x90

댓글