Skip to content

Commit

Permalink
[1.1.0.alpha/AN_FEAT, AN_UI] 도감 상세 UI 수정, 바이옴에서의 포켓몬 타입 가져오기 (#308)
Browse files Browse the repository at this point in the history
* feat(PokemonBiomeUiModel): 포켓몬 바이옴 리스트와 모든 바이옴 정보를 통해 ui 모델로

* refactor(PokemonBiomeUiModel): 포켓몬 바이옴 리스트와 모든 바이옴 정보를 통해 ui 모델로

* feat(PokemonDetailUiState2): PokemonUiModel 을 가진다

* refactor(PokemonDetailViewModel): 바이옴 레포지토리를 추가로 가진다

* feat(PokemonDetailSkillFragment): PokemonDetailUiState2 에 대한 함수 추가

* feat(PokemonEvolutionFragment): PokemonDetailUiState2 에 대한 함수 추가

* feat(PokemonInformationFragment): PokemonDetailUiState2 에 대한 함수 추가

* feat(PokemonStatFragment): PokemonDetailUiState2 에 대한 함수 추가

* feat(PokemonDetailBiomeAdapter): PokemonDetailUiState2 에 대한 함수 추가

* refactor(PokemonDetailActivity): PokemonDetailUiState 에 대한 참조 제거

* refactor(PokemonEvolutionFragment): PokemonDetailUiState 에 대한 참조 제거

* refactor(PokemonInformationFragment): PokemonDetailUiState 에 대한 참조 제거

* refactor(PokemonDetailSkillFragment): PokemonDetailUiState 에 대한 참조 제거

* refactor(PokemonStatFragment): PokemonDetailUiState 에 대한 참조 제거

* refactor(PokemonDetailUiState.kt): PokemonDetailUiState2 -> PokemonDetailUiState

* test(PokemonDetailViewModelTest): 포켓모 상세에서 바이옴 정보

* ui(PokemonDetailBiomeTypesAdapter): 바이옴의 타입 정보 추가

* ui(PokemonDetailBiomeViewHolder): 바이옴의 타입 정보 추가

* feat(PokemonInformationFragment.kt): 체중, 키를 서버로부터 로드한 데이터 보여준다

* feat(PokemonBiome): 바이옴에서 출연하는 포켓몬 타입 프로퍼티 추가

* feat(DefaultDexRepository): 바이옴 레포지토리 생성자 추가

* feat(PokemonBiomeUiModel): PokemonBiome 에서 ui 모델로 매핑

* refactor(PokemonBiomeUiModel): 포켓몬 뷰모델은 이전처럼 dex repository 하나만 갖는다

* refactor(PokemonBiomeUiModel): ui 모델로 매핑할 때 다른 파라미터를 갖지 않는다

* test(PokemonDetailViewModelTest): 포켓몬 상세 로드

* chore: ktlint

* refactor(DefaultDexRepository): 포켓몬 상세 로직 가독성 개선
  • Loading branch information
sh1mj1 authored Sep 9, 2024
1 parent 31fde9a commit 9b80faa
Show file tree
Hide file tree
Showing 16 changed files with 219 additions and 74 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package poke.rogue.helper.presentation.dex.detail

import poke.rogue.helper.data.model.PokemonBiome
import poke.rogue.helper.data.model.Biome
import poke.rogue.helper.data.model.PokemonDetail
import poke.rogue.helper.data.model.PokemonDetailSkills
import poke.rogue.helper.data.model.Stat
import poke.rogue.helper.presentation.dex.model.EvolutionsUiModel
import poke.rogue.helper.presentation.dex.model.PokemonBiomeUiModel
import poke.rogue.helper.presentation.dex.model.PokemonDetailAbilityUiModel
import poke.rogue.helper.presentation.dex.model.PokemonUiModel
import poke.rogue.helper.presentation.dex.model.StatUiModel
Expand All @@ -20,12 +21,24 @@ sealed interface PokemonDetailUiState {
val skills: PokemonDetailSkills,
val height: Float,
val weight: Float,
val biomes: List<PokemonBiome>,
val biomes: List<PokemonBiomeUiModel>,
) : PokemonDetailUiState

data object IsLoading : PokemonDetailUiState
}

fun PokemonDetail.toUi(allBiomes: List<Biome>): PokemonDetailUiState.Success =
PokemonDetailUiState.Success(
pokemon = pokemon.toUi(),
stats = stats.map(Stat::toUi),
abilities = abilities.toPokemonDetailUi(),
evolutions = evolutions.toUi(),
skills = skills,
height = height.toFloat(),
weight = weight.toFloat(),
biomes = biomes.toUi(),
)

fun PokemonDetail.toUi(): PokemonDetailUiState.Success =
PokemonDetailUiState.Success(
pokemon = pokemon.toUi(),
Expand All @@ -35,5 +48,5 @@ fun PokemonDetail.toUi(): PokemonDetailUiState.Success =
skills = skills,
height = height.toFloat(),
weight = weight.toFloat(),
biomes = biomes,
biomes = biomes.toUi(),
)
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@ class PokemonDetailViewModel(
) :
ErrorHandleViewModel(logger),
PokemonDetailNavigateHandler {
private val _uiState: MutableStateFlow<PokemonDetailUiState> =
MutableStateFlow(PokemonDetailUiState.IsLoading)
private val _uiState: MutableStateFlow<PokemonDetailUiState> = MutableStateFlow(PokemonDetailUiState.IsLoading)
val uiState = _uiState.asStateFlow()

val isEmpty: StateFlow<Boolean> =
Expand All @@ -44,7 +43,7 @@ class PokemonDetailViewModel(
private val _navigateToPokemonDetailEvent = MutableSharedFlow<String>()
val navigateToPokemonDetailEvent = _navigateToPokemonDetailEvent.asSharedFlow()

fun updatePokemonDetail(pokemonId: String) {
fun updatePokemonDetail(pokemonId: String?) {
requireNotNull(pokemonId) { "Pokemon ID must not be null" }
viewModelScope.launch {
_uiState.value = dexRepository.pokemonDetail(pokemonId).toUi()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ package poke.rogue.helper.presentation.dex.detail.information
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.ListAdapter
import poke.rogue.helper.data.model.PokemonBiome
import poke.rogue.helper.databinding.ItemPokemonDetailInformationBiomeBinding
import poke.rogue.helper.presentation.dex.detail.PokemonDetailNavigateHandler
import poke.rogue.helper.presentation.dex.model.PokemonBiomeUiModel
import poke.rogue.helper.presentation.util.view.ItemDiffCallback

class PokemonDetailBiomeAdapter(
private val onClickBiomeItem: PokemonDetailNavigateHandler,
) : ListAdapter<PokemonBiome, PokemonDetailBiomeViewHolder>(biomeComparator) {
) : ListAdapter<PokemonBiomeUiModel, PokemonDetailBiomeViewHolder>(biomeComparator) {
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int,
Expand All @@ -34,7 +34,7 @@ class PokemonDetailBiomeAdapter(

companion object {
val biomeComparator =
ItemDiffCallback<PokemonBiome>(
ItemDiffCallback<PokemonBiomeUiModel>(
onItemsTheSame = { oldItem, newItem -> oldItem.id == newItem.id },
onContentsTheSame = { oldItem, newItem -> oldItem == newItem },
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package poke.rogue.helper.presentation.dex.detail.information

import android.content.Context
import android.widget.ImageView
import com.google.android.flexbox.FlexboxLayout
import poke.rogue.helper.presentation.type.model.TypeUiModel
import poke.rogue.helper.presentation.util.view.dp

class PokemonDetailBiomeTypesAdapter(private val context: Context, private val viewGroup: FlexboxLayout) {
fun addTypes(
types: List<TypeUiModel>,
spacingBetweenTypes: Int = 0.dp,
iconSize: Int = 18.dp,
) {
viewGroup.removeAllViews()

types.forEach { type ->
val imageView =
ImageView(context).apply {
setImageResource(type.typeIconResId)

layoutParams =
FlexboxLayout.LayoutParams(
iconSize,
iconSize,
).apply {
setMargins(
spacingBetweenTypes,
0,
0,
0,
)
}
}

viewGroup.addView(imageView)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,36 @@
package poke.rogue.helper.presentation.dex.detail.information

import androidx.recyclerview.widget.RecyclerView
import poke.rogue.helper.data.model.PokemonBiome
import poke.rogue.helper.databinding.ItemPokemonDetailInformationBiomeBinding
import poke.rogue.helper.presentation.dex.detail.PokemonDetailNavigateHandler
import poke.rogue.helper.presentation.dex.model.PokemonBiomeUiModel
import poke.rogue.helper.presentation.util.view.dp

class PokemonDetailBiomeViewHolder(
private val binding: ItemPokemonDetailInformationBiomeBinding,
private val onClickBiomeItem: PokemonDetailNavigateHandler,
) : RecyclerView.ViewHolder(binding.root) {
fun bind(biome: PokemonBiome) {
fun bind(biome: PokemonBiomeUiModel) {
binding.apply {
this.biome = biome
uiEventHandler = onClickBiomeItem
}

val typesLayout = binding.flBiomeTypeIcons
val biomeTypesAdapter =
PokemonDetailBiomeTypesAdapter(
context = binding.root.context,
viewGroup = typesLayout,
)
biomeTypesAdapter.addTypes(
types = biome.types,
spacingBetweenTypes = TYPES_SPACING,
iconSize = TYPE_ICON_SIZE,
)
}

companion object {
private val TYPES_SPACING = 5.dp
private val TYPE_ICON_SIZE = 18.dp
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,20 @@ class PokemonInformationFragment :
activityViewModel.uiState.collect { pokemonDetailUiState ->
when (pokemonDetailUiState) {
is PokemonDetailUiState.IsLoading -> {}
is PokemonDetailUiState.Success -> biomesAdapter.submitList(pokemonDetailUiState.biomes)
is PokemonDetailUiState.Success -> bindPokemonInformation(pokemonDetailUiState)
}
}
}
}

private fun bindPokemonInformation(pokemonDetail: PokemonDetailUiState.Success) {
binding.apply {
height = pokemonDetail.height
weight = pokemonDetail.weight
}
biomesAdapter.submitList(pokemonDetail.biomes)
}

override fun onResume() {
super.onResume()
binding.root.requestLayout()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,6 @@ class PokemonDetailSkillFragment : BindingFragment<FragmentPokemonSkillsBinding>
activityViewModel.uiState.collect { state ->
when (state) {
is PokemonDetailUiState.IsLoading -> {}
// TODO: skill 을 현재는 한 종류의 스킬 목록만 사용하고 있음..... 이후에는 여러개의 스킬을 받아야함
is PokemonDetailUiState.Success -> {
eggSkillsAdapter.submitList(state.skills.eggLearn.toUi())
skillsAdapter.submitList(state.skills.selfLearn.toUi())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class PokemonStatFragment : BindingFragment<FragmentPokemonStatBinding>(R.layout
activityViewModel.uiState.collect { uiState ->
when (uiState) {
is PokemonDetailUiState.IsLoading -> return@collect
is PokemonDetailUiState.Success -> bindDatas(uiState)
is PokemonDetailUiState.Success -> bindData(uiState)
}
}
}
Expand All @@ -64,7 +64,7 @@ class PokemonStatFragment : BindingFragment<FragmentPokemonStatBinding>(R.layout
}
}

private fun bindDatas(uiState: PokemonDetailUiState.Success) {
private fun bindData(uiState: PokemonDetailUiState.Success) {
binding.apply {
pokemonStatAdapter.submitList(uiState.stats)
abilityAdapter.submitList(uiState.abilities)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package poke.rogue.helper.presentation.dex.model

import poke.rogue.helper.data.model.PokemonBiome
import poke.rogue.helper.presentation.type.model.TypeUiModel
import poke.rogue.helper.presentation.type.model.toUi

data class PokemonBiomeUiModel(
val id: String,
val name: String,
val imageUrl: String,
val types: List<TypeUiModel>,
)

fun PokemonBiome.toUi(): PokemonBiomeUiModel =
PokemonBiomeUiModel(
id = id,
name = name,
imageUrl = imageUrl,
types = pokemonType.toUi(),
)

fun List<PokemonBiome>.toUi(): List<PokemonBiomeUiModel> = this.map(PokemonBiome::toUi)
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@
android:id="@+id/layout_pokemon_detail_pokemon_types"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:gravity="start"
android:orientation="vertical"
app:layout_constraintStart_toStartOf="@id/tv_pokemon_detail_pokemon_name"
app:layout_constraintTop_toBottomOf="@id/tv_pokemon_detail_pokemon_name"
Expand Down
26 changes: 18 additions & 8 deletions android/app/src/main/res/layout/fragment_pokemon_information.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,17 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">

<data>

<variable
name="height"
type="Float" />

<variable
name="weight"
type="Float" />
</data>

<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
Expand All @@ -25,7 +36,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/pokemon_detail_information_weight"
android:text="@string/pokemon_detail_information_weight_title"
android:textSize="16sp"
app:layout_constraintEnd_toStartOf="@id/divider_pokemon_detail_information_weight_height"
app:layout_constraintStart_toStartOf="parent"
Expand All @@ -36,11 +47,12 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="6.9kg"
android:text="@{String.format(@string/pokemon_detail_information_weight, weight)}"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="@id/tv_pokemon_detail_information_weight_title"
app:layout_constraintStart_toStartOf="@id/tv_pokemon_detail_information_weight_title"
app:layout_constraintTop_toBottomOf="@id/tv_pokemon_detail_information_weight_title" />
app:layout_constraintTop_toBottomOf="@id/tv_pokemon_detail_information_weight_title"
tools:text="6.9 kg" />

<View
android:id="@+id/divider_pokemon_detail_information_weight_height"
Expand All @@ -58,7 +70,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/pokemon_detail_information_height"
android:text="@string/pokemon_detail_information_height_title"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/divider_pokemon_detail_information_weight_height"
Expand All @@ -69,14 +81,12 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="0.8m"
android:text="@{String.format(@string/pokemon_detail_information_height, height)}"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="@id/tv_pokemon_detail_information_height_title"
app:layout_constraintStart_toStartOf="@id/tv_pokemon_detail_information_height_title"
app:layout_constraintTop_toTopOf="@id/tv_pokemon_detail_information_weight_value"
tools:text="0.8m" />

/>
</androidx.constraintlayout.widget.ConstraintLayout>

<TextView
Expand All @@ -85,7 +95,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="바이옴"
android:text="@string/pokemon_detail_biome_title"
android:textSize="24sp"
app:layout_constraintBottom_toTopOf="@id/divider_pokemon_detail_information_biome"
app:layout_constraintStart_toStartOf="@id/cl_pokemon_detail_information_weight_height"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,42 +7,49 @@

<variable
name="biome"
type="poke.rogue.helper.data.model.PokemonBiome" />
type="poke.rogue.helper.presentation.dex.model.PokemonBiomeUiModel" />

<variable
name="uiEventHandler"
type="poke.rogue.helper.presentation.dex.detail.PokemonDetailNavigateHandler" />
</data>

<androidx.constraintlayout.widget.ConstraintLayout
onSingleClick="@{()->uiEventHandler.navigateToBiomeDetail(String.valueOf(biome.id))}"
android:layout_width="match_parent"
onSingleClick="@{()->uiEventHandler.navigateToBiomeDetail(biome.id)}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/shape_pokemon_corner_radius">
android:background="@drawable/shape_pokemon_corner_radius"
android:padding="10dp">

<TextView
android:id="@+id/tv_pokemon_detail_information_biome_name"
android:id="@+id/tv_biome_name"
style="@style/TextAppearance.Poke.TitleLargeBold"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="4dp"
android:text="@{biome.name}"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="화산" />

<com.google.android.flexbox.FlexboxLayout
android:id="@+id/fl_biome_type_icons"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:flexDirection="row"
app:layout_constraintBottom_toBottomOf="@id/tv_biome_name"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/tv_biome_name" />

<ImageView
android:id="@+id/iv_pokemon_detail_information_biome"
android:id="@+id/iv_biome"
imageUrl="@{biome.imageUrl}"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="4dp"
android:importantForAccessibility="no"
android:padding="4dp"
android:layout_width="200dp"
android:layout_height="100dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_pokemon_detail_information_biome_name"
app:layout_constraintTop_toBottomOf="@id/tv_biome_name"
tools:ignore="ContentDescription"
tools:srcCompat="@tools:sample/avatars" />

</androidx.constraintlayout.widget.ConstraintLayout>
Expand Down
Loading

0 comments on commit 9b80faa

Please sign in to comment.