스마트폰/안드로이드

인스타그램처럼 fragment를 사용하고 싶을땐 어떻게 하면되죠

나를찾는아이 2017. 11. 7. 19:15
728x90
반응형

세계적인앱 인스타그램은 다음과 같은 UI를 가지고 있습니다.





5개의 하단탭메뉴가 있고 각 탭메뉴를 클릭하면 본문영역이 바뀌죠


그리고 각 탭별로 얼마만큼의 뎁스를 이동했는지에 상관없이


다른 탭을 누르고 다시 돌아와도 해당 탭에서 내가 마지막으로 봤던 화면이 나와요.


그리고 뒤로가기 버튼을 누르면 해당탭에서 내가 이동했던 뎁스 순서대로 되돌아 옵니다.




사실 너무나도 당연한 UX인데요.


iOS에서는 이것을 구현하기가 매우 쉽고, 당연합니다.



하단에 tabbar를 놓고, 탭바의 아이템 갯수만큼 viewcontroller를 만들어서 붙이게 되거든요.


각 탭마다 navigationcontroller를 붙여넣고 viewcontroller를 붙여넣으면 끝입니다.


각 탭별로 별도의 navigationcontroller가 붙어있기 때문에 각 탭에서의 navigation 흐름이 보존되어있습니다.




그런데 안드로이드는 이와같은 UI를 만들기가 어렵습니다.


백버튼이 없고 navigationcontroller의 뒤로가기 버튼을 통해 이동하는 ios와 다르게


안드로이드는 navigationcontroller라는것이 없고 global하게 쓰이는 back버튼이 있거든요.



이번에 인스타그램같은 ui를 안드로이드에서 구현하면서 어떻게 구현하는것이 가장 좋을까 고민을 많이 했습니다.


안드로이드는 fragmentmanager라는것이 framelayout에 붙였던 fragment 인스턴스를 관리하는데요.


그런데 이녀석은 1차원 적으로만 fragment history를 가지고 있어서


여러개의 탭을 가지고 있는 경우에는 각각의 탭의 히스토리를 가지고 있는 2차원이 되어야되는데


그래서 fragmentmanager로는 한게가 있습니다.



여러가지 방법을 사용했는데 그중 가장 낫다고 생각하는 방법을 공유하려고 합니다.



화면은 하단의 tablayout과 본문영역의 framelayout으로 구성을 합니다.


그리고 fragment 교체의 모든것을 담당할 fragmentcontroller를 만듭니다.


사용자가 tab을 눌렀거나, 본문에서 다른 아이템을 클릭해서 다른 뎁스로 들어가는 모든 액션을


이 controller가 처리합니다. 어떻게 이동되었는지 순서를 stack 관리하듯이 관리할꺼거든요.


컨트롤러는 hashmap을 통해서 각탭의 fragment 의 stack을 관리합니다.



hashmap에서 사용자의 발자취에 따른 fragment의 흐름에 대한 스택을 관리하고 있으므로, 


사용자 액션이 발생하면 해당탭에서 보여져야할 fragment가 뭔지 파악하고


이를 fragmentmanager에게 알려주어


fragmentmanager가 현재 사용자에게 보여지고 있는 fragment를 detach하고 


보여져야할 fragment를 fragmentmanager가 가지고 있는 fragment들 중에서 찾아서 attach합니다.



fragmentmanager가 가지고 있지 않은 fragment라면 추가해서 attach 하고요.



1번탭에서도 C화면을 볼수 있고


3번탭에서도 C화면을 볼수 있는 경우가 있기 때문에 fragment는 항상 유니크한 태그를 붙여서 관리합니다.



그림으로도 나름 열심히 그려보았는데 설명이 잘 되었는지 모르겠네요.




근데 사실 이렇게 만든구조도 그렇게 썩 마음에 들지는 않습니다.


실제 인스타그램이랑 비교했을때 뭔가 더 어색한것 같은 느낌이 드는건 사실입니다.


더 좋은 구조 찾으시는분 있으시면 알려주시면 감사하겠습니다.




샘플 소스코드는


https://github.com/spotlight21c/FragmentNavigation



깃헙에 올려두었습니다.



참고 : https://github.com/f22labs/InstaLikeFragmentTransaction

728x90
반응형