[팀 프로젝트] 두 번째 코드 리뷰 (1)

HEETAE HEO·2022년 2월 17일
0

TeamProject

목록 보기
3/3
post-thumbnail
post-custom-banner

이번 코드 리뷰의 코드를 작성한 팀원의 Velog입니다.

https://velog.io/@errored_pasta/WIP-Team-박카스-팀-프로젝트-2022.02.08-코드-리뷰

이 글에서는 팀원이 어떤 방법으로 기능을 구현하였는지에 대해 작성을 한 후
다음 글에서는 코드 리뷰를 진행하면서 나왔던 질문들과 답변 및 문제점으로 인한 수정부분에 대해서 작성하겠습니다.

새로운 할인 상품의 정보를 불러와서 사용자에게 출력
근처 마켓 정보를 불러와서 가까운 순으로 사용자에게 출력
카테고리별 버튼을 생성하여 클릭 시 해당 카테고리의 상품들을 출력
처음 화면(HomeMainFragment)과 상품 목록을 보여주는 화면(HomeFragment)의 이동
근처 마켓 정보와 새로운 할인 상품의 정보를 출력할 때 사용할 ViewHolder

HomeMainViewModel

class HomeMainViewModel(
    private val homeRepository: HomeRepository
    // TODO 22.01.18 add item repository
) : BaseViewModel() {

    private val _marketData = MutableLiveData<HomeMainState(HomeMainState.Uninitialized)
##     val marketData: LiveData<HomeMainState> = _marketData

    private val _itemData = MutableLiveData<HomeMainState(HomeMainState.Uninitialized)
    val itemData: LiveData<HomeMainState> = _itemData
    ...
     override fun fetchData(): Job = viewModelScope.launch {
        // get list after get location data
        if (LocationData.locationStateLiveData.value is LocationState.Success) {
            fetchMarketData()
            fetchItemData()
        }
    }
    ...
    }

HomeMainFrament에서 보여줄 근처 마켓의 정보와 새로운 할인상품을 나타낼 LiveData로 marketData 와 itemData를 Backing Property를 이용하여 데이터를 View에서 수정할 수 없도록 작성하였습니다. 처음 선언할 때 보면 Unintialized로 초기 설정을 하였고 HomeMainState의 상태가 Success가 된다면 Model들에서 데이터를 가지고 오게 하였습니다.

fetchMarketData() 와 fetchItemData() 메소드를 살펴보자면

 private suspend fun fetchMarketData() {
        if (marketData.value !is HomeMainState.Success<*>
        ) { _marketData.value = HomeMainState.Loading
            _marketData.value = HomeMainState.Success(
                modelList = homeRepository.getAllMarketList().map {
                    it.copy(type = CellType.HOME_CELL)
                }.sortedBy { it.distance }
            )
        }
    }

fetchMarketData()는 근처의 마켓의 정보를 가지고와 거리가 가까운 순으로 정렬하는 메소드 입니다. if (marketData.value !is HomeMainState.Success<*>) 문을 활용하여 데이터가 Success가 아닐때만 정보를 가지고 오도록하여 불필요한 상황에서 데이터를 계속 불러오는 것을 방지했습니다.

   private suspend fun fetchItemData() {
        if (itemData.value !is HomeMainState.Success<*>
        ) {
            _itemData.value = HomeMainState.Loading

            allNewSaleItemsList = homeRepository.getAllNewSaleItems()
            _itemData.value = HomeMainState.ListLoaded
        }
    }

fetchItemData()는 새로운 할인상품의 데이터를 불러오는 메소드입니다.
위의 fetchMarketData와 마찬가지로 데이터를 Success상태에서만 불러와 불필요한 데이터 요청을 방지했습니다.

Category별 할인상품의 출력

 private lateinit var allNewSaleItemsList: List<HomeItemModel>

   fun setItemFilter(category: HomeListCategory) {
        if (::allNewSaleItemsList.isInitialized) {
            _itemData.value = HomeMainState.Success(
                modelList = allNewSaleItemsList.filter {
                    it.homeListCategory == category
                }
            )
        }
    }

Spinner를 활용하여 새로운 할인상품에서 선택된 카테고리에 맞는 데이터를 불러온다

다음 이미지와 같이 선택할 수 있는 카테고리들이 있고 선택하면 allNewSaleItemsList에서 선택된 category에 맞는 데이터들이 modelList에 저장되고 해당되는 데이터들만 보여지게 된다.

흔히 Fragment의 화면전환은 supportFragmentManager.beginTransaction().replace() 이렇게 작성하여 마지막에 commit()을하여 많이 하였습니다. 하지만 Navigation Component를 사용하면 화면의 전환을 더욱 직관적이며 위의 명령어와 같은 Boilerplate 코드를 줄일 수 가 있습니다.

다음 이미지는 저희 프로젝트에서 작업중인 HomeFragment에 BottomNavigationView가 적용된 모습입니다. 아래 Bar에 보면 홈, 주문목록, 찜, 지도, 내 정보등의 버튼이 존재합니다.

Navigation Component에서 BottomNavigationView에서 사용하기 위해서 Navigation Graph와 BottomNavigationView의 Menu Item들을 일치시켜 주어야합니다.
그 후 Activity/Fragment에서 FragmentContainerView부분을 정해주고 navGraph 및 defaultNavHost을 설정해주고 Android Developers 공식 페이지에서는 NavHostFragment에서 NavController를 직접 가져오라고 적혀 있기에

bottomNav.setupWithNavController(navController)

이와 같이 코드를 작성해줍니다. 연결이 다된 후 다른 View를 누르게 된다면

다음과 같이 내 정보 부분이 보이게 된다.

마치며

NavigationView부분을 조금 더 자세히 작성하려다 보니 글의 내용이 많이 길어질거 같아 따로 Android 개발에 유용한 기능들을 설명하는 글을 작성할 때 해당 기능을 사용할 수 있는 방법에 대해 작성하도록 하겠습니다. 다음 글은 처음 글의 시작에 적혀있던대로 질의 및 수정 사항에 대하여 작성하도록 하겠습니다. 읽어주셔서 감사합니다.

profile
Android 개발 잘하고 싶어요!!!
post-custom-banner

0개의 댓글