본문 바로가기

android

(24)
Lifecycle Activity, Fragment 와 같은 생명 주기를 가진 컴포넌트들은 특정 상황이 되면 Android 프레임워크에서 자동으로 Lifecycle Callback 메서드를 호출해줍니다. Activity 의 각 Lifecycle Callback 메서드에 Log 를 찍어보면 현재 Lifecycle state 가 어떤 지 금방 확인할 수 있지만, 어떤 경로를 통해 Lifecycle 의 state 가 변경되는 지 코드를 통해 분석해보기로 했습니다. 아래의 Activity Lifecycle state 가 업데이트 되는 경로는 앱을 처음 실행하여 MainActivity 가 실행될 때의 경로를 확인한 것입니다. ActivityThread 에서 관찰중인 Looper 에 새로운 Activity 를 실행해달라는 메시지가 ..
Fragment 내에 ViewPager 를 사용한 Fragment 호스팅 시 Navigation 문제 상황 AFragment 내에 ViewPager2 를 사용하여 BFragment 를 호스팅하고 있음 BFragment 의 특정 UI 요소를 클릭하면 CFragment 로 navigate 되어야 하는 상황 문제 발생 BFragment 의 UI 요소를 클릭하여 CFragment 로 navigate 하는 순간 java.lang.IllegalArgumentException: Navigation action/destination com.xxx.xxx:id/action_BFragment_to_CFragment cannot be found from the current destination Destination(com.xxx.xxx:id/aFragment) label=AFragment class=com.xxx.xxx...
setContentView Android 프로젝트를 생성하면 MainActivity 클래스의 onCreate() 메서드에서 setContentView() 메서드를 호출하는 코드가 기본으로 생성됩니다. setContentView() 메서드가 정확히 어떤 작업을 담당하는 것인지 알지 못한 채 그냥 "setContentView() 메서드에 전달한 Layout 파일이 파싱되고, View 인스턴스가 생성되겠지?" 라고만 생각했었는데, Android 의 View System 에 대해 좀 더 알고 싶어져서 과연 setContentView() 메서드는 내부적으로 어떤 동작을 하는지 분석해보기로 했습니다. 총 9단계로 setContentView() 메서드를 분석하였습니다. 1. MainActivity 가 상속받은 AppCompatActivity ..
Jetpack Navigation NavHostFragment Jetpack Navigation 을 사용하여 Fragment 간에 전환하면 NavController 가 적절한 Navigator(예: FragmentNavigator) 를 선택하여 직접 FragmentManager 를 사용하여 FragmentTransaction 을 생성하고 각 Destination(NavBackStackEntry) 을 BackStack 에 push,pop 을 하기 때문에 개발자 입장에서는 굉장히 편리하게 화면 전환을 구현할 수 있습니다. Chapter 01 Navigation Graph 의 각 Destination 을 호스팅하는 NavHostFragment 일반적으로 Jetpack Navigation 을 통해 Single Activity 에 여러 Fragment 를 사용할 때는 act..
6. ViewModelStore 와 ViewModelStoreOwner ① ViewModelStore 은 ViewModel 객체를 저장하기 위한 클래스입니다. 내부에 ViewModel 을 저장하기 위해 HashMap 을 가지고 있으며, put(ViewModelStore 에 ViewModel 저장), get(ViewModelStore 에 저장된 ViewModel 반환), clear(ViewModelStore 에 저장된 ViewModel 객체 정리) 메서드를 제공합니다. ② ViewModelStore 객체는 ViewModelStoreOwner 인터페이스 구현 객체에서 관리합니다. Activity(ComponentActivity class) 또는 Fragment(Fragment class) 는 ViewModelStoreOwner 인터페이스를 구현한 ViewModelStoreOwn..
Animation 1 - Tween Animation Tween Animation 은 View Animation 의 한 종류로 View 의 위치, 투명도, 크기, 회전을 지정한 시간동안 수행하는 애니메이션입니다. Tween Animation 의 종류는 아래와 같습니다. ① TranslateAnimation → View 의 좌표를 변경하여 위치를 변경시키는 애니메이션입니다. ② AlphaAnimation → View 의 투명도를 변경하는 애니메이션입니다. ③ ScaleAnimation → View 의 가로와 세로 크기를 변경하는 애니메이션입니다. ④ RotateAnimation → View 를 회전시키는 애니메이션입니다. Tween Animation 은 코드 또는 XML 을 이용하여 View 에 적용할 수 있습니다. 코드를 이용한 Tween Animation..
edge-to-edge edge-to-edge 란 ① edge-to-edge 란 앱 컨텐츠를 system bar(status bar + navigation bar) 영역까지 확장하여 표시하게 만드는 것을 말합니다. 쉽게 말해 status bar 와 navigation bar 를 투명하게 만들어서 앱 컨텐츠가 보이게 만드는 것을 말합니다. edge-to-edge 구현 ① system bar 의 색상 변경 앱이 edge-to-edge 로 동작할 때 앱 컨텐츠를 볼 수 있도록 status bar 와 navigation bar 의 색상을 투명하게 만들어야 합니다. 앱이 이 단계를 수행한 후 시스템은 Gestrue Navigation 모드에서는 navigation bar 뒤에 있는 컨텐츠에 따라 색상을 변경하는 dynamic color..
Room DB 와 RoomTrackingLiveData Room 의 구성요소인 Dao 에서 getAll() 과 같은 메서드에서는 리턴타입을 LiveData 형태로하면 연결된 테이블의 데이터가 변경되면 옵저버들에게 통지가 가도록 만들 수 있습니다. 그런데 생각을 해보다 좀 이상한 부분이 있었습니다. LiveData 는 관찰 가능한 데이터 홀더 클래스로 값이 변경될 때 setValue 또는 postValue 메서드를 호출하여 옵저버들의 onChanged 메서드를 호출하여 통지를 해주는 방식으로 동작합니다. 그렇게 하려면 데이터소스에서 데이터를 읽어온 후 LiveData 에 값을 설정하는 메서드에서 setValue 를 호출해줘야지만 옵저버들에게 통지가 가게됩니다. 즉 아래와 같이 Activity 또는 Fragment 에서 먼저 LiveData 옵저버를 등록한 후 ..
Location 기능 사용 시 워크플로우 (1) 위치 액세스 권한 흐름 ① Manifest 파일에 ACCESS_COARSE_LOCATION(대략적 위치) 과 ACCESS_FINE_LOCATION(정확한 위치) 권한을 선언합니다. ② 사용자가 위치 정보에 액세스해야 하는 기능(예: 배달앱의 초기 주소 설정 등)을 실행할 때 권한이 존재하는지 검사 후 없다면 사용자에게 런타임 권한 요청을 합니다. 만약 앱에서 정밀한 위치 정보가 필요한 경우에는 ACCESS_COARSE_LOCATION 과 ACCESS_FINE_LOCATION 을 함께 요청해야 합니다. 만약 ACCESS_FINE_LOCATION 만 요청하는 경우 Android 12 이상을 타겟팅하는 경우 "ACCESS_FINE_LOCATION must be requested with ACCESS_C..
Custom View onMeasure Custom View 의 크기를 지정하기 위한 작업을 onMeasure 메서드에서 해야 합니다. onMeasure 메서드의 매개변수는 부모 View 에서 측정한 자식 View 의 widthMeasureSpec 과 heightMeasureSpec 입니다. MeasureSpec 은 Mode 와 Size 를 인코딩한 정수값입니다. CustomView 의 layout_width 또는 layout_height 를 MATCH_PARENT 또는 특정 dp 로 설정하면 , 부모 View 에서 측정하여 전달한 MeasureSpec 의 Mode 가 EXACTLY 로 설정되어 onMeasure 에 전달되며, wrap_content 로 설정하면 AT_MOST 로 전달됩니다. EXACTLY 로 전달된 경우 부모 View 에서 ..