FoodLay - Restaurant Food Delivery App Flutter UI Kit

documentation version 1.0


Introduction

Foodlay UI Kit is a modern, comprehensive, and beautifully designed Flutter UI template specially crafted for food delivery businesses and startups.

This powerful UI kit includes two complete applications in a single package:

  • Customer App — A full-featured food ordering experience for end-users
  • Deliveryman App — A dedicated companion app for delivery partners/riders

Built entirely with Flutter, Foodlay delivers pixel-perfect, responsive, and smooth user interfaces that work flawlessly on both Android and iOS platforms from a single codebase.


Highlights & Basic Overview

  • Clean & modern food delivery design trend
  • 100+ high-quality ready-to-use screens
  • Two fully independent apps (Customer + Deliveryman)
  • Smooth animations and transitions
  • Dark & Light theme support
  • Multi-language supported with RTL
  • Google Map & Firebase integrated
  • Responsive layout — phones, tablets, foldables

Customer App – key features

  • Onboarding, authentication, and profile management.
  • Restaurant and cuisine browsing with search and filtering.
  • Menu and item details with add-to-cart and customization flows.
  • Multiple payment options and promo/discount support.
  • Order history, live order tracking, and notification prompts.

Customer App – basic usage

  • Launch the Customer app and complete onboarding or sign in.
  • Choose your location, browse restaurants, and open a restaurant page.
  • Add desired items to the cart, review quantities, and proceed to checkout.
  • Select address and payment method, then confirm the order.
  • Track the order status until the delivery is completed.

Deliveryman App – key features

  • Real-time order assignment list with detailed task view.
  • Map-based navigation support to restaurant and customer locations.
  • Order status updates (accepted, picked up, on the way, delivered).
  • Earnings, payout summary, and delivery history screens.

Deliveryman App – basic usage

  • Open the Deliveryman app, sign in, and switch to online mode.
  • Review incoming delivery requests and accept suitable orders.
  • Navigate to the restaurant, pick up the order, and update status.
  • Follow the route to the customer, deliver the order, and mark it delivered.
  • At the end of the day, review completed orders and earnings.

Why Choose Foodlay UI Kit?

  • Well-organized code structure & easy to customize
  • Reusable custom widgets & components
  • Detailed documentation & helpful code comments

Whether you're building the next big food delivery platform, creating a local restaurant aggregator, or launching a quick MVP — Foodlay helps you save hundreds of hours of design and frontend development time.

Start building your dream food delivery experience today with Foodlay UI Kit.

Prerequisites for Foodlay UI Kit

Before you begin working with Foodlay UI Kit — the complete Flutter solution containing both the Customer App and Deliveryman App — please ensure your development environment meets the following requirements. This will help you avoid common setup issues and allow you to run, customize, and build the projects smoothly.

What is Flutter?

Flutter is Google's free and open-source UI software development toolkit for crafting high-performance, natively compiled applications for mobile (iOS & Android), web, desktop, and embedded devices — all from a single codebase.

Released in 2017 and reaching full maturity by 2026, Flutter has become one of the most popular cross-platform frameworks thanks to:

  • Hot Reload — see code changes almost instantly.
  • Beautiful, customizable widgets — rich set of Material & Cupertino components.
  • Fast performance — compiles to native ARM code (no JavaScript bridge).
  • Single codebase — write once, deploy everywhere.
  • Strong ecosystem — thousands of packages on pub.dev, excellent tooling & community.

Foodlay UI Kit is built entirely with the latest stable Flutter 3.38.x (as of January 2026), ensuring modern features, optimal performance, and long-term compatibility for your food delivery Customer App and Deliveryman App.

Whether you're a beginner or an experienced developer, Flutter makes it fast and enjoyable to create stunning, responsive user interfaces like the ones included in Foodlay.

Setup Procedure and Required Tools

To work efficiently with Foodlay UI Kit, prepare the following essential tools:

Required

  • Flutter SDK — Version 3.38.6 or newer (stable channel).
  • Dart — Included with Flutter (3.10.7+).
  • Git — For cloning, updating projects, and version control.

Recommended IDE / Editor

The most popular and fully supported options are:

  • Android Studio (2025+ versions, recommended for beginners) — built-in emulators, device manager, Flutter inspector, performance profiling.
  • Visual Studio Code — lightweight & fast, with official Flutter + Dart extensions.
  • IntelliJ IDEA (Ultimate/Community) — excellent Flutter support similar to Android Studio.

Additional Platform Tools

  • Android — Android Studio + Android SDK (API 34+ recommended).
  • iOS (macOS only) — Xcode 16+ + CocoaPods.
  • Web/Desktop (optional) — Chrome and compatible desktop SDKs.

After installation, always validate your setup by running:

flutter doctor

Resolve any reported issues (especially Android licenses, Xcode tools, etc.) before opening the Foodlay project.

Environment compatibility

  • Flutter: 3.38.x (stable) or newer
  • Dart: 3.10.x (included with Flutter)
  • JDK: 17+
  • Android Gradle Plugin: 8.5+; Gradle: 8.9+
  • Xcode: 16+ (macOS)
  • iOS deployment target: 13.0+
  • Android minSdkVersion: 21; targetSdkVersion: 34

Windows - Flutter Setup in Android Studio

Follow these professional steps to get Flutter fully working in Android Studio on Windows:

Install Android Studio
Download the latest version from: https://developer.android.com/studio
Run the installer and follow the wizard (install Android SDK, emulator, etc.).

Download & extract Flutter SDK
Go to https://docs.flutter.dev/install
Download the latest stable ZIP (e.g., flutter_windows_3.38.6-stable.zip)
Extract to a permanent location, e.g.: C:\src\flutter (avoid paths with spaces).

Update system PATH
Search for "Environment Variables" in Windows Search and edit the Path variable under System variables. Add:

C:\src\flutter\bin

Click OK and restart your terminal / PowerShell.

Install Flutter & Dart plugins in Android Studio
In Android Studio: File → Settings → Plugins
Search and install Flutter (this automatically installs Dart), then restart Android Studio when prompted.

Let Android Studio locate Flutter SDK
Go to File → Settings → Languages & Frameworks → Flutter
Set Flutter SDK path to your extraction folder (e.g., C:\src\flutter) and click Apply / OK.

Run Flutter Doctor

flutter doctor
flutter doctor --android-licenses

Create / test a project (optional verification):

flutter create my_test_app
cd my_test_app
flutter run

You're now ready to open and run Foodlay projects on Windows!

macOS - Flutter Setup in Android Studio

macOS setup is streamlined and perfect for iOS + Android development:

Install Android Studio
Download from https://developer.android.com/studio,
drag to the Applications folder and launch.

Download & extract Flutter SDK
Visit https://docs.flutter.dev/install
Download the macOS stable ZIP and extract to e.g.: ~/development/flutter.

Update PATH
Open Terminal and edit your shell config (zsh is default in recent macOS):

nano ~/.zshrc
export PATH="$PATH:`pwd`/development/flutter/bin"
source ~/.zshrc

Install Flutter & Dart plugins
In Android Studio: Android Studio → Preferences → Plugins
Install Flutter (includes Dart) and restart.

Configure Flutter SDK in Android Studio
Preferences → Languages & Frameworks → Flutter
Set Flutter SDK path (e.g., /Users/yourname/development/flutter) and apply changes.

Install Xcode (for iOS)
App Store → search "Xcode" → install latest (16+).
Open Xcode once and accept the license.

Install Command Line Tools

xcode-select --install
sudo gem install cocoapods
pod setup

Final checks

flutter doctor
flutter doctor --android-licenses

Now launch Foodlay apps on simulators / devices from Android Studio on macOS!

Linux - Flutter Setup in Android Studio

Linux setup (Ubuntu 22.04+, Fedora, etc.) is clean and efficient:

Install Android Studio
Download from the official site or use Snap:

sudo snap install android-studio --classic

Download & extract Flutter SDK
Go to https://docs.flutter.dev/install
Download the stable tarball and extract:

mkdir -p ~/development
tar xf flutter_linux_3.38.6-stable.tar.xz -C ~/development

Update PATH
Edit ~/.bashrc or ~/.zshrc:

nano ~/.bashrc
export PATH="$PATH:$HOME/development/flutter/bin"
source ~/.bashrc

Install dependencies (Ubuntu example):

sudo apt update
sudo apt install clang cmake ninja-build pkg-config libgtk-3-dev liblzma-dev
sudo nano /etc/udev/rules.d/51-android.rules
SUBSYSTEM=="usb", ATTR{idVendor}=="18d1", MODE="0666", GROUP="plugdev"
sudo udevadm control --reload-rules && sudo service udev restart

Flutter & Dart plugins in Android Studio
Launch Android Studio → File → Settings → Plugins → install Flutter → restart IDE.

Set Flutter SDK path
Settings → Languages & Frameworks → Flutter
Point to ~/development/flutter and apply.

Verify & accept licenses

flutter doctor
flutter doctor --android-licenses

You're set! Open Foodlay UI Kit folders in Android Studio and start building beautiful food delivery apps on Linux.

Device targeting tips

List connected devices and run on a specific target:

flutter devices
flutter run -d <device_id>

Verify Android devices visibility:

adb devices

Quick Start

Welcome to the Getting Started section of Foodlay UI Kit.

This guide walks you through the essential steps to open, configure, build, and launch both the Customer App and Deliveryman App on your device or emulator.

Foodlay is structured as two separate Flutter applications. The process is nearly identical for both — just make sure to work inside the correct project folder.

Step 1 — Extract & Open the Project

  • Unzip the downloaded package to a convenient location.
  • Inside, you will find two folders:
customer_app/
deliveryman_app/
  • Open your desired app folder in your IDE:
  • Android Studio (recommended), Visual Studio Code, or IntelliJ IDEA.

Use File → Open and select the app folder.

Open project folder in IDE

Step 2 — Install Dependencies

  • Open the integrated terminal in your IDE (or a system terminal).
  • Run:
flutter pub get

This downloads and installs all required packages listed in pubspec.yaml.

  • Alternatively, in Android Studio / IntelliJ:
  • Open pubspec.yaml and click the Pub get button.

Run flutter pub get

Step 3 — Build & Launch the Application

  • Connect a physical device (USB debugging enabled) or start an emulator/simulator.
  • In Android Studio:
  • Select your target device from the toolbar dropdown and click the Run button.

Select device and run in Android Studio

From terminal (alternative method):

# Customer app
cd customer_app
flutter pub get
flutter run

# Deliveryman app
cd ../deliveryman_app
flutter pub get
flutter run

# List devices and run on a specific target
flutter devices
flutter run -d <device_id>

Bonus — Speed Up Development with Hot Reload

  • Make any UI or logic changes.
  • Save the file (Ctrl/Cmd + S).
  • Flutter will instantly reload the changes.

For signing and publishing, see the Android/iOS release checklists under Advanced configuration.

Advanced Configuration & Script Customization

This section guides you through essential customization steps to rebrand and prepare your Foodlay applications (Customer App and Deliveryman App) for production. These changes include updating the app name (display label), launcher icon, application ID (Android package name), and bundle identifier (iOS).

Recommendation: For faster and error-free results, consider using popular Flutter packages such as:

  • flutter_launcher_icons — automatic icon generation and replacement.
  • rename or change_app_package_name — bulk renaming of app name and bundle / package ID across platforms.

Install them globally or per-project as needed (see pub.dev for the latest instructions).

Android & iOS Configuration

Open the Android module in Android Studio

  1. Launch Android Studio.
  2. From the welcome screen, select Open an existing project.
  3. Navigate to and select the android folder inside your app directory (for example customer_app/android or deliveryman_app/android).
  4. Wait for the project to fully sync with Gradle files (if it doesn’t, go to File → Sync Project with Gradle Files).
  5. Once synced, you can run the Android app directly by selecting your device/emulator and clicking the Run button (green play icon).

Open existing Foodlay Android project in Android Studio

Android Studio device and emulator selection for Foodlay

Changing the application name (display label)

The display name appears on the device home screen and app drawer.

  1. Open android/app/src/main/AndroidManifest.xml.
  2. Locate the <application> tag.
  3. Update the android:label attribute, for example:
android:label="Foodlay Customer"   // or your desired name

AndroidManifest.xml application label for Foodlay app name

Changing the application icon

  1. Use a tool like App Icon Generator or the flutter_launcher_icons package.
  2. Upload your square PNG image (recommended minimum 1024×1024 px).
  3. Generate the full set of Android icons.
  4. Replace the generated files in the following folders (keep the filename as ic_launcher.png or follow adaptive icon structure if using newer formats):
android/app/src/main/res/mipmap-hdpi/
android/app/src/main/res/mipmap-mdpi/
android/app/src/main/res/mipmap-xhdpi/
android/app/src/main/res/mipmap-xxhdpi/
android/app/src/main/res/mipmap-xxxhdpi/

For adaptive icons (Android 8.0+), also update mipmap-anydpi-v26/ic_launcher.xml if present.

After replacement, run:

flutter clean
flutter pub get

Then rebuild the app.

Running flutter pub get for Foodlay project

Changing the application ID (package name)

The package name is unique and used for Google Play identification.

  1. Open android/app/build.gradle.kts.
  2. In the defaultConfig block, update:
applicationId = "com.example.flutter_boilerplate"   // Customer app
applicationId = "com.foodly.deliveryman"            // Deliveryman app

Use reverse domain notation, for example: com.yourcompany.foodlay.delivery for the Deliveryman app.

If using Firebase or Google Maps, also update:

  • google-services.json (download a new file from Firebase Console with the updated package name).
  • Any API key restrictions in Google Cloud Console.

Note: changing the package name requires a full clean rebuild and may affect existing installations. Uninstall the old version from devices before installing the new one.

keytool -genkey -v -keystore ~/foodlay-release.keystore -alias foodlay \
-keyalg RSA -keysize 2048 -validity 10000

Android applicationId configuration in build.gradle for Foodlay

iOS Configuration

Open your Flutter project in Xcode

  1. Navigate to the ios folder (for example customer_app/ios/Runner.xcworkspace).
  2. Double-click Runner.xcworkspace to launch Xcode.

Changing the app name (display name)

  1. In the Project Navigator, select the Runner project file (blue icon at the top).
  2. Select the Runner target under TARGETS.
  3. Go to the Info tab.
  4. Update Bundle name (or Display Name in newer Xcode versions) to your desired app name, for example Foodlay.

Xcode Runner target general and app name configuration for Foodlay

Changing the bundle identifier

The bundle ID uniquely identifies your app on the App Store.

  1. With the Runner target selected, go to the General tab.
  2. In the Identity section, update Bundle Identifier to a unique value, for example:
com.thedayone.foodlay.customer

(The value must match what you register in App Store Connect.)

Important: update any associated provisioning profiles, certificates, and capabilities (for example, Push Notifications, Maps) after changing the Bundle ID.

Project structure

Typical layout of the two apps:

  • customer_app/ — Android, iOS, lib, assets
  • deliveryman_app/ — Android, iOS, lib, assets
  • lib/config/route/route_config.dart — central route definitions
  • lib/core/dependency_injection/ — get_it + injectable setup
  • lib/config/theme/ — light/dark themes and custom colors
  • lib/config/util/ — constants, assets.gen.dart, fonts.gen.dart, styles
  • lib/features/<feature>/presentation/screens/ — feature screens
  • lib/features/<feature>/presentation/widgets/ — feature-private widgets
  • assets/ — images, icons, etc.; pubspec.yaml — dependencies and assets

For renaming and branding, see Android configuration and iOS configuration sections above.

Mock Data & API Integration — Development Flow

Both apps ship with a local mock API for rapid UI development and a clean path to connect a real backend when ready.

  • Local mock server: Implemented with shelf + shelf_router, starts during app initialization via dependency injection.
  • Ports: Customer → 8080; Deliveryman → 8081.
  • Base URL: Defined in AppConstants.baseUrl and injected into ApiClient via @Named('appBaseUrl').
# Customer
lib/core/mock/mock_api_server.dart          # port 8080
lib/config/util/app_constants.dart          # baseUrl = 'http://localhost:8080'

# Deliveryman
lib/core/mock/mock_api_server.dart          # port 8081
lib/config/util/app_constants.dart          # baseUrl = 'http://localhost:8081'

# DI entry
lib/core/dependency_injection/dependency_injection.dart
lib/core/dependency_injection/dependency_module.dart

Use mock data (default for development)

  1. Keep AppConstants.baseUrl pointing to http://localhost:<port> (per app).
  2. Mock JSON lives under assets/mock_data/ and is wired via Assets.mockData.* (generated by flutter_gen).
  3. Add or adjust routes in lib/core/mock/mock_api_server.dart:
    router.get(AppConstants.itemsUri,
    (req) => _handleRequestWithFile(req, Assets.mockData.items));
  4. Hot reload to see changes instantly; no external backend required.

Switch to a real backend

  1. Set AppConstants.baseUrl to your API endpoint (e.g., https://api.yourdomain.com).
  2. Optionally change DI environment and call:
    // lib/main.dart
    await configureDependencies(env: Environment.prod);
  3. Ensure authentication, CORS, and TLS are correctly configured in your backend. Android cleartext is disabled by default; use HTTPS for production.

Client behavior & headers

  • ApiClient attaches Content-Type, Authorization: Bearer <token>, and locale headers.
  • Customer app also sets X-User-ID when available; Deliveryman adds zoneid.
  • Tokens and preferences persist via SharedPreferences keys (see AppConstants.token, language_code).
  • Feature calls flow as Repository → Service → Bloc using dependency injection (get_it + injectable).

Localization & RTL

  • Localizations are wired via AppLocalizations in lib/main.dart (delegates, supported locales, and locale).
  • Translation files live under lib/l10n/arb/ (e.g. app_en.arb, app_ar.arb, app_bn.arb, app_es.arb, app_hi.arb).
  • Access strings using context.l10n from lib/l10n/l10n.dart.
  • Language switching is handled by LocalizationBloc and persisted via CommonServiceInterface.
  • RTL is supported (Arabic included). Flutter applies direction automatically; prefer directional-aware widgets (e.g., EdgeInsetsDirectional, AlignmentDirectional) and verify on RTL devices.

Theme & branding

  • Edit lib/config/theme/light_theme.dart and dark_theme.dart to customize ThemeData.
  • Use CustomThemeColors (theme extensions) to manage a global color palette.
  • Fonts: declare families in pubspec.yaml and set fontFamily in theme files.
  • Theme toggling is managed by ThemeBloc and persisted via CommonServiceInterface.
  • Assets: replace logos/images under assets/; use flutter_launcher_icons for app icons.

Maps API key

Android: add your Google Maps API key to AndroidManifest.xml:

<application>
<meta-data
    android:name="com.google.android.geo.API_KEY"
    android:value="YOUR_ANDROID_API_KEY"/>
</application>

iOS: add your API key to ios/Runner/Info.plist:

<key>GMSApiKey</key>
<string>YOUR_IOS_API_KEY</string>

Best practices:

  • Restrict Android key by package name and SHA-1.
  • Restrict iOS key by bundle identifier.
  • Limit APIs to the required Maps SDKs only.
  • Both apps use google_maps_flutter; see map helpers for bounds and settings: lib/core/helper/map_bound_helper.dart (Customer) and lib/core/helper/google_map_setting_bound.dart (Deliveryman).
  • Enable APIs and create keys:

    1. Open Google Cloud Console → APIs & Services.
    2. Enable Maps SDK for Android and Maps SDK for iOS.
    3. Create two API keys (Android and iOS) and apply restrictions.

    Get SHA-1 fingerprints:

    # Debug keystore
    keytool -list -v -alias androiddebugkey -keystore ~/.android/debug.keystore -storepass android -keypass android
    
    # Release keystore
    keytool -list -v -alias foodlay -keystore ~/foodlay-release.keystore

    Testing basics

    • Unit tests — pure Dart logic tests in test/.
    • Widget tests — render widgets and assert UI behavior.
    • Integration tests — end-to-end flows in integration_test/.

    Run unit and widget tests:

    flutter test

    Run integration tests (ensure a device/emulator is ready):

    flutter test integration_test

    Widget copy flow

    The Widget copy flow lets you duplicate any existing reusable widget (e.g., RestaurantCard, QuantitySelector) into another location or into the second app (Customer ↔ Deliveryman) without breaking theming or state management.

    1. Locate the widget

    1. Widgets live in lib/common/presentation/widgets/ or inside a feature folder such as lib/features/<feature>/presentation/widgets/.
    2. Open the file and confirm it is self-contained (no hard-coded business logic, relies only on parameters).

    2. Copy the widget file

    1. Right-click the file → Copy (or Ctrl/Cmd + C).
    2. Navigate to the target folder (same project or second app).
    3. Right-click → Paste and rename if necessary (e.g., restaurant_card.dartgrocery_card.dart).

    3. Update imports & constructor

    1. Fix the relative import paths at the top of the file.
    2. If you renamed the class, update the constructor call sites accordingly.
    3. Make sure any custom theme extensions or color tokens are imported (e.g., import '../../core/theme/app_colors.dart';).

    4. Optional: barrel file

    1. If you prefer aggregated exports, create or update a local barrel file inside the module (for example lib/common/presentation/widgets/widgets.dart or lib/features/<feature>/presentation/widgets/widgets.dart).
    2. Add an export for the new widget:
    export 'grocery_card.dart';

    5. Use the copied widget

    1. Import it wherever needed:
    import 'package:flutter_boilerplate/common/presentation/widgets/grocery_card.dart';

    6. Hot-reload test

    1. Place the copied widget in a dummy screen or inside an existing Column/ListView.
    2. Save → Hot-reload (r) to verify rendering.
    3. Adjust theming, padding, or parameters to match your new context.
    Pro tip: If you need the widget in the other app (Customer → Deliveryman or vice-versa), simply copy the file into the corresponding path in the second project and update the package imports.

    Screen copy flow

    The Screen copy flow allows you to duplicate an entire screen (page/route) including its bloc, repository, and UI files. This is useful when you want a new flow that resembles an existing one (e.g., copy “Restaurant Details” to create “Grocery Details”).

    1. Identify the screen folder

    1. Screens are grouped under lib/features/<feature>/presentation/ (e.g., lib/features/restaurant_details/presentation/screens/).
    2. Open the folder and note the files:
      • view/ (UI layer)
      • cubit/ or bloc/ (state management)
      • repository/ (data source)
      • model/ (data classes)

    2. Duplicate the folder

    1. In the IDE, right-click the folder → Copy.
    2. Right-click features/Paste.
    3. Rename the new folder (e.g., grocery_details).

    3. Rename classes & files

    1. Open each file inside the new folder.
    2. Use IDE global rename (Shift + F6 in Android Studio) to rename classes:
      • RestaurantDetailsPageGroceryDetailsPage
      • RestaurantDetailsCubitGroceryDetailsCubit
      • RestaurantDetailsRepositoryGroceryDetailsRepository
    3. Update any internal references (constructors, state classes, event names).

    4. Update the route

    1. Open your route configuration file: lib/config/route/route_config.dart.
    2. Add a new route entry:
    // 1) Add a route constant
    static const String groceryDetails = 'grocery_details';
    
    // 2) Register the route in GoRouter
    GoRoute(
      path: groceryDetails.pathUrl,
      builder: withRouteContext((context, state) => const GroceryDetailsPage()),
      pageBuilder: GoTransitions.fade.call,
    ),

    5. Wire up dependency injection

    1. Use get_it with injectable annotations.
    2. Annotate your new classes with @injectable (and add any @module bindings in lib/core/dependency_injection/dependency_module.dart if needed).
    3. Regenerate DI mappings:
    flutter pub run build_runner build --delete-conflicting-outputs

    At startup, DI is initialized via configureDependencies() in lib/core/dependency_injection/dependency_injection.dart, so no manual registration calls are required.

    6. Clean & rebuild

    1. Run flutter clean to clear old build cache.
    2. Run flutter pub get to refresh dependencies.
    3. Start the app and navigate to the new screen (via button or deep-link) to verify it loads without errors.
    Common pitfall: Forgetting to register the new cubit/repository in DI will throw a ProviderNotFoundException at runtime. Always double-check the injection setup.

    7. (Optional) Copy API endpoints

    1. If the new screen needs different backend data, clone the corresponding repository methods under lib/features/<feature>/data/repositories/ and update any calls in lib/core/data/api/ as appropriate.
    2. Map the new JSON response to your renamed models.

    Once these steps are complete, you have a fully independent screen that can evolve separately from the original. Repeat the flow for any additional screens you need to duplicate.

    Android release signing

    Create a release keystore:

    keytool -genkey -v -keystore ~/foodlay-release.keystore -alias foodlay -keyalg RSA -keysize 2048 -validity 10000

    Create key.properties in the android folder:

    storeFile=/Users/yourname/foodlay-release.keystore
    storePassword=YOUR_PASSWORD
    keyAlias=foodlay
    keyPassword=YOUR_PASSWORD

    Configure signing in android/app/build.gradle.kts:

    val keystorePropertiesFile = rootProject.file("key.properties")
    val keystoreProperties = java.util.Properties()
    if (keystorePropertiesFile.exists()) {
        keystoreProperties.load(java.io.FileInputStream(keystorePropertiesFile))
    }
    
    android {
        signingConfigs {
            create("release") {
                storeFile = file(keystoreProperties["storeFile"] as String)
                storePassword = keystoreProperties["storePassword"] as String
                keyAlias = keystoreProperties["keyAlias"] as String
                keyPassword = keystoreProperties["keyPassword"] as String
            }
        }
        buildTypes {
            release {
                signingConfig = signingConfigs.getByName("release")
                isMinifyEnabled = true
                isShrinkResources = true
            }
        }
    }

    Android release checklist

    1. Update versionCode and versionName in android/app/build.gradle.kts:
    android {
        defaultConfig {
            applicationId = "com.example.flutter_boilerplate"
            minSdk = 21
            targetSdk = 34
            versionCode = 2
            versionName = "1.1.0"
        }
    }
    1. Build a release App Bundle (recommended for Play Store):
    flutter build appbundle
    1. Alternatively, build a release APK:
    flutter build apk --release
    1. Test your release build on a physical device.
    2. Upload to Google Play Console and complete store listing.

    iOS signing & capabilities

    Configure signing and required capabilities in Xcode:

    • Set Team and enable Automatically manage signing.
    • Add Push Notifications capability (if used).
    • Add Background Modes → enable required modes.
    • Add Maps / Location permissions when needed.

    Changing the app icon

    1. Generate icons using a tool like App Icon Generator (1024×1024 source PNG recommended).
    2. In Xcode’s Project Navigator, expand Runner → Assets.xcassets.
    3. Select AppIcon.
    4. Drag and drop the generated icons into the corresponding slots (or replace the entire set).

    Xcode will automatically handle size variations.

    Xcode AppIcon asset configuration for Foodlay iOS app

    After making changes

    1. Clean the Xcode build: Product → Clean Build Folder.
    2. Return to the terminal and run:
    flutter clean
    flutter pub get

    Then rebuild and run:

    flutter run

    Foodlay app run completed successfully after configuration changes

    These customizations ensure your Foodlay apps reflect your brand identity across both platforms. Always test thoroughly on physical devices after changes, especially icons and identifiers.

    iOS release checklist

    1. Update version in ios/Runner/Info.plist:
    <key>CFBundleShortVersionString</key>
    <string>1.1.0</string>
    <key>CFBundleVersion</key>
    <string>3</string>
    1. Build the iOS release:
    flutter build ios --release
    1. Open the Xcode workspace, select Any iOS Device (arm64), then Product → Archive.
    2. Upload via the Organizer to App Store Connect and complete TestFlight/Release.

Mock Data & API Integration

This section provides a professional, end-to-end guide for developing with mock data and integrating real APIs for both Foodlay applications (Customer and Deliveryman).

Architecture Overview

  • Local mock server runs inside the app process using shelf + shelf_router.
  • Dependency injection registers the mock server as a singleton on app startup.
  • ApiClient reads the base URL from AppConstants and attaches headers (token, locale).
  • Feature calls flow as Repository → Service → Bloc via get_it + injectable.

Key files:

  • Customer: customer_app/lib/core/mock/mock_api_server.dart
  • Deliveryman: deliveryman_app/lib/core/mock/mock_api_server.dart
  • Customer base URL: customer_app/lib/config/util/app_constants.dart
  • Deliveryman base URL: deliveryman_app/lib/config/util/app_constants.dart
  • DI setup: customer_app/lib/core/dependency_injection/dependency_injection.dart
  • Api client (Customer): customer_app/lib/core/data/api/api_client.dart
  • Api client (Deliveryman): deliveryman_app/lib/core/data/api/api_client.dart

Ports & Base URLs

  • Customer app base URL: http://localhost:8080
  • Deliveryman app base URL: http://localhost:8081
  • Because the mock server runs inside the app, localhost points to the device itself (no emulator bridging required).

Using Mock Data (Development)

  1. Keep AppConstants.baseUrl pointed to the local port.
  2. Mock JSON files are under assets/mock_data/ and referenced via Assets.mockData.*.
  3. Add routes in mock_api_server.dart:
    router.get(AppConstants.itemsUri,
    (req) => _handleRequestWithFile(req, Assets.mockData.items));
  4. Update AppConstants for new endpoints as needed.
  5. Run flutter pub run build_runner build to regenerate DI and assets code when necessary.

Switching to a Real Backend

  1. Set AppConstants.baseUrl to your API host (e.g., https://api.yourdomain.com).
  2. Optionally initialize DI with production env:
    // in main.dart
    await configureDependencies(env: Environment.prod);
  3. Ensure your backend supports required headers, authentication, CORS and TLS.

Headers & Persistence

  • Customer headers include Authorization, locale, and optionally X-User-ID.
  • Deliveryman headers include Authorization, locale
  • Tokens and preferences persist in SharedPreferences (see keys in AppConstants).

Deliveryman-Specific Flow Insight

  • Status progression for orders is modeled in mock server (e.g., ready_to_handover → picked_up → on_the_way → delivered).
  • Try updating status via mock routes to validate UI reactions before real API integration.

Debugging

  • Use curl to hit local routes directly:
    curl http://localhost:8080/api/v1/customer/app-screen/home
    curl http://localhost:8081/api/v1/deliveryman/orders
  • Console logs show server start/stop and request details for faster diagnosis.

Common Issues & Troubleshooting

Even with a well-structured Flutter project like Foodlay UI Kit (containing both the Customer App and Deliveryman App), you might encounter build, dependency, or runtime errors — especially during initial setup, after Flutter/Dart upgrades, or when switching platforms.

This section covers the most frequently reported issues developers face with Foodlay-style Flutter UI kits, along with clear, step-by-step solutions (updated for Flutter 3.38.x in January 2026).

Gradle build failed – non-zero exit value 1

Typical symptoms:

  • Android build fails immediately with a vague "non-zero exit value 1" message.

Common causes:

  • Outdated or incompatible Gradle / Android Gradle Plugin version.
  • Missing Android licenses.
  • Java version mismatch (recent Flutter requires JDK 17+).
  • Corrupted Gradle or build cache.

Quick fixes:

# Accept all licenses
flutter doctor --android-licenses

# Clean Android Gradle project
cd android
./gradlew clean
cd ..

# Delete Flutter caches & rebuild
flutter clean
flutter pub get
flutter pub cache repair   # optional but powerful

# Run again
flutter run

Flutter SDK path not found / "Flutter SDK not available"

Symptoms: IDE shows a red error or flutter commands fail.

Fix:

  • Ensure the Flutter bin directory is in your system PATH.
  • In Android Studio / IntelliJ: go to Settings → Languages & Frameworks → Flutter and set the correct SDK path (for example C:\flutter or ~/development/flutter).
  • Restart the IDE completely after updating the path.

Dependency resolution failed / version solving failed

Symptoms: flutter pub get shows conflict errors such as "Because package A depends on package B ^1.0.0 which doesn't match any versions".

Solutions:

  • Run with override (temporary workaround):
flutter pub get --no-version-check
  • Upgrade conflicting packages manually in pubspec.yaml to compatible versions.
  • Use the latest compatible versions by running:
flutter pub upgrade --major-versions
  • Delete pubspec.lock and resolve fresh:
rm -f pubspec.lock
flutter pub get

iOS: IPHONEOS_DEPLOYMENT_TARGET out-of-range

Symptoms: Errors like IPHONEOS_DEPLOYMENT_TARGET is set to x.x, but the range is 9.0 to 16.0 (or similar).

Cause: Mismatch between the project deployment target and CocoaPods / Podfile settings.

Fix:

  1. Open ios/Podfile.
  2. Uncomment and update the platform line near the top:
platform :ios, '13.0'   # or '14.0', '15.0' etc. — match your needs

Then run:

cd ios
pod deintegrate
pod cache clean --all
pod install --repo-update
cd ..

flutter clean
flutter pub get

"No matching client found for this package name"

Cause: The Google services configuration (for example google-services.json) has a different package name to your Android app ID.

Fix:

  • Open android/app/google-services.json and check package_name.
  • Ensure it exactly matches your applicationId in android/app/build.gradle.kts (e.g., com.example.flutter_boilerplate for Customer, com.foodly.deliveryman for Deliveryman).
  • If needed, regenerate the config file from Firebase Console with the new package name.

Unsupported Gradle version / Gradle plugin errors

Cause: Flutter requires newer Android Gradle Plugin (AGP) and Gradle versions.

Fix:

  1. In android/build.gradle, update the Android Gradle Plugin classpath, for example:
dependencies {
classpath 'com.android.tools.build:gradle:8.5.0'   // or latest compatible
}
  1. In android/gradle/wrapper/gradle-wrapper.properties, update the distribution URL, for example:
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-all.zip

Use a Gradle version compatible with your AGP and Flutter version.

Type / class not found

Cause: Missing imports, outdated generated files, or an incomplete flutter pub get.

Fix:

  • Ensure all required Dart imports are present.
  • Delete generated tooling folders and rebuild:
rm -rf .dart_tool/
rm -rf build/

flutter clean
flutter pub get

If you use code generators (for example freezed, json_serializable), also run:

flutter pub run build_runner build --delete-conflicting-outputs

General recovery checklist

When in doubt, start with a clean rebuild. This checklist solves most local environment issues:

flutter clean
rm -f pubspec.lock   # optional but often helpful
flutter pub get
flutter pub cache repair

cd android && ./gradlew clean && cd ..
cd ios && pod install   # if on macOS, with CocoaPods installed

flutter run --verbose

Most issues in Foodlay are resolved with a clean + fresh flutter pub get cycle. If problems persist, check your Flutter version (flutter --version), ensure you're on the stable channel, and verify that flutter doctor reports no major issues.

Networking & emulator proxy

Symptoms: Emulator cannot access internet or API; proxy or VPN interference.

Fix:

  • Disable emulator proxy under Android Studio → Settings → HTTP Proxy.
  • Ensure system proxy excludes localhost: set environment variables:
export no_proxy=127.0.0.1,localhost
export NO_PROXY=127.0.0.1,localhost
  • Restart the emulator and try again with verbose logs:

Mock server not responding / blank data

Symptoms: Empty lists, 404s from localhost, or "Unable to connect to server".

Fix:

  • Check console logs for "Mock API server started on http://localhost:8080/8081". If absent, ensure DI registers MockApiServer (it’s a singleton).
  • Verify AppConstants.baseUrl:
    • Customer: http://localhost:8080
    • Deliveryman: http://localhost:8081
  • Android: allow cleartext HTTP. Customer app includes android:networkSecurityConfig="@xml/network_security_config"; ensure the file permits localhost for development.
  • Proxies/VPNs: exclude localhost as shown above.

Generated files missing (freezed/json/FlutterGen/DI)

Symptoms: Errors like "Target of URI does not exist: app_localizations.dart", missing assets.gen.dart, dependency_injection.config.dart, or *.freezed.dart/*.g.dart.

Fix:

  • Refresh dependencies and rebuild generators:
flutter clean
flutter pub get
flutter pub run build_runner build --delete-conflicting-outputs
  • Ensure flutter_gen_runner, freezed, json_serializable, and injectable_generator are present in dev_dependencies (both apps include them).
  • Confirm flutter: generate: true is set in pubspec.yaml.

FAQ

  • The app doesn’t appear on my device — Ensure the device is visible via flutter devices, accept trust prompts (Android USB debugging; iOS trust computer). Re-run flutter run.
  • CocoaPods keeps failing — Clean caches: pod cache clean --all, pod install --repo-update, verify xcode-select --install.
  • Google Maps shows blank screen — Check API key restrictions (Android package name + SHA‑1; iOS bundle ID) and add keys to Manifest/Info.plist.
  • First build is very slow — Flutter builds caches; subsequent runs are faster. Use flutter clean only when necessary, then flutter pub get.

Help & Support – Foodlay UI Kit

We’re committed to helping you get the most out of Foodlay UI Kit — your complete Flutter solution for building professional Customer and Deliveryman food delivery applications.

Before reaching out, please review the full documentation: Prerequisites, Quick Start, Advanced Configuration, and Common Issues & Troubleshooting. Most setup, build, and customization questions can be resolved quickly using the provided guides and code comments.

How to get support

What to include

  • Your purchase/order reference (if applicable) or proof of purchase
  • A clear description of the issue or question
  • Steps to reproduce the problem (if it’s a bug)
  • Relevant screenshots, error logs, or console output
  • Your current Flutter version (flutter --version)
  • Target platform (Android, iOS, or both)
  • Any recent changes made to the code or dependencies

Support scope & guidelines

Support covers:

  • Issues directly related to Foodlay UI Kit code, structure, and included features
  • Bugs in the original template
  • Configuration questions and basic customization guidance

We do not provide support for:

  • Third-party package integrations or updates
  • Custom feature development
  • Backend/API implementation
  • General Flutter/Dart learning
  • Issues caused by modified code or incompatible environment changes

Requests are handled on a first-come, first-served basis. Typical response time is 24–72 hours (business days).

Additional resources

  • Revisit the complete Foodlay documentation
  • Check Flutter’s official docs: https://flutter.dev
  • Search Stack Overflow, Flutter GitHub issues, or relevant pub.dev package pages

Thank you for choosing Foodlay UI Kit. We’re excited to support you on your journey to launching a beautiful, high-performance food delivery platform.