Google Maps Api보다 친절하다는 얘기를 종종 들었다.
구글이야 글로벌하니까 레퍼런스 찾기가 쉽다.
예제는 예제 일 뿐 비즈니스 로직(?)을 짜는데는 크게 도움이 안된다.
당연히 소리인게 사용설명서에는 사용 방법을 알려주지 활용하는 방법을 알려주진 않는다.
그런 측면에서 내가 글로벌 서비스를 계획하고 있거나 다양한 레퍼런스들로 실습해보고 싶다면 닥구글 인 것 같다.
이전 포스트에 api 사용을 위한 권한 및 초기 설정에 관해 다룬적이 있다.
그래서 이번에는 더 깊게 들어가서 지도와 좌표에 필요한 요소들에 대해 알아보자.
하나의 지도는 뷰 요소와 인터페이스 요소로 구성됩니다. 뷰 요소는 화면에 지도를 나타내는 역할을 하며, MapFragment
와 MapView
가 여기에 해당합니다. 지도를 다루는 인터페이스 역할을 하는 인터페이스 요소는 NaverMap
클래스가 담당하며, 오버레이를 추가하고 상호작용하는 등 지도와 관련된 기능 대부분을 이 클래스에서 제공합니다. MapFragment
및 MapView
는 개발자가 직접 생성할 수 있으나 NaverMap
객체는 오직 콜백 메서드를 이용해서 얻어올 수 있습니다.
MapFragment
는 androidx.fragment.app.Fragment
의 하위 클래스로, 여타 프래그먼트와 마찬가지로 레이아웃 XML 또는 FragmentTransaction
을 사용해 추가할 수 있습니다.
val fm = supportFragmentManager
val mapFragment = fm.findFragmentById(R.id.map) as MapFragment?
?: MapFragment.newInstance().also {
fm.beginTransaction().add(R.id.map, it).commit()
}
MapFragment
를 다른 프래그먼트 내에 배치할 경우 supportFragmentManager
대신 childFragmentManager
를 사용해 MapFragment
를 자식 프래그먼트로 두어야 합니다.
다음은 MapFragment
를 다른 프래그먼트 내에 배치하는 예제입니다.
val fm = childFragmentManager
val mapFragment = fm.findFragmentById(R.id.map) as MapFragment?
?: MapFragment.newInstance().also {
fm.beginTransaction().add(R.id.map, it).commit()
}
MapView의 특징 때문
MapView
를 사용할 때는 반드시 MapView
가 포함된 액티비티의 라이프 사이클에 맞추어 onCreate()
, onStart()
, onResume()
, onPause()
, onStop()
, onDestroy()
, onSaveInstanceState()
, onLowMemory()
를 호출해야 합니다. 단, MapView
가 프래그먼트에 포함될 경우 프래그먼트의 onCreateView()
또는 onViewCreated()
에서 onCreate()
를, onDestroyView()
에서 onDestroy()
를 호출해야 합니다. 그렇지 않으면 지도가 정상적으로 동작하지 않습니다. MapFragment
를 사용하면 이러한 절차가 필요하지 않으므로 MapFragment
를 사용하는 것을 권장합니다.
라고 Naver에서 권장하고 있다.
MapFragment
및 MapView
는 지도에 대한 뷰 역할만을 담당하므로 API를 호출하려면 인터페이스 역할을 하는 NaverMap
객체가 필요합니다. MapFragment
또는 MapView
의 getMapAsync()
메서드로 OnMapReadyCallback
을 등록하면 비동기로 NaverMap
객체를 얻을 수 있습니다. NaverMap
객체가 준비되면 onMapReady()
콜백 메서드가 호출됩니다.
FragmentTransaction vs FragmentContainerView
FragmentTransaction이 프래그먼트를 좀 더 동적으로 추가/교체가 가능하다고 하여 채택하였다.