스마트폰/안드로이드

Android Jetpack 구성요소 Navigation 알파버전을 실무에 적용해보니

나를찾는아이 2018. 12. 27. 15:03
728x90
반응형




안드로이드가 jetpack이라는 이름으로 안드로이드 앱 개발에 도움을 주는 android 구성요소 콜렉션을 소개했습니다.


구성요소 하나하나가 다 흥미로운 녀석이었지만


그중에서도 Navigation은 저에게 꽤 끌리는 항목입니다.


당장 적용하고 싶을만큼요.



Navigation을 통해서 안드로이드도 iOS에서 하던것처럼 스토리보드라는것의 작성이 가능해졌거든요




iOS는 이미 아주 오래전부터 제공된 스토리보드를 통해서 


개별화면의 UI를 작성할수 있을뿐만 아니라 앱의 전체적인 흐름까지 비주얼하게 볼 수가 있었습니다.


이 화면에서 저 화면으로 어떠한 액션으로 이동되는지 볼 수가 있었죠.



안드로이드는 개별화면의 편집만 가능한 layout editor는 있었는데


아쉽게도 스토리보드 기능까지는 지원하지 않았습니다.




그런데 이번 navigation 의 추가로 스토리보드라는것을 그릴수 있게 되었습니다.


각 화면간의 액션 설정도 가능해졌죠


화면간의 관계에 대해서 한눈에 볼 수 있게 되었습니다.






이렇게 말입니다.



이렇게 한눈에 보이는 전체 네비게이션을 navigation graph라고 하는데


네비게이션 에디터를 통해 편집할 수 있습니다.


개별화면의 수정은 원래 사용하던 layout editor를 사용하고


네비게이션 수준의 연결은 navigation editor를 통해 할수 있습니다.




하나의 navigation graph는 보통 하나의 activity와 연결됩니다.





AndroidManifest.xml 파일에서 이 액티비티가 어떠한 네비게이션 그래프를 사용할지 정해주면 됩니다.



그리고 이 액티비티는 NavHostFragment라는 UI 구성요소를 갖고 있으면 됩니다. 일종의 fragment container입니다.









navigation graph를 구성하는 화면 단위는 fragment 입니다.




acitivty를 넣을수 없는것은 아니지만 현재 액티비티에서 다른 액티비티를 여는 액션정도로만 사용할 뿐입니다.


navigation graph는 NavHostFragment가 관리하는 fragment들의 조합이기 때문에


navigation graph가 관리하는 stack들은 fragment가 됩니다.




안드로이드는 꾸준히 fragment의 사용을 권장하고 있는데요


activity가 할 수 있는 모든 것은 fragment가 할 수 있어야한다가 큰 원칙입니다.



activity는 fragment의 껍데기 정도로 사용하고


실제 구현은 fragment를 통해서 하는것이 여러모로 flexible한 방법이기도 하고,


안드로이드가 권장하고 있습니다.



이번에 새로 추가된 네비게이션 기능을 쓰면 이러이러한 장점들이 있습니다.



1. fragment 트랜잭션을 관리할수 있습니다.


2. up버튼과 back버튼이 구분없이 동일하게 동작합니다.


3. transition과 animation 효과를 표준화하여 코딩할수 있습니다.


4. 딥링크의 처리가 가능합니다


5. Navigation UI 를 사용해서 navigation drawer와 bottom navigation과의 연동을 매우 손쉽게 구현할 수 있습니다.


6. fragment간의 이동시에 안전하게 데이터를 넘길  수 있습니다.


7. android studio의 navigation editor를 이용해 비주얼하게 navigation을 관리할수 있습니다.




https://developer.android.com/topic/libraries/architecture/navigation/


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


이번 포스팅은 네비게이션을 어떻게 구현하는지에 대한 포스팅이 아닌 


써본 후기 정도의 글이라 상세한 구현방법은 위의 코드랩을 참고하면 좋을 것입니다.




실제로 사용해보니 좋은점과 나쁜점은 다음과 같습니다.


그런데 사실 나쁜점이라고 적힌것은 나쁘다 라기보다


아직 알파버전이라 지원이 되지 않는다 이거나


제가 솔루션을 찾지 못했을수도 있으니 알고계신분 계시다면 댓글로 남겨주시면 큰 도움이 될것 같습니다.




좋은점



1. fragmentmanager가 관리하는 back stack의 고질적인 복잡성 해결


새 기능 navigation을 사용하지 않았던 기존의 방식은


fragment manager를 통해 fragment의 스택을 관리하는 것인데


메뉴가 많고 경로가 많아지면 이 스택을 관리하는게 점점 헬입니다.


스택의 정밀한 제어가 가능하긴 하지만 그만큼 복잡함을 요구했습니다.



그런데 navigation을 쓰면 NavHostFragment가 일관성있게 자신의 stack을 관리하게 되기때문에


앱의 입구부터 현재까지의 트랜잭션 stack이 내가 코드로 굳이 관리하지 않아도 알아서 일관성있게 관리됩니다.


무엇이던간에 fragment가 바뀌었으면 새로운 stack이 쌓이게된것이며


이렇게 쌓인 stack의 역순으로 뒤로가기 버튼을 누르면 이동이 됩니다.



다만 단점으로는 예전처럼 스택의 중간을 빼낸다던가 하는 그런 꼼수를 사용할수 없습니다.


하지만 제가 보기에는 stack의 중간을 빼내고 뒤섞는등의 난잡한 관리 보다는


이런식의 제약을 통한 효율성 및 생산성 제고가 훨씬 좋다고 생각합니다.



2. 다른 메뉴UI와 매우 손쉬운 연동





딱 이렇게 코딩하는 것만으로


bottom navigation view와 toolbar의 액션과 NavHostFragment와의 연동이 끝납니다.


bottom navigation의 특정 메뉴를 클릭하면 NavHostFragment가 해당 메뉴에 대응하는 fragment를 불러옵니다.


정말 아주 쉽게 메뉴를 구성할수 있습니다.




3. 네비게이션 에디터를 이용한 프래그먼트 트랜잭션 관리


navigation graph에 속한 fragment들은 각자 고유의 destination id를 가지고 있습니다.


그래서 해당 destination id 를 이용하여 해당 fragment로 이동을 할 수 있습니다.


그리고 네비게이션 에디터를 통해 액션이라는 것도 만들수 있습니다


A 프래그먼트에서 B프래그먼트로 이동하는 액션을 만들어서 이 액션의 id를 이용해서 fragment간 이동을 할 수도 있습니다.


이러한 장점으로 코드를 좀 더 human readable하게 작성할수 있습니다.



그리고 navigation graph를 통해 한눈에 볼 수 있다는 점도 굉장히 매력적입니다.




위에 언급한 장점 말고도


up 버튼과 back버튼의 액션을 서로 달리 고민하지 않아도 된다는점,


딥링크 마저도 정해진 stack을 쌓으면서 이동하게 할수 있다는 점도 좋습니다.




나쁜점



1. 인스타그램스타일의 하단탭 네비게이션UX를 적용하기 어려움





가장 많이 쓰이는 UI구조입니다.


인스타그램식 UI라고도 하죠


인스타그램은 하단의 각각의 탭이 자기만의 navigation stack을 가지고 있습니다.



그러니깐 내가 1번탭인 홈메뉴안에서 여기저기 둘러보고


2,3,4,5 탭메뉴를 열어서 거기서 여기저기 둘러보다가


다시 1번탭을 왔을때 


1번탭은 2,3,4,5번에서 뭘하고 돌아다녔던간에


1번탭의 navigation stack만을 기억하기 때문에


마지막으로 봤던 페이지를 보여주고 상단의 뒤로가기 버튼을 클릭하면 1번탭에서의 뒤로가기 기능이 동작합니다.






근데 사실 이렇게 동작하는 당연한 이유가


아이폰은 back 버튼이라는 글로벌한 뒤로가기 버튼이 없습니다.


그리고 실제 구현에 있어서도 각각의 탭안에 navigation controller를 넣기때문에


각각의 탭의 navigation이 서로를 간섭하지 않습니다.


1번탭을 보고 곧바로 3번탭을 본 뒤에 뒤로가기 버튼을 눌렀을때 3번탭의 이전 뎁스로 이동하지 1번탭으로 이동하지는 않습니다.










반면에 android는 글로벌한 back 버튼이 있고,


하나의 container안에 다른 fragment를 교체하는식인데요.



그래서 아이폰과의 네비게이션 아키텍쳐에 차이가 존재할수밖에 없습니다.





예를 들면


사용자가 1번 탭을 열어서 그 안에서 2번째 뎁스까지 들어갔다가 하단 탭메뉴의 3번탭을 눌러 3번탭을 열었다고 가정해봅시다.


이때 사용자가 뒤로가기 버튼을 누르면 화면은 어디로 이동되어야 해야할까요?



아이폰은 글로벌한 뒤로가기 버튼이 없습니다.


그래서 3번탭을 열었을때 자신이 첫번째 뎁스라면 상단바에 뒤로가기 버튼이 나타나지 않습니다



하지만 안드로이드의 경우


뒤로가기 버튼을 누르게 되면


3번탭을 열기 전에 열었던 1번탭의 2번뎁스화면이 보이게 됩니다.



뒤로가기 버튼이 탭간에 간섭을 하게 되는데요



인스타그램 안드로이드앱은 아이폰의 UX를 유지하고 싶었는지


네비게이션 스택관리를 아이폰처럼 하는데요



내가 현재 보고 있는 탭에 쌓여있는 네비게이션 스택이 있는경우


그 이전 액션이 다른 탭을 보고 있었던것이라도 상관없이 먼저 해당 탭에 있는 스택을 소비합니다.




이처럼 아이폰 인스타그램처럼 동작하는 UI 네비게이션 아키텍쳐를 안드로이드로 만들려면


fragmentmanager관리를 조금 복잡하게 해야했습니다.



근데 Navigation 은 stack관리를 정밀하게 할수 있는 방법이 없어서


이렇게 구현하기가 막막해집니다.



그래서 뒤로가기 UX가 왜 이렇게 되어야 하는가에 대해서 다른 멤버들을 설득해야만 하는 어려움이 존재합니다.


(왜 인스타그램은 그렇게해서...)


글로 문제점이 잘 전달되었을런지 모르겠네요.



2. 이전 스택의 fragment가 다시 보여졌을때 뒤로가기 버튼과 타이틀 텍스트의 프로그램적인 변경이 불가능하다.



다소 좀 어이가 없었던 버그(?)인데요


아니 설마 이게 안될리가 있나? 라는 생각인데 지금도 방법을 찾지 못했습니다.



android toolbar는 뒤로가기 버튼 아이콘과 툴바 타이틀을 커스텀하게 넣을수 있는데요


처음 프래그먼트가 oncreate될때는 이게 적용이 잘되는데


뒤로가기를 통해 해당 fragment가 다시 보여졌을때는


이게 적용이 되지 않더라고요 onresume에 적용했는데도 말이죠!


기본 뒤로가기 버튼아이콘과 navigation graph에서 설정한 label값에서 변경을 하는 방법을 찾을수 없었습니다.



3. Best practice 부족


이제 알파버전이 나온상태라 어떻게 쓰면 좋은지에 대한 사례가 조금 부족합니다.


검색해도 생각보다 관련 결과가 많지가 않습니다.


특히나 애매했던점은 tablet을 고려한 유연한 ui 설계시


기존에는 2개의 프래그먼트를 사용했는데 


navigation ui를 쓸때는 이러한 상황에서는 어떻게 써야하는건지 혼자서 판단을 내리기가 다소 어렵더라고요




이 세가지를 제외하고는 매우 만족스럽게 Navigation의 적용을 마쳤습니다.


1번의 UX는 기획자를 설득해야하는일이


2번의 경우는 뒤로가기 버튼 아이콘이미지에 대해서 기본 아이콘을 사용하되 색상만 변경하는 쪽으로 디자이너를 설득해야했습니다.


3번은 시간이 해결해주겠죠, 구글도 좀 더 관련한 예제를 많이 소개했으면 좋겠습니다.



구현자체는 워낙 심플해서 실제로 개발시간을 크게 단축한점이 무엇보다 와닿는 장점이었습니다.


아직 알바버전이지만 앞으로 더 좋아지겠죠?

728x90
반응형