Skip to content

Deivincci/GoodListPlus-Android

Repository files navigation

GoodListPlus

Accessible shopping list app for Android. Designed for elderly users and anyone who values clarity over clutter.

Get it on Google Play

Why this app exists

I built this for my mom. She struggles with most shopping list apps — tiny buttons, cluttered interfaces, ads everywhere, and apps that collect data they don't need. So I made one that does the opposite.

Screenshots

Main screen showing the user's shopping lists
Main screen
Creating a new shopping list
Create list
Viewing a shopping list with its items
View list
Editing items in an existing list
Edit list
Buy mode while shopping
Buy mode
Buy mode tracking real prices
Buy mode (prices)
In-app help and instructions
Help
Purchase history with totals
Purchase history
Sharing a list via messaging apps
Share list

Features

  • Create and manage shopping lists with quantities and prices
  • "Buy mode" that learns real prices as you shop
  • Purchase history with totals
  • Available in 16 languages
  • Dark mode built in
  • Accessibility-first design: large buttons, readable typography, high contrast
  • No personal data collection: only Google AdMob receives standard advertising identifiers (with GDPR consent via UMP)
  • Share lists via WhatsApp, Telegram, email, or any messaging app

Tech stack

  • Language: Kotlin
  • UI: Jetpack Compose with Material 3
  • Architecture: Single-activity, navigation with NavHost
  • Persistence: SharedPreferences (lightweight, app-local)
  • Monetization: Google AdMob with UMP consent (GDPR compliant)
  • Min SDK: 26 (Android 8.0+)
  • Target SDK: 35

Project highlights

  • Migrated from a v1 prototype with a memory leak (AdView instances leaking WebView contexts) to a v2 with proper lifecycle management
  • Security-audited: no telemetry, no tracking, minimal permissions
  • Validated input handling — no crashes from edge cases
  • Code minified and obfuscated with R8 in release builds (~65% size reduction from v1)
  • Full internationalization in 16 languages

Engineering notes

This app went through 8 iterations of polishing before its v2.0 release. A few decisions worth highlighting:

  • Cross-screen consistency: unified design language across all screens (cards, typography, color palette)
  • i18n via universal button asset: instead of using semantic icons (which would multiply asset count by 16 languages), text overlays on a single decorative button image. One asset, sixteen languages.
  • Race condition prevention: an isSaving flag prevents double-tap duplicate creations
  • Persistent price learning: prices update immediately during shopping, even if the purchase is cancelled — the app "learns" real market prices over time

Building from source

The repo is buildable as-is, but signing the release variant requires a few credentials kept outside the project tree.

  1. Clone and open in Android Studio (Hedgehog or newer recommended).
  2. For a debug build: just run. AdMob uses Google's sample/test IDs in debug, so tapping ads is safe.
  3. For a signed release build, copy gradle.properties.template to ~/.gradle/gradle.properties (or %USERPROFILE%\.gradle\gradle.properties on Windows) and fill in your keystore values. Keep the .jks file outside the project.

If signing credentials are missing, the release build will still compile (unsigned) with a warning — useful for CI.

Languages

Arabic, Bengali, Chinese, English, French, German, Hindi, Indonesian, Italian, Japanese, Portuguese, Russian, Spanish, Urdu, Vietnamese, plus the default (English).

Privacy

GoodListPlus does not collect personal data. The only third-party service is Google AdMob, which receives standard advertising identifiers as documented in Google's privacy policy.

Users can manage advertising consent at any time from within the app (GDPR compliant via the UMP SDK).

License

Apache 2.0 — see LICENSE for details.

Contact

For feedback, bug reports, or feature requests: david.system80@gmail.com


Built with care, in the margins of a warehouse worker's life.