The Thesis & The Problem
Financial literacy is a critical life skill, yet traditional banking apps and educational curricula fail to engage young minds. Abstract concepts like compound interest, inflation, stock market volatility, and debt metrics are dry and hard for adolescents to conceptualize in a meaningful way.
LearnLoop was built to address this gap: a gamified, localized fintech portal. Built natively for Android using Kotlin and Jetpack Compose, LearnLoop guides users through interactive mini-quests, sandbox investing markets, and automated pocket money allocation vaults, converting dry theories into delightful, tactile loops.
Localized Singapore Context: To maximize real-world applicability, LearnLoop utilizes realistic localized scenarios: budgeting for school lunches at typical hawker centers, parsing CPF (Central Provident Fund) contribution schemas, and calculating compound interest models matching Singapore's post-office savings bank (POSB) savings rates.
Design Thinking: Engaging & Energetic UX
Prototyping a financial app that captures youth attention:
- Gamified Quest Modules: Financial lessons are structured as interactive multi-stage quests. Users receive virtual coins upon completing mini-quizzes, which can be spent inside a built-in sandbox mock investment game.
- SQLite Transaction Ledgers: All transaction records, mock investment portfolios, and logged quest progress are cached locally on-device using Android's native SQLite/Room databases, allowing offline access during transit.
- Dynamic Compose UI: Leveraged Android Jetpack Compose's state-driven framework to build responsive, micro-animated sliders, colorful progression progress bars, and custom card overlays.
On-Device Database Model (SQLite Room Schema)
Below is a code model representing our database structure, mapping virtual transactions and user progress logs in SQLite:
package com.learnloop.data
import androidx.room.Entity
import androidx.room.PrimaryKey
import androidx.room.ForeignKey
@Entity(tableName = "users")
data class YouthUser(
@PrimaryKey(autoGenerate = true) val userId: Long = 0,
val username: String,
val virtualBalanceCoins: Int = 100,
val currentQuestLevel: Int = 1
)
@Entity(
tableName = "virtual_transactions",
foreignKeys = [ForeignKey(
entity = YouthUser::class,
parentColumns = ["userId"],
childColumns = ["userRefId"],
onDelete = ForeignKey.CASCADE
)]
)
data class VirtualTransaction(
@PrimaryKey(autoGenerate = true) val transactionId: Long = 0,
val userRefId: Long,
val transactionType: String, -- 'quest_reward' | 'sandbox_buy' | 'sandbox_sell'
val amountCoins: Int,
val timestampMs: Long = System.currentTimeMillis()
)
Technical Achievements
- Offline-First Synchronization: Leveraged Room and Flow architectures, ensuring that balance counts and investment values update concurrently across multiple fragments without blocking thread queues.
- Simulated Sandboxed Market: Developed a basic simulated currency market that updates mock stock assets using randomized walk mathematical algorithms, giving users a safe environment to experience market volatility.
- Dynamic Light/Dark Themes: Followed standard Material 3 dynamic styling guidelines, matching the device's system theme seamlessly to maximize user visual comfort.