diff --git a/app/src/main/res/layout/activity_detail.xml b/app/src/main/res/layout/activity_detail.xml
index 67a7c37e5..bdb6bafac 100644
--- a/app/src/main/res/layout/activity_detail.xml
+++ b/app/src/main/res/layout/activity_detail.xml
@@ -16,6 +16,7 @@
-->
@@ -190,173 +191,26 @@
app:layout_constraintStart_toEndOf="@id/weight"
app:layout_constraintTop_toBottomOf="@id/height" />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ app:barrierDirection="bottom"
+ app:constraint_referenced_ids="weight_title,height_title" />
+
+
+
+
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/stats_layout.xml b/app/src/main/res/layout/stats_layout.xml
new file mode 100644
index 000000000..b0683dc34
--- /dev/null
+++ b/app/src/main/res/layout/stats_layout.xml
@@ -0,0 +1,195 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/core-database/schemas/com.skydoves.pokedex.core.database.PokedexDatabase/3.json b/core-database/schemas/com.skydoves.pokedex.core.database.PokedexDatabase/3.json
new file mode 100644
index 000000000..bbfe17f2d
--- /dev/null
+++ b/core-database/schemas/com.skydoves.pokedex.core.database.PokedexDatabase/3.json
@@ -0,0 +1,132 @@
+{
+ "formatVersion": 1,
+ "database": {
+ "version": 3,
+ "identityHash": "cc488f72b5ee2f40a7376fb08cb8c85d",
+ "entities": [
+ {
+ "tableName": "PokemonEntity",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`page` INTEGER NOT NULL, `name` TEXT NOT NULL, `url` TEXT NOT NULL, PRIMARY KEY(`name`))",
+ "fields": [
+ {
+ "fieldPath": "page",
+ "columnName": "page",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "name",
+ "columnName": "name",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "url",
+ "columnName": "url",
+ "affinity": "TEXT",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "autoGenerate": false,
+ "columnNames": [
+ "name"
+ ]
+ },
+ "indices": [],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "PokemonInfoEntity",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `name` TEXT NOT NULL, `height` INTEGER NOT NULL, `weight` INTEGER NOT NULL, `experience` INTEGER NOT NULL, `types` TEXT NOT NULL, `hp` INTEGER NOT NULL, `attack` INTEGER NOT NULL, `defense` INTEGER NOT NULL, `speed` INTEGER NOT NULL, `exp` INTEGER NOT NULL, `stats` TEXT NOT NULL, PRIMARY KEY(`id`))",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "name",
+ "columnName": "name",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "height",
+ "columnName": "height",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "weight",
+ "columnName": "weight",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "experience",
+ "columnName": "experience",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "types",
+ "columnName": "types",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "hp",
+ "columnName": "hp",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "attack",
+ "columnName": "attack",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "defense",
+ "columnName": "defense",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "speed",
+ "columnName": "speed",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "exp",
+ "columnName": "exp",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "stats",
+ "columnName": "stats",
+ "affinity": "TEXT",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "autoGenerate": false,
+ "columnNames": [
+ "id"
+ ]
+ },
+ "indices": [],
+ "foreignKeys": []
+ }
+ ],
+ "views": [],
+ "setupQueries": [
+ "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
+ "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'cc488f72b5ee2f40a7376fb08cb8c85d')"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/core-database/src/main/kotlin/com/skydoves/pokedex/core/database/PokedexDatabase.kt b/core-database/src/main/kotlin/com/skydoves/pokedex/core/database/PokedexDatabase.kt
index e33460eec..3aebbd675 100644
--- a/core-database/src/main/kotlin/com/skydoves/pokedex/core/database/PokedexDatabase.kt
+++ b/core-database/src/main/kotlin/com/skydoves/pokedex/core/database/PokedexDatabase.kt
@@ -24,10 +24,10 @@ import com.skydoves.pokedex.core.database.entitiy.PokemonInfoEntity
@Database(
entities = [PokemonEntity::class, PokemonInfoEntity::class],
- version = 2,
+ version = 3,
exportSchema = true,
)
-@TypeConverters(value = [TypeResponseConverter::class])
+@TypeConverters(value = [TypeResponseConverter::class, StatsResponseConverter::class])
abstract class PokedexDatabase : RoomDatabase() {
abstract fun pokemonDao(): PokemonDao
diff --git a/core-database/src/main/kotlin/com/skydoves/pokedex/core/database/StatsResponseConverter.kt b/core-database/src/main/kotlin/com/skydoves/pokedex/core/database/StatsResponseConverter.kt
new file mode 100644
index 000000000..bccf587f2
--- /dev/null
+++ b/core-database/src/main/kotlin/com/skydoves/pokedex/core/database/StatsResponseConverter.kt
@@ -0,0 +1,47 @@
+/*
+ * Designed and developed by 2022 skydoves (Jaewoong Eum)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.skydoves.pokedex.core.database
+
+import androidx.room.ProvidedTypeConverter
+import androidx.room.TypeConverter
+import com.skydoves.pokedex.core.model.PokemonInfo
+import com.squareup.moshi.JsonAdapter
+import com.squareup.moshi.Moshi
+import com.squareup.moshi.Types
+import javax.inject.Inject
+
+@ProvidedTypeConverter
+class StatsResponseConverter @Inject constructor(
+ private val moshi: Moshi,
+) {
+
+ @TypeConverter
+ fun fromString(value: String): List? {
+ val listType =
+ Types.newParameterizedType(List::class.java, PokemonInfo.StatsResponse::class.java)
+ val adapter: JsonAdapter> = moshi.adapter(listType)
+ return adapter.fromJson(value)
+ }
+
+ @TypeConverter
+ fun fromInfoType(type: List?): String {
+ val listType =
+ Types.newParameterizedType(List::class.java, PokemonInfo.StatsResponse::class.java)
+ val adapter: JsonAdapter> = moshi.adapter(listType)
+ return adapter.toJson(type)
+ }
+}
diff --git a/core-database/src/main/kotlin/com/skydoves/pokedex/core/database/di/DatabaseModule.kt b/core-database/src/main/kotlin/com/skydoves/pokedex/core/database/di/DatabaseModule.kt
index a25e5e8ba..2987282e7 100644
--- a/core-database/src/main/kotlin/com/skydoves/pokedex/core/database/di/DatabaseModule.kt
+++ b/core-database/src/main/kotlin/com/skydoves/pokedex/core/database/di/DatabaseModule.kt
@@ -21,6 +21,7 @@ import androidx.room.Room
import com.skydoves.pokedex.core.database.PokedexDatabase
import com.skydoves.pokedex.core.database.PokemonDao
import com.skydoves.pokedex.core.database.PokemonInfoDao
+import com.skydoves.pokedex.core.database.StatsResponseConverter
import com.skydoves.pokedex.core.database.TypeResponseConverter
import com.squareup.moshi.Moshi
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
@@ -47,11 +48,13 @@ internal object DatabaseModule {
fun provideAppDatabase(
application: Application,
typeResponseConverter: TypeResponseConverter,
+ statsResponseConverter: StatsResponseConverter,
): PokedexDatabase {
return Room
.databaseBuilder(application, PokedexDatabase::class.java, "Pokedex.db")
.fallbackToDestructiveMigration()
.addTypeConverter(typeResponseConverter)
+ .addTypeConverter(statsResponseConverter)
.build()
}
@@ -72,4 +75,10 @@ internal object DatabaseModule {
fun provideTypeResponseConverter(moshi: Moshi): TypeResponseConverter {
return TypeResponseConverter(moshi)
}
+
+ @Provides
+ @Singleton
+ fun provideStatsResponseConverter(moshi: Moshi): StatsResponseConverter {
+ return StatsResponseConverter(moshi)
+ }
}
diff --git a/core-database/src/main/kotlin/com/skydoves/pokedex/core/database/entitiy/PokemonInfoEntity.kt b/core-database/src/main/kotlin/com/skydoves/pokedex/core/database/entitiy/PokemonInfoEntity.kt
index e3f86edd0..0cb998b14 100644
--- a/core-database/src/main/kotlin/com/skydoves/pokedex/core/database/entitiy/PokemonInfoEntity.kt
+++ b/core-database/src/main/kotlin/com/skydoves/pokedex/core/database/entitiy/PokemonInfoEntity.kt
@@ -33,4 +33,5 @@ data class PokemonInfoEntity(
val defense: Int,
val speed: Int,
val exp: Int,
+ val stats: List,
)
diff --git a/core-database/src/main/kotlin/com/skydoves/pokedex/core/database/entitiy/mapper/PokemonInfoEntityMapper.kt b/core-database/src/main/kotlin/com/skydoves/pokedex/core/database/entitiy/mapper/PokemonInfoEntityMapper.kt
index f63217ca5..5421915e1 100644
--- a/core-database/src/main/kotlin/com/skydoves/pokedex/core/database/entitiy/mapper/PokemonInfoEntityMapper.kt
+++ b/core-database/src/main/kotlin/com/skydoves/pokedex/core/database/entitiy/mapper/PokemonInfoEntityMapper.kt
@@ -34,6 +34,7 @@ object PokemonInfoEntityMapper : EntityMapper {
defense = domain.defense,
speed = domain.speed,
exp = domain.exp,
+ stats = domain.stats,
)
}
@@ -50,6 +51,7 @@ object PokemonInfoEntityMapper : EntityMapper {
defense = entity.defense,
speed = entity.speed,
exp = entity.exp,
+ stats = entity.stats,
)
}
}
diff --git a/core-model/src/main/kotlin/com/skydoves/pokedex/core/model/PokemonInfo.kt b/core-model/src/main/kotlin/com/skydoves/pokedex/core/model/PokemonInfo.kt
index 6532f43f2..6b67446fd 100644
--- a/core-model/src/main/kotlin/com/skydoves/pokedex/core/model/PokemonInfo.kt
+++ b/core-model/src/main/kotlin/com/skydoves/pokedex/core/model/PokemonInfo.kt
@@ -29,6 +29,7 @@ data class PokemonInfo(
@field:Json(name = "weight") val weight: Int,
@field:Json(name = "base_experience") val experience: Int,
@field:Json(name = "types") val types: List,
+ @field:Json(name = "stats") val stats: List,
val hp: Int = Random.nextInt(MAX_HP),
val attack: Int = Random.nextInt(MAX_ATTACK),
val defense: Int = Random.nextInt(MAX_DEFENSE),
@@ -56,6 +57,18 @@ data class PokemonInfo(
@field:Json(name = "name") val name: String,
)
+ @JsonClass(generateAdapter = true)
+ data class StatsResponse(
+ @field:Json(name = "base_stat") val baseStat: Int,
+ @field:Json(name = "effort") val effort: Int,
+ @field:Json(name = "stat") val stat: Stat,
+ )
+
+ @JsonClass(generateAdapter = true)
+ data class Stat(
+ @field:Json(name = "name") val name: String,
+ )
+
companion object {
const val MAX_HP = 300
const val MAX_ATTACK = 300