Skip to content

Commit

Permalink
REFACTOR : 상품 리스트 화면 최적화
Browse files Browse the repository at this point in the history
* 리사이클러 adapter 작업을 viewModel로 옮겼습니다.
  • Loading branch information
minseonglove committed Jun 5, 2022
1 parent 398a7b7 commit e42ed86
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ import kotlinx.coroutines.launch
@AndroidEntryPoint
class ProductListFragment : Fragment() {

private lateinit var productListAdapter: ProductListAdapter

private var _binding: FragmentProductListBinding? = null

private val binding get() = _binding!!
Expand Down Expand Up @@ -53,42 +51,24 @@ class ProductListFragment : Fragment() {
super.onViewCreated(view, savedInstanceState)
initListener()
viewModel.requestProductList(true)
binding.recyclerProductList.addItemDecoration(
DividerItemDecoration(requireContext(), LinearLayout.VERTICAL).apply {
setDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.divider_product_list)!!)
}
)
collectProductList()
}

private fun collectProductList() {
lifecycleScope.launch {
viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.productList.collectLatest {
updateRecyclerView(it)
binding.swipeProductList.isRefreshing = false
viewModel.isLoading.collectLatest {
binding.swipeProductList.isRefreshing = it
}
}
}
}

private fun updateRecyclerView(productList: List<ProductListDto>) {
if (!::productListAdapter.isInitialized) {
productListAdapter = ProductListAdapter(
onClick = { viewModel.clickReadMore() },
isReadMoreVisible = { viewModel.isReadMoreVisible.value }
) {
getString(R.string.productlist_text_price, it)
}.apply {
submitList(productList)
}
val divider = DividerItemDecoration(requireContext(), LinearLayout.VERTICAL).apply {
setDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.divider_product_list)!!)
}
binding.recyclerProductList.apply {
addItemDecoration(divider)
adapter = productListAdapter
}
} else {
productListAdapter.submitList(productList.toList())
}
}

private fun initListener() {
binding.swipeProductList.setOnRefreshListener {
viewModel.requestProductList(true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,22 @@ class ProductListViewModel @Inject constructor(
private val repository: ProductListRepository
) : ViewModel() {

private val _productList = MutableStateFlow(mutableListOf<ProductListDto>())
private val productList = MutableStateFlow(listOf<ProductListDto>())
private val _isLoading = MutableStateFlow(false)
private val _isReadMoreVisible = MutableStateFlow(true)
private val isReadMoreVisible = MutableStateFlow(true)
private val isLastProduct = MutableStateFlow(false)
private val startNumber = MutableStateFlow(-1L)
private val searchWord = MutableStateFlow("")

val isReadMoreVisible: StateFlow<Boolean> get() = _isReadMoreVisible
val productList: StateFlow<List<ProductListDto>> get() = _productList
val isLoading: StateFlow<Boolean> get() = _isLoading

val adapter = ProductListAdapter(
onClick = { clickReadMore() },
isReadMoreVisible = { isReadMoreVisible.value }
) {
"${it}"
}

fun getNextProductList() {
// 이미 로딩 중일 때
// 더보기가 활성화 중일 때
Expand All @@ -48,13 +53,14 @@ class ProductListViewModel @Inject constructor(
setLoadingState(true)
repository.postProductList(searchWord.value, 0, LIST_COUNT, startNumber.value).let {
if (it.isSuccessful) {
val currentList = if (isInitialize) mutableListOf() else _productList.value.toMutableList()
val currentList = if (isInitialize) mutableListOf() else productList.value.toMutableList()
currentList.addAll(it.body()!!)
_productList.emit(currentList)
startNumber.emit(_productList.value[_productList.value.size - 1].productId)
productList.emit(currentList)
startNumber.emit(productList.value[productList.value.size - 1].productId)
adapter.submitList(productList.value.toList())
// 요청한 것 보다 더 적게 받아오면 끝자락이라고 판단
if (it.body()!!.size < LIST_COUNT) {
_isReadMoreVisible.value = false
isReadMoreVisible.value = false
isLastProduct.emit(true)
}
} else {
Expand All @@ -65,8 +71,8 @@ class ProductListViewModel @Inject constructor(
}
}

fun clickReadMore() {
_isReadMoreVisible.value = false
private fun clickReadMore() {
isReadMoreVisible.value = false
getNextProductList()
}

Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/layout/fragment_product_list.xml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
android:id="@+id/recycler_product_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:adapter="@{vm.adapter}"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />

</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
Expand Down
3 changes: 2 additions & 1 deletion app/src/main/res/navigation/nav_graph.xml
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@
<action
android:id="@+id/action_productRegistrationFragment_to_productListFragment"
app:destination="@id/productListFragment"
app:popUpTo="@id/productRegistrationFragment" />
app:popUpTo="@id/productListFragment"
app:launchSingleTop="true" />
</fragment>
<fragment
android:id="@+id/pictureSelectFragment"
Expand Down
1 change: 0 additions & 1 deletion app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
<string name="register_text_password_check_fail">설정한 비밀번호와 다릅니다!</string>
<string name="register_button_signup">가입 완료</string>
<!-- Strings related to ProductList -->
<string name="productlist_text_price">%1$s원</string>
<string name="productlist_load_more">더보기</string>
<!-- Strings related to Bottom Navigation -->
<string name="bottom_home">홈</string>
Expand Down

0 comments on commit e42ed86

Please sign in to comment.