본문 바로가기

안드로이드/안드로이드 디버깅

[디버깅] 게시판에서 특정 게시글을 보고 다시 게시판으로 돌아올 때 보던 위치로 돌아오기

개요

현재 개발 중인 앱에 게시판 기능이 존재하고 게시판의 목록 중 특정 게시글을 선택하면 해당 게시글에 대한 자세한 정보를 노출한다.

 

위 앱은 AAC의 네비게이션 컴포넌트를 기반으로 작성되어 있다. 

[안드로이드] 프래그먼트 스택 (feat. 네비게이션) (tistory.com)

 

기존 위 포스팅에서 네비게이션 컴포넌트에서 스택 관리를 위해 게시판으로 돌아가는 GlobalAction의 popUpTo를 활용하여 특정 게시글에서 게시판으로 되돌아갈 때 특정 게시글 프래그먼트를 스택에서 제거하는 방법으로 구현했다.

 

위 구현의 문제점은 action을 통해 진입하면 프래그먼트를 새로 그리는 것으로 보인다. 다시 말하면, 특정 게시글을 보고 게시판으로 돌아갈 때 게시판의 내용이 전부 리로드된다. 이는 필요없는 작업이고,  사용자는 40번 포지션 아이템까지 스크롤하여 아이템을 봤지만 다시 1번 포지션부터 보이므로 굉장히 불편하다고 느낄 것이다. 결론은 네비게이션에서 action을 사용하여 이동하면 스택에 해당 프래그먼트가 존재하더라도 해당 프래그먼트를 새로 그린다는 점이다.

 

 

위를 해결하기 위한 첫번째 접근 법 - 실패

클릭한 아이템의 번호를 기억하고 있다가, 게시판으로 돌아오면 리사이클러뷰의 scrollToPosition을 통해 해당 위치로 이동하는 방법을 고안했다. 하지만, 이 방법에서도 문제가 존재했다.

현재 페이징 라이브러리를 활용하여 20개씩 아이템을 로드하는데 만약 24번째 아이템을 보다가 게시판으로 돌아갔을 경우 리사이클러뷰는 리로드 되어 있는 상태라 1~20까지의 아이템이 존재하고, 24번으로는 이동할 수 없다. 이를 깊게 파서 해결하기란 매우 복잡해 보인다. 따라서, 원점으로 돌아가 스택 관리 방법을 다시 생각했다.

'

 

성공적인 접근법 1 - onBackPressed()

action을 통해 이동하면 프래그먼트를 새로 그리게 된다. 따라서, 뒤로가기 클릭시 activity의 onBackPressed()를 호출하여 프래그먼트를 다시 그리지 않게 되고, 사용자가 읽었던 위치까지 그대로 존재하게 된다. 이는 매우 간단한 솔루션이지만 네비게이션의 action이 프래그먼트를 새로 그린다는 개념을 몰라서 발생한 문제라고 생각한다.

다만 위 과정은 특정 게시글에서 댓글이 작성되거나 좋아요가 클릭되는 등 댓글 수, 좋아요 수가 반영이 바로 되지 않는다. 이는 프래그먼트를 새로 그리는게 아니기 때문에 당연하다. 따라서 이를 처리하는 별도의 작업이 필요하다. 프래그먼트의 onCreate()는 스택에서 되돌아 올 때 호출되지 않는다는 점에 유의.

 

성공적인 접근법 2 - navController.popBackStack('이동할 레이아웃 id', false)

navController.popBackStack('이동할 레이아웃 id', false) 메서드를 활용하면 네비게이션 컨트롤러의 백스택에서 해당 레이아웃이 존재하면 해당 레이아웃으로 이동하고 true를 반환한다. 백스택에 없다면 action을 통한 이동을 수행한다.

private fun goToCenterSearchFragment() = run{
        if(findNavController().popBackStack(R.id.centerSearchFragment,false)){
            Log.d(TAG,"centerSearchFragment found in backstack")
        }else{
            Log.d(TAG,"noExist")
            val directions = MapFragmentDirections.actionMapFragmentToCenterSearchFragment()
            findNavController().navigate(directions)
        }
    }