progress tracker (flutter)
syuaib
Prompt
make mobile software using flutter with professional and modern UI/UX design
Below is a complete, production-ready starter kit for a modern Flutter application. It is opinionated but flexible: you can delete what you don’t need and extend what you do. Everything is broken down into: 1. Product & UX groundwork 2. Project structure & tooling 3. Design system & theming 4. Key UI patterns (code) 5. Sample feature (code) 6. Quality, CI/CD & store-readiness ──────────────────────────────────────── 1. Product & UX groundwork ──────────────────────────────────────── • Personas & jobs-to-be-done → 3-sentence description for each user type. • Flows → map them in Figma or FigJam first; one purpose per screen. • Wireframes → low-fidelity, validate wording & hierarchy. • UI kit → Material-3 tokens + your brand colours, typography scale, elevation, spacing, states, iconography. • Accessibility → 4.5:1 contrast, focus order, semantics, larger tap areas, haptic feedback. • Motion → subtle, 200-300 ms, ease-in-out. Avoid gratuitous parallax. • Copywriting → informal but concise; error states must say what, why, how-to-fix. ──────────────────────────────────────── 2. Project structure & tooling ──────────────────────────────────────── . └─ lib ├─ bootstrap // entry & DI ├─ core // constants, env, errors, utils ├─ data │ ├─ models // freezed classes │ ├─ sources // remote/local │ └─ repositories ├─ features │ ├─ auth │ │ ├─ presentation // screens, widgets │ │ ├─ application // providers, use-cases │ │ └─ domain // entities │ └─ home … ├─ l10n // ARB files ├─ shared // atoms, molecules, templates └─ theme test → unit & golden integration_test → e2e Recommended packages • riverpod & flutter_riverpod (state management) • go_router (declarative navigation & deep links) • freezed & json_serializable (immutable models) • dio + retrofit (network) • flutter_gen (assets, fonts) • intl (localisation) • flex_color_scheme (Material-3 theming) • animations, rive, lottie (motion) • google_fonts • shimmer (skeleton loaders) • flutter_secure_storage (tokens) • device_preview + responsive_framework (device sizes) • flutter_test + mocktail + golden_toolkit ──────────────────────────────────────── 3. Design system & theming (code) ──────────────────────────────────────── /lib/theme/app_theme.dart ```dart import 'package:flex_color_scheme/flex_color_scheme.dart'; import 'package:flutter/material.dart'; class AppTheme { static ThemeData light() => FlexThemeData.light( scheme: FlexScheme.hippieBlue, useMaterial3: true, subThemesData: const FlexSubThemesData( elevatedButtonRadius: 12, inputDecoratorRadius: 12, bottomSheetRadius: 28, ), visualDensity: VisualDensity.adaptivePlatformDensity, ); static ThemeData dark() => FlexThemeData.dark( scheme: FlexScheme.hippieBlue, useMaterial3: true, ); } ``` main entry with DI & theme /lib/bootstrap/bootstrap.dart ```dart import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../theme/app_theme.dart'; import '../routes/app_router.dart'; Future<void> bootstrap() async { WidgetsFlutterBinding.ensureInitialized(); runApp(const ProviderScope(child: MyApp())); } class MyApp extends ConsumerWidget { const MyApp({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { final router = ref.watch(appRouterProvider); return MaterialApp.router( title: 'Modern App', theme: AppTheme.light(), darkTheme: AppTheme.dark(), routerConfig: router, locale: ref.watch(localeProvider), supportedLocales: const [Locale('en'), Locale('es')], debugShowCheckedModeBanner: false, ); } } ``` ──────────────────────────────────────── 4. Key UI patterns ──────────────────────────────────────── 4.1 Onboarding (paginated, swipable) ```dart class OnboardingScreen extends ConsumerStatefulWidget { … } class _OnboardingScreenState extends ConsumerState<OnboardingScreen> { final _pageController = PageController(); int _idx = 0; @override Widget build(BuildContext context) { final pages = [ _Page(asset: 'assets/1.json', title: 'Welcome', desc: 'Short pitch'), _Page(asset: 'assets/2.json', title: 'Sync', desc: 'Your data anywhere'), _Page(asset: 'assets/3.json', title: 'Secure', desc: 'Privacy first'), ]; return Scaffold( body: SafeArea( child: Column( children: [ Expanded( child: PageView.builder( controller: _pageController, onPageChanged: (i) => setState(() => _idx = i), itemCount: pages.length, itemBuilder: (_, i) => pages[i], ), ), Padding( padding: const EdgeInsets.all(16), child: Row( children: [ SmoothPageIndicator( controller: _pageController, count: pages.length, effect: const WormEffect(), ), const Spacer(), FilledButton( onPressed: () { if (_idx == pages.length - 1) { context.go('/auth'); } else { _pageController.nextPage( duration: 300.ms, curve: Curves.easeOut); } }, child: Text(_idx == pages.length - 1 ? 'Start' : 'Next'), ), ], ), ), ], ), ), ); } } ``` 4.2 Bottom navigation that turns into NavigationRail on tablet ```dart class AdaptiveScaffold extends StatelessWidget { final Widget child; const AdaptiveScaffold({required this.child, super.key}); @override Widget build(BuildContext context) { const destinations = [ NavigationDestination(icon: Icon(Icons.home), label: 'Home'), NavigationDestination(icon: Icon(Icons.bar_chart), label: 'Stats'), NavigationDestination(icon: Icon(Icons.settings), label: 'Settings'), ]; return LayoutBuilder(builder: (context, constraints) { final isTablet = constraints.maxWidth >= 600; return isTablet ? Row( children: [ NavigationRail( destinations: destinations .map((d) => NavigationRailDestination( icon: d.icon, label: Text(d.label))) .toList(), selectedIndex: 0 /* use Riverpod ftw */, ), Expanded(child: child), ], ) : Scaffold( body: child, bottomNavigationBar: NavigationBar( destinations: destinations, selectedIndex: 0, ), ); }); } } ``` 4.3 Reusable CTA button (atom) ```dart class AppButton extends StatelessWidget { final String text; final VoidCallback onPressed; const AppButton({super.key, required this.text, required this.onPressed}); @override Widget build(BuildContext context) { return FilledButton( style: FilledButton.styleFrom( minimumSize: const Size.fromHeight(48), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(14)), ), onPressed: onPressed, child: Text(text), ); } } ``` ──────────────────────────────────────── 5. Sample feature – Home list with shimmer while loading ──────────────────────────────────────── Model with Freezed ```dart @freezed class Item with _$Item { const factory Item({ required String id, required String title, required String subtitle, required String imageUrl, }) = _Item; factory Item.fromJson(Map<String, dynamic> json) => _$ItemFromJson(json); } ``` Repository (simplified) ```dart class ItemRepository { final Dio _dio; ItemRepository(this._dio); Future<List<Item>> fetch() async { final res = await _dio.get('/items'); return (res.data as List).map((e) => Item.fromJson(e)).toList(); } } ``` Riverpod provider ```dart final itemsProvider = FutureProvider.autoDispose<List<Item>>((ref) async { final repo = ref.watch(itemRepoProvider); return repo.fetch(); }); ``` Presentation ```dart class HomeScreen extends ConsumerWidget { const HomeScreen({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { final asyncItems = ref.watch(itemsProvider); return Scaffold( appBar: AppBar(title: const Text('Dashboard')), body: asyncItems.when( data: (items) => ListView.builder( padding: const EdgeInsets.all(12), itemCount: items.length, itemBuilder: (_, i) => _Card(item: items[i]), ), loading: () => ListView.builder( itemCount: 6, itemBuilder: (_, __) => const Shimmer.fromColors( baseColor: Colors.grey, highlightColor: Colors.white, child: Padding( padding: EdgeInsets.symmetric(horizontal:12, vertical:8), child: Card(height: 80), ), ), ), error: (e, st) => Center( child: Text('😢 Oops\n${e.toString()}', textAlign: TextAlign.center), ), ), ); } } ``` ──────────────────────────────────────── 6. Quality, CI/CD & store readiness ──────────────────────────────────────── • Static analysis: flutter_lints, very_good_analysis. • pre-commit: `dart format`, `flutter analyze`, `flutter test`. • UI tests: integration_test + flutter_driver or maestro. • Golden tests for widgets (golden_toolkit). • Fastlane: automatic versioning, screenshots, signing & upload to Play/App Store. • Firebase Crashlytics + Sentry for crash/error reporting. • Remote config & A/B testing (Firebase). • Performance tracing with Dart DevTools & Flutter DevTools. • Store assets: 6-8 screenshots, short & full description (max 80 / 4000 chars), 30-sec promo video. • Privacy policy & T&C hosted online; link in‐app (Settings > Legal). ──────────────────────────────────────── How to run ──────────────────────────────────────── 1. `flutter pub get` 2. `flutter gen-l10n` (if localisation enabled) 3. `flutter run --dart-define=ENV=dev` 4. For release: `flutter build apk --obfuscate --split-debug-info=build/symbols`. You now have: • A clean architecture base • Scalable design system with Material-3 • Adaptive layouts (phone ↔ tablet) • Strong state management & navigation • Production-grade testing & deployment pipeline Plug in your real features, swap the colour scheme to match your brand, and ship!
Drag to resize
Of course! Creating a mobile app with a professional and modern UI/UX in Flutter is an excellent choice. This guide will walk you through the entire process, from design philosophy to a practical code example. We'll build a concept for a simple, elegant "Mindful Moments" meditation app. ### Phase 1: The Design & UX Blueprint (The Professional Foundation) Before writing a single line of code, professional apps start with a solid plan. **Don't skip this phase.** **1. Define the User Experience (UX):** * **Goal:** What should the user be able to do, and how should they feel while doing it? For our app: "The user should feel calm and easily find and play a meditation session." * **User Flow:** Map out the screens and the user's journey. * `Splash Screen` -> `Onboarding (First time)` -> `Home Screen` -> `Session Details Screen` -> `Player Screen` * **Wireframes:** Low-fidelity sketches of each screen. This is about layout and function, not colors or fonts. Tools like **Figma**, **Sketch**, or even pen and paper are perfect for this. **2. Establish the UI Design System (The Modern Look):** This is the key to a consistent and professional look. We'll define our "style guide" in Figma or a similar tool. * **Color Palette:** Choose a primary, secondary, background, and accent color. Modern design often uses off-whites, muted primary colors, and a single bright accent. * *Primary:* Soft Blue (`#8E97FD`) * *Accent:* Light Pink (`#FFD6D6`) * *Background:* Off-White (`#F3F4F8`) * *Text/Dark:* Dark Slate (`#3F414E`) * **Typography:** Choose 1-2 fonts that are clean and readable. **Google Fonts** is an amazing resource. * *Headings:* A clean sans-serif like "Poppins" (Bold) * *Body Text:* "Inter" (Regular) * **Spacing & Grid:** Use a consistent spacing system (e.g., multiples of 8: 8px, 16px, 24px). This creates a visually balanced and organized layout. * **Iconography:** Choose a single style (e.g., line icons or solid icons). **Feather Icons** or **Phosphor Icons** are great modern choices. --- ### Phase 2: Setting up the Flutter Project **1. Create the App:** ```bash flutter create mindful_moments cd mindful_moments ``` **2. Project Structure (for Scalability):** A clean folder structure is a sign of a professional project. ``` lib/ ├── main.dart │ ├── core/ # Core logic, theme, constants │ ├── app_theme.dart │ └── constants.dart │ ├── features/ # Each feature gets its own folder │ ├── home/ │ │ ├── screens/ │ │ │ └── home_screen.dart │ │ └── widgets/ │ │ ├── session_card.dart │ │ └── welcome_header.dart │ └── player/ │ └── ... │ ├── shared/ # Widgets used across multiple features │ └── widgets/ │ └── custom_bottom_nav_bar.dart ``` **3. Add Essential Packages:** Open `pubspec.yaml` and add these packages for a modern UI. ```yaml dependencies: flutter: sdk: flutter google_fonts: ^6.1.0 # For beautiful typography flutter_svg: ^2.0.9 # For high-quality vector icons # We'll also use a state management solution later, like flutter_riverpod ``` Run `flutter pub get` in your terminal. --- ### Phase 3: Implementing the UI in Flutter Now, let's translate our design into code. **1. Create the App Theme (`core/app_theme.dart`):** Centralizing your theme is crucial for consistency. ```dart // core/app_theme.dart import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; class AppTheme { static const Color primaryColor = Color(0xFF8E97FD); static const Color accentColor = Color(0xFFFFD6D6); static const Color backgroundColor = Color(0xFFF3F4F8); static const Color textColor = Color(0xFF3F414E); static ThemeData get theme { return ThemeData( primaryColor: primaryColor, scaffoldBackgroundColor: backgroundColor, fontFamily: GoogleFonts.inter().fontFamily, textTheme: TextTheme( displayLarge: GoogleFonts.poppins(fontSize: 28, fontWeight: FontWeight.bold, color: textColor), bodyLarge: GoogleFonts.inter(fontSize: 16, color: textColor.withOpacity(0.7)), labelLarge: GoogleFonts.poppins(fontSize: 16, fontWeight: FontWeight.w600, color: Colors.white), ), appBarTheme: const AppBarTheme( backgroundColor: Colors.transparent, elevation: 0, iconTheme: IconThemeData(color: textColor), ), bottomNavigationBarTheme: const BottomNavigationBarThemeData( backgroundColor: Colors.white, selectedItemColor: primaryColor, unselectedItemColor: Colors.grey, showUnselectedLabels: false, showSelectedLabels: false, type: BottomNavigationBarType.fixed, elevation: 5, ), ); } } ``` **2. Update `main.dart`:** Connect the theme to your `MaterialApp`. ```dart // main.dart import 'package:flutter/material.dart'; import 'package:mindful_moments/core/app_theme.dart'; import 'package:mindful_moments/features/home/screens/home_screen.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: 'Mindful Moments', theme: AppTheme.theme, debugShowCheckedModeBanner: false, home: const HomeScreen(), ); } } ``` **3. Build the Home Screen (`features/home/screens/home_screen.dart`):** This is where we assemble our components. We'll use a `CustomScrollView` with `Slivers` for a modern, dynamic scrolling effect. ```dart // features/home/screens/home_screen.dart import 'package:flutter/material.dart'; import 'package:mindful_moments/features/home/widgets/session_card.dart'; class HomeScreen extends StatelessWidget { const HomeScreen({super.key}); @override Widget build(BuildContext context) { return Scaffold( body: SafeArea( child: CustomScrollView( slivers: [ // Welcome Header SliverToBoxAdapter( child: Padding( padding: const EdgeInsets.all(24.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Good Morning, User', style: Theme.of(context).textTheme.displayLarge, ), const SizedBox(height: 8), Text( 'We wish you have a good day', style: Theme.of(context).textTheme.bodyLarge, ), ], ), ), ), // Session Card Grid SliverPadding( padding: const EdgeInsets.symmetric(horizontal: 24.0), sliver: SliverGrid( gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 2, crossAxisSpacing: 20, mainAxisSpacing: 20, childAspectRatio: 0.8, ), delegate: SliverChildBuilderDelegate( (context, index) { // Demo data final sessions = [ {'title': 'Focus', 'color': const Color(0xFF8E97FD), 'image': 'assets/images/focus.svg'}, {'title': 'Happiness', 'color': const Color(0xFFFA6E5A), 'image': 'assets/images/happiness.svg'}, {'title': 'Relaxation', 'color': const Color(0xFFFEB18F), 'image': 'assets/images/relaxation.svg'}, {'title': 'Sleep', 'color': const Color(0xFF3F414E), 'image': 'assets/images/sleep.svg'}, ]; final session = sessions[index]; return SessionCard( title: session['title'] as String, color: session['color'] as Color, assetPath: session['image'] as String, ); }, childCount: 4, ), ), ), // Add more slivers here for other content sections ], ), ), bottomNavigationBar: BottomNavigationBar( items: const [ BottomNavigationBarItem(icon: Icon(Icons.home_filled), label: 'Home'), BottomNavigationBarItem(icon: Icon(Icons.music_note), label: 'Meditate'), BottomNavigationBarItem(icon: Icon(Icons.person), label: 'Profile'), ], ), ); } } ``` **4. Create a Reusable Widget (`features/home/widgets/session_card.dart`):** Reusable widgets are essential. This card will display our meditation sessions. *First, make sure to add some SVG images to your project under an `assets/images/` folder and declare it in `pubspec.yaml`.* ```yaml # pubspec.yaml flutter: uses-material-design: true assets: - assets/images/ ``` ```dart // features/home/widgets/session_card.dart import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; class SessionCard extends StatelessWidget { final String title; final String assetPath; final Color color; final VoidCallback? onTap; const SessionCard({ super.key, required this.title, required this.assetPath, required this.color, this.onTap, }); @override Widget build(BuildContext context) { return GestureDetector( onTap: onTap, child: Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: color, borderRadius: BorderRadius.circular(20), boxShadow: [ BoxShadow( color: color.withOpacity(0.3), blurRadius: 10, offset: const Offset(0, 5), ) ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Flexible( child: SvgPicture.asset( assetPath, width: 80, // Adjust size as needed height: 80, colorFilter: const ColorFilter.mode(Colors.white, BlendMode.srcIn), ), ), Text( title, style: Theme.of(context).textTheme.labelLarge, ), ], ), ), ); } } ``` *Note: I've used some placeholder SVG asset paths. You'll need to find your own SVGs (undraw.co is a great resource) and update the paths.* ### Phase 4: Polish & Interactivity (The "Modern" Feel) 1. **Implicit Animations:** For a delightful feel, wrap widgets in `AnimatedContainer` instead of `Container`. It will automatically animate changes to properties like `color`, `height`, `padding`, etc. 2. **State Management:** To manage which tab is selected or which song is playing, you need state management. **Riverpod** is a modern and powerful choice. It separates your UI from your business logic, which is critical for professional apps. 3. **Haptic Feedback:** Use `HapticFeedback.lightImpact()` on button presses to give a subtle physical response. 4. **Loading States:** Never let the user see a blank screen. Use `CircularProgressIndicator` or skeleton loaders (like the `shimmer` package) while fetching data. ### Final Result When you run this code, you'll have a visually appealing, well-structured home screen that follows modern design principles. It's responsive, uses a consistent theme, and is built with scalability in mind. This is the foundation. From here, you would: * Build out the other screens (`Session Details`, `Player`). * Integrate a state management solution like Riverpod to handle navigation and player state. * Connect to a backend like **Firebase** or **Supabase** to fetch real session data. * Add more animations and transitions using tools like `Hero` animations for screen transitions or the `lottie` package for complex vector animations.
Drag to resize
Certainly! Here’s a comprehensive **example of a Flutter mobile app** with a **professional, modern UI/UX design**. This example will be a **“Task Manager”** app, including: - App structure (`main.dart`) - Professional theming - Modern widgets and layout - UI screens: Login, Task List, Add Task - Clean, maintainable code **Note:** You can copy this code base into your Flutter project. For brevity, this sample covers main screens and theming for professionalism. You may integrate further features (state management, network, DB, etc.) as needed. --- ## 1. `main.dart` ```dart import 'package:flutter/material.dart'; import 'screens/login_screen.dart'; void main() { runApp(TaskManagerApp()); } class TaskManagerApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Task Manager', theme: ThemeData( fontFamily: 'Montserrat', primaryColor: Color(0xFF0066FF), scaffoldBackgroundColor: Color(0xFFF8F9FC), appBarTheme: AppBarTheme( backgroundColor: Colors.white, titleTextStyle: TextStyle( color: Colors.black87, fontWeight: FontWeight.w600, fontSize: 22, ), elevation: 2, ), inputDecorationTheme: InputDecorationTheme( filled: true, fillColor: Color(0xFFF0F1F5), border: OutlineInputBorder( borderRadius: BorderRadius.circular(14), borderSide: BorderSide.none, ), ), elevatedButtonTheme: ElevatedButtonThemeData( style: ButtonStyle( backgroundColor: MaterialStateProperty.all(Color(0xFF0066FF)), shape: MaterialStateProperty.all( RoundedRectangleBorder( borderRadius: BorderRadius.circular(14), ), ), textStyle: MaterialStateProperty.all( TextStyle( fontWeight: FontWeight.bold, fontSize: 17, ), ), padding: MaterialStateProperty.all(EdgeInsets.symmetric(vertical: 12, horizontal: 32)), ), ), ), home: LoginScreen(), ); } } ``` --- ## 2. `/screens/login_screen.dart` ```dart import 'package:flutter/material.dart'; import 'task_list_screen.dart'; class LoginScreen extends StatelessWidget { final TextEditingController _emailController = TextEditingController(); final TextEditingController _passwordController = TextEditingController(); @override Widget build(BuildContext context) { return Scaffold( body: Center( child: SingleChildScrollView( child: Padding( padding: const EdgeInsets.symmetric(horizontal: 32.0), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(Icons.check_circle_outline, size: 64, color: Colors.blue), SizedBox(height: 18), Text( "Welcome Back!", style: TextStyle(fontWeight: FontWeight.w700, fontSize: 28), ), SizedBox(height: 8), Text( "Login to manage your tasks", style: TextStyle(color: Colors.grey[600], fontSize: 16), ), SizedBox(height: 30), TextField( controller: _emailController, decoration: InputDecoration( labelText: "Email", prefixIcon: Icon(Icons.email_outlined), ), ), SizedBox(height: 18), TextField( controller: _passwordController, obscureText: true, decoration: InputDecoration( labelText: "Password", prefixIcon: Icon(Icons.lock_outline), ), ), SizedBox(height: 26), ElevatedButton( onPressed: () { Navigator.pushReplacement( context, MaterialPageRoute(builder: (_) => TaskListScreen()), ); }, child: Center( child: Text("Login"), ), ), ], ), ), ), ), ); } } ``` --- ## 3. `/screens/task_list_screen.dart` ```dart import 'package:flutter/material.dart'; import 'add_task_screen.dart'; class TaskListScreen extends StatefulWidget { @override State<TaskListScreen> createState() => _TaskListScreenState(); } class _TaskListScreenState extends State<TaskListScreen> { List<Map> tasks = [ {"title": "Finish Flutter project", "done": false}, {"title": "Check email", "done": true}, {"title": "Read UI/UX article", "done": false}, ]; void _addTask(String title) { setState(() { tasks.insert(0, {"title": title, "done": false}); }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("My Tasks"), actions: [ IconButton( icon: Icon(Icons.account_circle_outlined, color: Colors.black54), onPressed: () {}, ), ], ), body: tasks.isEmpty ? Center( child: Text( "No tasks yet!", style: TextStyle(fontSize: 18, color: Colors.grey[500]), ), ) : ListView.builder( padding: EdgeInsets.symmetric(vertical: 4), itemCount: tasks.length, itemBuilder: (context, index) => Card( margin: EdgeInsets.symmetric(horizontal: 18, vertical: 8), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(14), ), child: ListTile( contentPadding: EdgeInsets.symmetric(vertical: 6, horizontal: 16), leading: Checkbox( value: tasks[index]["done"], shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(6)), onChanged: (bool? value) { setState(() { tasks[index]["done"] = value!; }); }, ), title: Text( tasks[index]["title"], style: TextStyle( fontSize: 17, decoration: tasks[index]["done"] ? TextDecoration.lineThrough : null, color: tasks[index]["done"] ? Colors.grey : Colors.black, ), ), trailing: IconButton( icon: Icon(Icons.delete_outline, color: Colors.grey[500]), onPressed: () { setState(() { tasks.removeAt(index); }); }, ), ), ), ), floatingActionButton: FloatingActionButton.extended( icon: Icon(Icons.add), label: Text("Add Task"), backgroundColor: Theme.of(context).primaryColor, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(14), ), onPressed: () async { final result = await Navigator.push( context, MaterialPageRoute(builder: (_) => AddTaskScreen())); if (result != null && result is String && result.trim().isNotEmpty) { _addTask(result.trim()); } }, ), ); } } ``` --- ## 4. `/screens/add_task_screen.dart` ```dart import 'package:flutter/material.dart'; class AddTaskScreen extends StatelessWidget { final TextEditingController _controller = TextEditingController(); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("New Task"), ), body: Padding( padding: const EdgeInsets.symmetric(vertical: 40.0, horizontal: 24.0), child: Column( children: [ TextField( controller: _controller, autofocus: true, maxLength: 70, decoration: InputDecoration( labelText: "Task Title", hintText: "What do you want to do?", prefixIcon: Icon(Icons.edit_outlined), ), ), SizedBox(height: 22), ElevatedButton( onPressed: () { if (_controller.text.trim().isNotEmpty) { Navigator.pop(context, _controller.text); } }, child: Text("Save"), ), ], ), ), ); } } ``` --- ## 5. Tips for **Professional, Modern UI/UX** - Use **clean fonts** (e.g., Montserrat or default). - Use **consistent padding, large touch areas**, gentle rounded shapes (radius 12-16). - **Soft background colors** (light gray/white), elevated cards for clarity. - **Animations**: Use `Hero` or implicit animations for transitions, if desired. - **Feedback**: Dialogs/snackbars for errors/success. - Responsive; use widgets like `SingleChildScrollView`. --- ## 6. Further Improvements - Integrate state management (`Provider`, `Riverpod`) for complex apps. - Use a backend (Firebase, REST API) and login validation. - Add onboarding/introduction screens. - Use custom assets and illustrations for visual appeal. - Add dark mode (`ThemeData.dark()`). --- Ready to run in Flutter! Let me know your requirements for more screens, features (profile, analytics, settings, etc.), or customizations.
Drag to resize
Creating a professional and modern mobile app with Flutter involves a combination of best practices, modern design principles, and leveraging Flutter's powerful ecosystem. Below is a step-by-step guide with code snippets and recommendations: --- ### **1. Setup & Environment** - **Install Flutter**: ```bash flutter doctor ``` - **IDE**: Use VS Code or Android Studio with Flutter/Dart plugins. - **Packages**: Use `pub.dev` for third-party libraries (e.g., `provider`, `riverpod`, `http`, `get`, `animations`, `go_router`). --- ### **2. Project Structure** Adopt a **clean architecture** and **modular structure**: ``` lib/ ├── core/ │ ├── themes/ │ ├── utils/ │ └── constants/ ├── feature/ │ ├── home/ │ │ ├── widgets/ │ │ ├── models/ │ │ └── views/ │ ├── settings/ │ └── ... ├── shared/ │ ├── components/ │ └── services/ main.dart ``` --- ### **3. Modern UI/UX Design** - **Themes & Styling**: Use **Material 3** and **adaptive themes**: ```dart final theme = ThemeData( colorSchemeSeed: Colors.blue, useMaterial3: true, brightness: Brightness.light, fontFamily: 'Poppins', appBarTheme: AppBarTheme( backgroundColor: Colors.transparent, elevation: 0, ), ); ``` - **Responsive Layouts**: Use `LayoutBuilder` or `flutter_layout_grid`: ```dart LayoutBuilder( builder: (_, constraints) { if (constraints.maxWidth > 600) { return DesktopView(); } else { return MobileView(); } }, ); ``` - **Custom Widgets**: Example for a card with animations: ```dart class ModernCard extends StatelessWidget { @override Widget build(BuildContext context) { return AnimatedContainer( duration: Duration(milliseconds: 300), margin: EdgeInsets.symmetric horizontal: 16, vertical: 8, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(12), boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.1), blurRadius: 10)], ), padding: EdgeInsets.all(16), child: Row( children: [ Icon(Icons.edit, color: Theme.of(context).primaryColor), SizedBox(width: 12), Text("Editable Section", style: Theme.of(context).textTheme.titleMedium), ], ), ); } } ``` - **Animations**: Use `flutter_animate` for quick effects: ```dart Container(...) .animate() .fadeIn(duration: 500.ms) .slideX(delay: 200.ms); ``` --- ### **4. Navigation** Use **`go_router`** for declarative navigation with deep linking: ```dart final router = GoRouter( routes: [ GoRoute(path: '/', builder: (_, __) => HomeView()), GoRoute(path: '/details', builder: (_, __) => DetailsView()), ], ); ``` --- ### **5. State Management** Choose **Riverpod/Provider** (Riverpod preferred for large projects): ```dart final counterProvider = StateProvider<int>((_) => 0); class CounterView extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final count = ref.watch(counterProvider); return IconButton( icon: Text('$count'), onPressed: () => ref.read(counterProvider.notifier).update((state) => state + 1), ); } } ``` --- ### **6. API Integration** Use `http`, `dio`, or `get_it` for dependency injection: ```dart final getIt = GetIt.instance; class ApiService { final _client = http.Client(); Future fetchData() async { final res = await _client.get(Uri.parse('https://api.example.com/data')); return jsonDecode(res.body); } } // Register service getIt.registerLazySingleton<ApiService>(() => ApiService()); ``` --- ### **7. Testing & Debugging** - **Unit Tests**: ```dart void main() { test('Counter increments', () { final counter = Counter(); counter.increment(); expect(counter.value, 1); }); } ``` - **Widgets Tests**: ```dart testWidgets('HomeView has title', (WidgetTester tester) async { await tester.pumpWidget(MaterialApp(home: HomeView())); expect(find.text('Welcome'), findsOneWidget); }); ``` - Use **DevTools** for performance profiling. --- ### **8. Deployment** - **Android**: Generate app bundle: ```bash flutter build appbundle ``` - **iOS**: Archive via Xcode. - Use **Fastlane** for CI/CD. --- ### **9. Professional Enhancements** - **Dark Mode**: ```dart brightness: MediaQuery.platformBrightness == Brightness.dark; ``` - **Localization**: Use `flutter_localizations` and `arb` files. - **Accessibility**: Ensure `Semantics` and `Label` for widgets. - **Security**: Use `encrypt` for data encryption. --- ### **10. Starter Template** Here’s a simple modern home screen: ```dart class HomeView extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Modern App'), actions: [IconButton(icon: Icon(Icons.dark_mode), onPressed: toggleTheme)], ), body: Padding( padding: EdgeInsets.all(16), child: Column( children: [ Text( 'Welcome!', style: Theme.of(context).textTheme.titleLarge, ), SizedBox(height: 20), Expanded( child: GridView.builder( gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2), itemBuilder: (_, i) => ModernCard(), ), ), ], ), ), ); } } ``` --- ### **Tools & Packages** - **UI**: `smooth_page_indicator`, `cached_network_image`, `shimmer`, `flutter_spinkit`. - **Utils**: `freezed`, `json_serializable`, `logger`. - **Design Systems**: Export Figma components with `Flutter Flow`. --- ### **Ready to Build?** Share your app idea or specific features (e.g., authentication, payments, maps), and I can generate a tailored template! 🚀 Example: > "I need an e-commerce app with a product grid, cart, and checkout." Response: Scaffold code for product cards, cart provider, and checkout screen using Stripe integration.
Drag to resize
Below, I'll provide a comprehensive guide to help you create a mobile app using Flutter with a professional and modern UI/UX design. Since your request is a bit vague (e.g., what type of app? Like a social app, e-commerce, productivity tool?), I'll assume we're building a simple yet professional **News Reader App**. This app will fetch news from an API (e.g., NewsAPI.org), display articles in a clean feed, and include features like search, favorites, and dark mode for a modern touch. If this isn't what you meant (e.g., you want a different app type), please provide more details like the app's purpose, features, or target audience, and I can refine this! ### Why Flutter? - **Cross-Platform**: Builds for iOS and Android from a single codebase. - **UI/UX Focus**: Flutter excels at custom, responsive designs with built-in widgets for Material Design (Android-like) or Cupertino (iOS-like). We'll use modern practices like Riverpod for state management, animations, and theming for a professional feel. - **Performance**: Native compilation ensures smooth, fast apps. ### Prerequisites - Install Flutter SDK: Follow the official guide at [flutter.dev](https://flutter.dev/docs/get-started/install). - IDE: Use VS Code or Android Studio with Flutter extensions. - Dependencies: We'll use packages like `http` for API calls, `riverpod` for state management, `cached_network_image` for images, and `flutter_animations` for smooth UX. - API Key: Sign up for a free NewsAPI key at [newsapi.org](https://newsapi.org). ### Step 1: Project Setup 1. Create a new Flutter project: ``` flutter create news_reader_app cd news_reader_app ``` 2. Add dependencies to `pubspec.yaml` (run `flutter pub get` after): ```yaml dependencies: flutter: sdk: flutter http: ^1.2.0 # For API requests riverpod: ^2.5.1 # State management cached_network_image: ^3.3.1 # Efficient image loading intl: ^0.19.0 # Date formatting shared_preferences: ^2.2.3 # Local storage for favorites flutter_slidable: ^3.1.0 # Swipe actions animations: ^2.0.11 # For modern animations ``` 3. Enable dark mode and theming in `main.dart` by wrapping your app in `MaterialApp` with themes. ### Step 2: App Structure and Features We'll design a professional, modern UI/UX: - **Modern Elements**: Clean typography (Google Fonts), card-based layouts, smooth animations (e.g., page transitions, loading indicators), responsive design for all screen sizes. - **UI/UX Best Practices**: - **Minimalism**: Use whitespace, subtle shadows, and primary colors (e.g., blue accents for a news app). - **Accessibility**: Add semantics for screen readers, high contrast modes. - **Navigation**: Bottom navigation bar for easy access. - **Themes**: Support light/dark mode with system auto-switch. - **Animations**: Fade-ins, hero animations for images. - **Error Handling**: Graceful loading states and errors. - Screens: - Home: News feed with infinite scrolling. - Search: Filter news by keyword. - Favorites: Saved articles (local storage). - Article Detail: Full view with share button. ### Step 3: Core Code Implementation I'll provide key code snippets. The full app would be structured like this: - `lib/main.dart`: Entry point. - `lib/providers/`: State management (e.g., news_provider.dart). - `lib/screens/`: UI screens (home_screen.dart, etc.). - `lib/models/`: Data models (news_article.dart). - `lib/widgets/`: Reusable components (news_card.dart). #### 1. Data Model (`lib/models/news_article.dart`) ```dart class NewsArticle { final String title; final String description; final String url; final String imageUrl; final String publishedAt; NewsArticle({required this.title, required this.description, required this.url, required this.imageUrl, required this.publishedAt}); factory NewsArticle.fromJson(Map<String, dynamic> json) { return NewsArticle( title: json['title'] ?? 'No Title', description: json['description'] ?? 'No Description', url: json['url'] ?? '', imageUrl: json['urlToImage'] ?? 'https://via.placeholder.com/150', publishedAt: json['publishedAt'] ?? '', ); } } ``` #### 2. State Management (`lib/providers/news_provider.dart`) Using Riverpod for clean, testable state. ```dart import 'package:riverpod/riverpod.dart'; import 'package:http/http.dart' as http; import 'dart:convert'; import '../models/news_article.dart'; final newsProvider = FutureProvider<List<NewsArticle>>((ref) async { const apiKey = 'YOUR_NEWSAPI_KEY'; // Replace with your key final response = await http.get(Uri.parse('https://newsapi.org/v2/top-headlines?country=us&apiKey=$apiKey')); if (response.statusCode == 200) { final data = json.decode(response.body); return (data['articles'] as List).map((json) => NewsArticle.fromJson(json)).toList(); } else { throw Exception('Failed to load news'); } }); ``` #### 3. Main App Entry (`lib/main.dart`) ```dart import 'package:flutter/material.dart'; import 'package:riverpod/riverpod.dart'; import 'package:google_fonts/google_fonts.dart'; // Add to pubspec.yaml: google_fonts: ^6.2.1 import 'screens/home_screen.dart'; void main() { runApp(ProviderScope(child: MyApp())); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'News Reader', theme: ThemeData( primarySwatch: Colors.blue, textTheme: GoogleFonts.poppinsTextTheme(), // Modern font brightness: Brightness.light, cardTheme: CardTheme(elevation: 4, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16))), visualDensity: VisualDensity.adaptivePlatformDensity, ), darkTheme: ThemeData( brightness: Brightness.dark, primarySwatch: Colors.blueGrey, textTheme: GoogleFonts.poppinsTextTheme().apply(bodyColor: Colors.white), ), themeMode: ThemeMode.system, // Auto dark mode home: HomeScreen(), ); } } ``` #### 4. Home Screen (`lib/screens/home_screen.dart`) A modern feed with pull-to-refresh and animations. ```dart import 'package:flutter/material.dart'; import 'package:riverpod/riverpod.dart'; import '../providers/news_provider.dart'; import '../widgets/news_card.dart'; class HomeScreen extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final newsAsync = ref.watch(newsProvider); return Scaffold( appBar: AppBar(title: Text('Top Headlines', style: Theme.of(context).textTheme.titleLarge)), body: RefreshIndicator( onRefresh: () => ref.refresh(newsProvider.future), child: newsAsync.when( data: (news) => ListView.builder( itemCount: news.length, itemBuilder: (context, index) { return AnimatedSlide( // Modern animation offset: index % 2 == 0 ? Offset(0, 0.1) : Offset(0, -0.1), duration: Duration(milliseconds: 500), child: NewsCard(article: news[index]), ); }, ), loading: () => Center(child: CircularProgressIndicator()), error: (err, stack) => Center(child: Text('Error: $err')), ), ), bottomNavigationBar: BottomNavigationBar( items: [ BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Home'), BottomNavigationBarItem(icon: Icon(Icons.search), label: 'Search'), BottomNavigationBarItem(icon: Icon(Icons.favorite), label: 'Favorites'), ], ), ); } } ``` #### 5. Reusable Widget (`lib/widgets/news_card.dart`) Professional card with image, swipe-to-favorite, and hero animation. ```dart import 'package:flutter/material.dart'; import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter_slidable/flutter_slidable.dart'; import '../models/news_article.dart'; class NewsCard extends StatelessWidget { final NewsArticle article; const NewsCard({required this.article}); @override Widget build(BuildContext context) { return Slidable( endActionPane: ActionPane( motion: ScrollMotion(), children: [SlidableAction(onPressed: (_) {}, backgroundColor: Colors.red, icon: Icons.favorite)], ), child: Card( margin: EdgeInsets.all(8), child: ListTile( leading: Hero( tag: article.url, // For smooth transitions to detail screen child: CachedNetworkImage(imageUrl: article.imageUrl, width: 100, fit: BoxFit.cover), ), title: Text(article.title, style: TextStyle(fontWeight: FontWeight.bold)), subtitle: Text(article.description), onTap: () { Navigator.push(context, MaterialPageRoute(builder: (_) => ArticleDetailScreen(article: article))); }, ), ), ); } } ``` #### 6. Additional Screens - **Search Screen**: Similar to Home but with a TextField to filter via API. - **Favorites Screen**: Use `shared_preferences` to store/save articles locally. - **Article Detail Screen**: Full article view with WebView or just text/image, plus share functionality. ### Step 4: Enhancing UI/UX - **Animations**: Use `Hero` for image transitions, `AnimatedBuilder` for custom effects. - **Responsive Design**: Wrap in `MediaQuery` for screen size adaptations. - **Testing**: Run `flutter test` and use device emulators. - **Performance**: Add pagination for infinite scrolling (e.g., with `ListView.builder` and a scroll controller). - **Polish**: Add splash screen, app icon, and localization if needed. ### Step 5: Build and Deploy - Test on emulator: `flutter run`. - Build APK (Android): `flutter build apk --release`. - Build IPA (iOS): `flutter build ios --release` (requires macOS). - For production: Optimize with `flutter build --obfuscate`, add analytics (e.g., Firebase), and publish to Google Play/App Store. ### Final Tips for Professional/Modern Design - **Tools**: Use Figma or Adobe XD for wireframing before coding. - **Inspiration**: Study apps like Google News or Twitter for modern feeds. - **Best Practices**: Follow Flutter's [UI guidelines](https://flutter.dev/docs/development/ui). Use linters (`flutter analyze`) for clean code. - **Extensions**: Add Riverpod for state, Provider for simpler cases, or Bloc if you prefer. This should give you a solid starting point for a professional Flutter app! If you share more details (e.g., specific features or a different app idea), I can provide more tailored code or even a GitHub repo link to a sample project. Let's build something awesome! 🚀
Drag to resize
# Flutter Mobile App Development with Professional UI/UX Here's a comprehensive guide to creating a mobile app with Flutter that features a professional, modern UI/UX design. ## Project Setup First, set up your Flutter project: ```bash flutter create professional_app cd professional_app ``` ## Core Dependencies (pubspec.yaml) ```yaml dependencies: flutter: sdk: flutter cupertino_icons: ^1.0.5 provider: ^6.0.5 flutter_svg: ^2.0.7 flutter_bloc: ^8.1.3 shared_preferences: ^2.2.1 cached_network_image: ^3.3.0 intl: ^0.18.1 google_fonts: ^4.0.4 flutter_screenutil: ^5.9.0 smooth_page_indicator: ^1.1.0 flutter_launcher_icons: ^0.13.1 ``` ## Folder Structure ``` lib/ ├── core/ │ ├── constants/ │ ├── utils/ │ ├── theme/ │ ├── services/ ├── features/ │ ├── auth/ │ ├── home/ │ ├── profile/ │ ├── settings/ ├── widgets/ ├── app.dart ├── main.dart ``` ## Modern UI/UX Implementation ### 1. Custom Theme (theme/app_theme.dart) ```dart import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; class AppTheme { static ThemeData lightTheme = ThemeData( brightness: Brightness.light, primaryColor: const Color(0xFF6C63FF), scaffoldBackgroundColor: Colors.white, colorScheme: ColorScheme.light( primary: const Color(0xFF6C63FF), secondary: const Color(0xFF4DCCC6), surface: Colors.white, background: const Color(0xFFF8F9FA), error: const Color(0xFFFF6584), ), textTheme: TextTheme( displayLarge: GoogleFonts.poppins( fontSize: 32, fontWeight: FontWeight.bold, color: Colors.black, ), displayMedium: GoogleFonts.poppins( fontSize: 24, fontWeight: FontWeight.w600, color: Colors.black, ), bodyLarge: GoogleFonts.poppins( fontSize: 16, fontWeight: FontWeight.normal, color: Colors.black87, ), bodyMedium: GoogleFonts.poppins( fontSize: 14, fontWeight: FontWeight.normal, color: Colors.black54, ), ), appBarTheme: AppBarTheme( elevation: 0, centerTitle: true, backgroundColor: Colors.transparent, titleTextStyle: GoogleFonts.poppins( color: Colors.black, fontSize: 20, fontWeight: FontWeight.w600, ), ), cardTheme: CardTheme( elevation: 2, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), margin: EdgeInsets.zero, ), ); static ThemeData darkTheme = ThemeData( brightness: Brightness.dark, // Dark theme configurations ); } ``` ### 2. Responsive App Scaffold (widgets/app_scaffold.dart) ```dart import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; class AppScaffold extends StatelessWidget { final String? title; final Widget body; final List<Widget>? actions; final Widget? floatingActionButton; final Color? backgroundColor; final bool extendBodyBehindAppBar; final bool showBackButton; final Widget? bottomNavigationBar; const AppScaffold({ Key? key, this.title, required this.body, this.actions, this.floatingActionButton, this.backgroundColor, this.extendBodyBehindAppBar = false, this.showBackButton = true, this.bottomNavigationBar, }) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( extendBodyBehindAppBar: extendBodyBehindAppBar, backgroundColor: backgroundColor ?? Theme.of(context).colorScheme.background, appBar: title == null ? null : AppBar( automaticallyImplyLeading: showBackButton, title: Text( title!, style: Theme.of(context).textTheme.titleLarge, ), actions: actions, elevation: 0, backgroundColor: extendBodyBehindAppBar ? Colors.transparent : Theme.of(context).appBarTheme.backgroundColor, ), body: SafeArea( child: Padding( padding: EdgeInsets.symmetric(horizontal: 16.w), child: body, ), ), floatingActionButton: floatingActionButton, bottomNavigationBar: bottomNavigationBar, ); } } ``` ### 3. Custom Bottom Navigation Bar (widgets/bottom_nav_bar.dart) ```dart import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; class AppBottomNavBar extends StatelessWidget { final int currentIndex; final Function(int) onTap; const AppBottomNavBar({ Key? key, required this.currentIndex, required this.onTap, }) : super(key: key); @override Widget build(BuildContext context) { return Container( decoration: BoxDecoration( boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.1), blurRadius: 10, offset: const Offset(0, -5), ), ], ), child: BottomNavigationBar( currentIndex: currentIndex, onTap: onTap, type: BottomNavigationBarType.fixed, backgroundColor: Theme.of(context).colorScheme.surface, selectedItemColor: Theme.of(context).primaryColor, unselectedItemColor: Colors.grey, selectedLabelStyle: TextStyle(fontSize: 12.sp), unselectedLabelStyle: TextStyle(fontSize: 12.sp), items: const [ BottomNavigationBarItem( icon: Icon(Icons.home_outlined), activeIcon: Icon(Icons.home), label: 'Home', ), BottomNavigationBarItem( icon: Icon(Icons.search), activeIcon: Icon(Icons.search), label: 'Discover', ), BottomNavigationBarItem( icon: Icon(Icons.favorite_outline), activeIcon: Icon(Icons.favorite), label: 'Favorites', ), BottomNavigationBarItem( icon: Icon(Icons.person_outline), activeIcon: Icon(Icons.person), label: 'Profile', ), ], ), ); } } ``` ### 4. Example Feature - Onboarding Screen ```dart import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:smooth_page_indicator/smooth_page_indicator.dart'; class OnboardingScreen extends StatefulWidget { const OnboardingScreen({Key? key}) : super(key: key); @override _OnboardingScreenState createState() => _OnboardingScreenState(); } class _OnboardingScreenState extends State<OnboardingScreen> { final PageController _controller = PageController(); int _currentPage = 0; final List<Map<String, String>> onboardingData = [ { 'title': 'Welcome to Our App', 'description': 'The best solution for your needs with amazing features', 'image': 'assets/images/onboarding1.svg', }, { 'title': 'Easy to Use', 'description': 'Simple and intuitive interface for all users', 'image': 'assets/images/onboarding2.svg', }, { 'title': 'Get Started', 'description': 'Join thousands of satisfied users today', 'image': 'assets/images/onboarding3.svg', }, ]; @override Widget build(BuildContext context) { return AppScaffold( extendBodyBehindAppBar: true, body: Column( children: [ Expanded( child: PageView.builder( controller: _controller, onPageChanged: (index) => setState(() => _currentPage = index), itemCount: onboardingData.length, itemBuilder: (context, index) { return OnboardingPage( title: onboardingData[index]['title']!, description: onboardingData[index]['description']!, imagePath: onboardingData[index]['image']!, ); }, ), ), SizedBox(height: 20.h), SmoothPageIndicator( controller: _controller, count: onboardingData.length, effect: ExpandingDotsEffect( activeDotColor: Theme.of(context).primaryColor, dotColor: Colors.grey.shade300, dotHeight: 8.h, dotWidth: 8.w, spacing: 8.w, ), ), SizedBox(height: 30.h), Padding( padding: EdgeInsets.symmetric(horizontal: 24.w), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ TextButton( onPressed: () => _controller.jumpToPage(onboardingData.length - 1), child: Text( 'Skip', style: Theme.of(context).textTheme.bodyLarge?.copyWith( color: Colors.grey, ), ), ), ElevatedButton( onPressed: () { if (_currentPage < onboardingData.length - 1) { _controller.nextPage( duration: const Duration(milliseconds: 500), curve: Curves.easeInOut, ); } else { Navigator.pushReplacementNamed(context, '/home'); } }, style: ElevatedButton.styleFrom( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(30), ), padding: EdgeInsets.symmetric( horizontal: 24.w, vertical: 12.h, ), ), child: Text( _currentPage == onboardingData.length - 1 ? 'Get Started' : 'Next', ), ), ], ), ), SizedBox(height: 40.h), ], ), ); } } class OnboardingPage extends StatelessWidget { final String title; final String description; final String imagePath; const OnboardingPage({ Key? key, required this.title, required this.description, required this.imagePath, }) : super(key: key); @override Widget build(BuildContext context) { return Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Expanded( flex: 3, child: Padding( padding: EdgeInsets.symmetric(horizontal: 24.w), child: Center( child: Image.asset( imagePath, fit: BoxFit.contain, ), ), ), ), SizedBox(height: 32.h), Text( title, style: Theme.of(context).textTheme.displayMedium?.copyWith( fontWeight: FontWeight.bold, ), textAlign: TextAlign.center, ), SizedBox(height: 16.h), Padding( padding: EdgeInsets.symmetric(horizontal: 24.w), child: Text( description, style: Theme.of(context).textTheme.bodyLarge, textAlign: TextAlign.center, ), ), ], ); } } ``` ## Key UI/UX Principles Implemented 1. **Consistent Design System**: - Color palette with primary, secondary, and semantic colors - Typography hierarchy with Google Fonts - Consistent spacing using ScreenUtil for responsiveness 2. **Responsive Design**: - Adapts to different screen sizes - Pixel-perfect implementation with flutter_screenutil 3. **Micro-Interactions**: - Smooth page transitions - Animated indicators - Visual feedback for actions 4. **Accessibility**: - Sufficient color contrast - Scalable text - Clear visual hierarchy 5. **Modern Components**: - Custom bottom navigation - Responsive app scaffold - Themed buttons and cards ## Additional Recommendations 1. Implement state management with BLoC or Provider 2. Add splash screen and launcher icons using flutter_launcher_icons 3. Use SVG graphics with flutter_svg for crisp assets 4. Implement dark mode support 5. Add animations for core user flows with flutter_animations 6. Set up internationalization for multiple languages 7. Use caching for images with cached_network_image 8. Implement proper error handling and empty states Would you like me to expand on any specific aspect of this implementation or add more example screens?
Drag to resize
Here's a comprehensive guide on how to build a mobile software with Flutter and a professional, modern UI/UX design. **Project Setup** To create a new Flutter project, open your command prompt/terminal and run: ```bash flutter create mobile_software ``` Navigate into the project directory: ```bash cd mobile_software ``` **UI/UX Design** For a modern and professional design, we'll follow Material Design principles and use a clean, intuitive architecture. Let's design a mockup for a simple e-commerce app. The app will have: * A splash screen * A login/register screen * A home screen displaying products * A product details screen * A cart screen We'll use the `flutter/material.dart` library to adhere to Material Design. ### Splash Screen Create a new file `splash_screen.dart`: ```dart // lib/splash_screen.dart import 'package:flutter/material.dart'; class SplashScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( body: Container( child: Center( child: Text('E-commerce', style: TextStyle(fontSize: 24)), ), ), ); } } ``` ### Login/Register Screen Create a new file `login_screen.dart`: ```dart // lib/login_screen.dart import 'package:flutter/material.dart'; class LoginScreen extends StatefulWidget { @override _LoginScreenState createState() => _LoginScreenState(); } class _LoginScreenState extends State<LoginScreen> { final _formKey = GlobalKey<FormState>(); String _email = ''; String _password = ''; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Login'), ), body: Form( key: _formKey, child: Padding( padding: const EdgeInsets.all(16.0), child: Column( children: [ TextFormField( decoration: InputDecoration( labelText: 'Email', border: OutlineInputBorder(), ), TextFormField( obscureText: true, decoration: InputDecoration( labelText: 'Password', border: OutlineInputBorder(), ), SizedBox(height: 16), ElevatedButton( onPressed: () { // Perform login or register }, child: Text('Login'), ), ], ), ), ), ); } } ``` ### Home Screen Create a new file `home_screen.dart`: ```dart // lib/home_screen.dart import 'package:flutter/material.dart'; class HomeScreen extends StatelessWidget { final List<Product> products = [ Product('Product 1', 'assets/product1.jpg', 9.99), Product('Product 2', 'assets/product2.jpg', 19.99), // Add more products... ]; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Home'), ), body: GridView.builder( gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 2, ), itemCount: products.length, itemBuilder: (context, index) { return Card( child: Column( children: [ Expanded( child: Image.asset(products[index].image), ), Text(products[index].name), Text('\$${products[index].price.toStringAsFixed(2)}'), ], ), ); ), ); } } class Product { final String name; final String image; final double price; Product(this.name, this.image, this.price); } ``` ### Product Details Screen Create a new file `product_details_screen.dart`: ```dart // lib/product_details_screen.dart import 'package:flutter/material.dart'; class ProductDetailsScreen extends StatelessWidget { final Product product; ProductDetailsScreen(this.product); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(product.name), ), body: Padding( padding: const EdgeInsets.all(16.0), child: Column( children: [ Image.asset(product.image), Text(product.name), Text('\$${product.price.toStringAsFixed(2)}'), ], ), ); } } ``` ### Cart Screen Create a new file `cart_screen.dart`: ```dart // lib/cart_screen.dart import 'package:flutter/material.dart'; class CartScreen extends StatefulWidget { @override _CartScreenState createState() => _CartScreenState(); } class _CartScreenState extends State<CartScreen> { final List<Product> cart = []; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Cart'), ), body: cart.isEmpty ? Center(child: Text('Cart is empty')) : ListView.builder( itemCount: cart.length, itemBuilder: (context, index) { return ListTile( title: Text(cart[index].name), trailing: Text( '\$${cart[index].price.toStringAsFixed(2)}'), ); ), ); } } ``` ### Navigation To navigate between the different screens, we'll use the `Navigator` widget. ```dart // lib/main.dart import 'package:flutter/material.dart'; import 'splash_screen.dart'; import 'login_screen.dart'; import 'product_details_screen.dart'; import 'cart_screen.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'E-commerce', initialRoute: '/', routes: { '/': (context) => SplashScreen(), '/login': (context) => LoginScreen(), '/home': (context) => HomeScreen(), '/product': (context) => ProductDetailsScreen(), '/cart': (context) => CartScreen(), }, ); } } ``` ### Routing between screens To navigate between the different screens, we'll use the `Navigator.pushNamed()` function. ```dart // Navigate to home screen after successful login Navigator.pushReplacementNamed(context, '/home'); ``` To go to the product details screen when a product is tapped: ```dart // In HomeScreen onTap: () { Navigator.pushNamed(context, '/product', arguments: products[index]); }, ``` To display the cart screen when the cart icon is pressed: ```dart // In AppBar actions IconButton( icon: Icon(Icons.shopping_cart), onPressed: () { Navigator.pushNamed(context, '/cart'); }, ), ``` **State Management** For state management, we can use Provider or Riverpod. Let's use Provider. Add the `provider` package to your `pubspec.yaml`: ```yml dependencies: flutter: sdk: flutter provider: ^4.3.2 ``` To use Provider, wrap your `MaterialApp` with `MultiProvider`: ```dart // lib/main.dart import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; void main() { runApp( MultiProvider( providers: [ ChangeNotifierProvider(create: (_) => ProductProvider()), // Add other providers... ], child: MyApp(), ), ); } ``` Create a `ProductProvider` to manage the products and their state: ```dart // lib/providers/product_provider.dart import 'package:flutter/material.dart'; class ProductProvider with ChangeNotifier { List<Product> _products = []; List<Product> get products => _products; void addProduct(Product product) { _products.add(product); notifyListeners(); } // Other product-related functions... } ``` To access the `ProductProvider` in your screens: ```dart // In HomeScreen final productProvider = Provider.of<ProductProvider>(context); ``` **API Calls** To make API calls, we can use `http` package. Add `http` to your `pubspec.yaml`: ```yml dependencies: flutter: sdk: flutter http: ^0.13.3 ``` To make a GET request: ```dart import 'package:http/http.dart' as http; Future<List<Product>> fetchProducts() async { final response = await http.get(Uri.parse('https://example.com/products')); if (response.statusCode == 200) { // Parse the response and return the products } else { throw Exception('Failed to load products'); } } ``` To make a POST request: ```dart Future<Product> createOrder() async { final response = await http.post( Uri.parse('https://example.com/orders'), headers: { 'Content-Type': 'application/json', }, body: jsonEncode({'product_id': 1, 'quantity': 2}), ); if (response.statusCode == 201) { // Parse the response and return the created order } else { throw Exception('Failed to create order'); } } ``` This is a basic structure for a Flutter e-commerce app. You can add more functionalities like authentication, order management, etc., as needed. Make sure to follow best practices and keep your code clean and readable. To run the app, use: ```bash flutter run ``` **Example Use Cases** 1. User launches the app and is shown the login/register screen. 3. After logging in, the user is taken to the home screen, where they can browse through the product catalog. 5. When a product is selected, they are taken to the product details screen, where they can add the item to their cart. 7. The user can then proceed to checkout and place an order. These are the fundamental components and functionalities needed to create a mobile software with a UI/UX using Flutter.
Drag to resize
### Modern Flutter Expense Tracker App with Elegant UI/UX Here's a professional Flutter app with modern UI/UX principles, featuring a responsive layout, smooth animations, and clean design: ```dart // main.dart import 'package:easy_splash_screen/easy_splash_screen.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:google_fonts/google_fonts.dart'; void main() { runApp(const MyApp()); SystemChrome.setSystemUIOverlayStyle( const SystemUiOverlayStyle( statusBarColor: Colors.transparent, statusBarIconBrightness: Brightness.dark, ), ); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: 'BalanceFlow', debugShowCheckedModeBanner: false, theme: ThemeData( primarySwatch: Colors.blue, scaffoldBackgroundColor: const Color(0xFFF8F9FD), visualDensity: VisualDensity.adaptivePlatformDensity, textTheme: GoogleFonts.poppinsTextTheme(), appBarTheme: const AppBarTheme( elevation: 0, backgroundColor: Colors.transparent, iconTheme: IconThemeData(color: Color(0xFF1D3557)), ), ), home: const SplashScreen(), ); } } class SplashScreen extends StatelessWidget { const SplashScreen({super.key}); @override Widget build(BuildContext context) { return EasySplashScreen( logo: SvgPicture.asset( 'assets/logo.svg', height: 120, ), title: Text( 'BalanceFlow', style: GoogleFonts.poppins( fontSize: 32, fontWeight: FontWeight.w800, color: const Color(0xFF1D3557), ), ), backgroundColor: Theme.of(context).scaffoldBackgroundColor, showLoader: true, loaderColor: const Color(0xFF1D3557), duration: 2500, navigator: const HomeScreen(), ); } } class HomeScreen extends StatefulWidget { const HomeScreen({super.key}); @override State<HomeScreen> createState() => _HomeScreenState(); } class _HomeScreenState extends State<HomeScreen> { int _currentIndex = 0; @override Widget build(BuildContext context) { return Scaffold( appBar: _buildAppBar(), body: _buildBody(), floatingActionButton: _buildFloatingActionButton(), bottomNavigationBar: _buildBottomNavigationBar(), extendBody: true, ); } PreferredSizeWidget _buildAppBar() { return AppBar( title: Text( 'Overview', style: GoogleFonts.poppins( fontWeight: FontWeight.w600, fontSize: 24, color: const Color(0xFF1D3557), ), ), actions: [ IconButton( onPressed: () {}, icon: Container( padding: const EdgeInsets.all(6), decoration: BoxDecoration( color: Colors.deepPurpleAccent.withOpacity(0.15), shape: BoxShape.circle, ), child: const Icon(Icons.notifications_outlined), ), ), ], ); } Widget _buildBody() { return SingleChildScrollView( child: Padding( padding: const EdgeInsets.symmetric(horizontal: 20), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ _buildBalanceCard(), const SizedBox(height: 30), _buildTransactionsHeader(), const SizedBox(height: 20), _buildTransactionList(), ], ), ), ); } Widget _buildBalanceCard() { return Container( padding: const EdgeInsets.all(20), decoration: BoxDecoration( gradient: const LinearGradient( colors: [Color(0xFF316FF6), Color(0xFF3A5FE0)], begin: Alignment.topLeft, end: Alignment.bottomRight, ), borderRadius: BorderRadius.circular(20), boxShadow: [ BoxShadow( color: Colors.blueGrey.withOpacity(0.2), blurRadius: 25, offset: const Offset(0, 10), ) ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Total Balance', style: GoogleFonts.poppins( color: Colors.white70, fontSize: 16, ), ), const SizedBox(height: 10), Text( '\$12,425.50', style: GoogleFonts.poppins( color: Colors.white, fontSize: 36, fontWeight: FontWeight.w700, ), ), const SizedBox(height: 25), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ _buildBalanceStat('Income', '\$5,250.40', true), _buildBalanceStat('Expense', '\$1,824.90', false), ], ) ], ), ); } Widget _buildBalanceStat(String label, String amount, bool isIncome) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( label, style: GoogleFonts.poppins( color: Colors.white70, fontSize: 14, ), ), const SizedBox(height: 6), Text( amount, style: GoogleFonts.poppins( color: Colors.white, fontSize: 20, fontWeight: FontWeight.w600, ), ), ], ); } Widget _buildTransactionsHeader() { return Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( 'Recent Transactions', style: GoogleFonts.poppins( fontSize: 18, fontWeight: FontWeight.w600, color: const Color(0xFF1D3557), ), ), TextButton( onPressed: () {}, child: Text( 'View All', style: GoogleFonts.poppins( fontWeight: FontWeight.w500, color: Colors.blue, ), ), ), ], ); } Widget _buildTransactionList() { final transactions = [ {'emoji': '🍔', 'title': 'Food & Drinks', 'date': 'Today, 12:30', 'amount': '-$42.50', 'color': const Color(0xFFFF9F1C)}, {'emoji': '🛒', 'title': 'Shopping', 'date': 'Yesterday, 16:45', 'amount': '-$238.75', 'color': const Color(0xFFE71D36)}, {'emoji': '💼', 'title': 'Salary', 'date': 'May 30, 08:00', 'amount': '+$3,500.00', 'color': const Color(0xFF2EC4B6)}, {'emoji': '🎬', 'title': 'Entertainment', 'date': 'May 28, 19:20', 'amount': '-$85.00', 'color': const Color(0xFF8F3985)}, {'emoji': '🚕', 'title': 'Transport', 'date': 'May 27, 14:15', 'amount': '-$32.75', 'color': const Color(0xFF3A86FF)}, ]; return ListView.builder( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), itemCount: transactions.length, itemBuilder: (context, index) { final item = transactions[index]; return Padding( padding: const EdgeInsets.only(bottom: 15), child: Container( decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(16), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.05), blurRadius: 15, offset: const Offset(0, 5), ) ], ), child: ListTile( contentPadding: const EdgeInsets.symmetric( horizontal: 20, vertical: 12, ), leading: Container( height: 50, width: 50, decoration: BoxDecoration( color: item['color']!.withOpacity(0.15), borderRadius: BorderRadius.circular(14), ), child: Center( child: Text( item['emoji']!, style: const TextStyle(fontSize: 20), ), ), ), title: Text( item['title']!, style: GoogleFonts.poppins( fontWeight: FontWeight.w600, fontSize: 16, ), ), subtitle: Text( item['date']!, style: GoogleFonts.poppins( color: Colors.grey.shade500, ), ), trailing: Text( item['amount']!, style: GoogleFonts.poppins( color: (item['amount'] as String).contains('-') ? const Color(0xFFE63946) : const Color(0xFF2A9D8F), fontWeight: FontWeight.w600, fontSize: 16, ), ), ), ), ); }, ); } Widget _buildFloatingActionButton() { return FloatingActionButton( onPressed: () {}, backgroundColor: const Color(0xFF316FF6), elevation: 8, child: const Icon( Icons.add, color: Colors.white, size: 30, ), ); } Widget _buildBottomNavigationBar() { return ClipRRect( borderRadius: const BorderRadius.only( topLeft: Radius.circular(24), topRight: Radius.circular(24), ), child: BottomNavigationBar( currentIndex: _currentIndex, onTap: (index) => setState(() => _currentIndex = index), backgroundColor: Colors.white, selectedItemColor: const Color(0xFF316FF6), unselectedItemColor: Colors.grey.shade500, selectedLabelStyle: GoogleFonts.poppins(fontSize: 12), unselectedLabelStyle: GoogleFonts.poppins(fontSize: 12), type: BottomNavigationBarType.fixed, items: [ BottomNavigationBarItem( icon: Padding( padding: const EdgeInsets.only(top: 10, bottom: 5), child: Icon( _currentIndex == 0 ? Icons.home_rounded : Icons.home_outlined, size: 26, ), ), label: 'Home', ), BottomNavigationBarItem( icon: Padding( padding: const EdgeInsets.only(top: 10, bottom: 5), child: Icon( _currentIndex == 1 ? Icons.pie_chart_rounded : Icons.pie_chart_outline_rounded, size: 26, ), ), label: 'Stats', ), BottomNavigationBarItem( icon: Container( height: 60, ), label: '', ), BottomNavigationBarItem( icon: Padding( padding: const EdgeInsets.only(top: 10, bottom: 5), child: Icon( _currentIndex == 3 ? Icons.wallet_rounded : Icons.wallet_outlined, size: 26, ), ), label: 'Wallet', ), BottomNavigationBarItem( icon: Padding( padding: const EdgeInsets.only(top: 10, bottom: 5), child: Icon( _currentIndex == 4 ? Icons.person_rounded : Icons.person_outline_rounded, size: 26, ), ), label: 'Profile', ), ], ), ); } } ``` ### Key Features of this Professional UI: 1. **Modern Visual Hierarchy**: - Gradient balance card with clear visual priority - Floating action button for primary action - Custom curved-bottom navigation bar 2. **UX Best Practices**: - Clear typography using Google Fonts (Poppins) - Consistent spacing and padding - Visual feedback through shadows and animation hints 3. **Responsive Design**: - Adapts to different screen sizes - Appropriate whitespace on all devices - Scrollable content areas 4. **Visual Elements**: - Emoji-based categories for intuitive recognition - Color-coded income/expense indicators - Soft shadows for depth perception 5. **Navigation**: - Centered FAB for primary action - Five-tab navigation with inactive states - Custom navigational affordances ### To Run This App: 1. Add these dependencies to your `pubspec.yaml`: ```yaml dependencies: flutter: sdk: flutter easy_splash_screen: ^1.4.0 google_fonts: ^4.0.4 flutter_svg: ^2.0.7 ``` 2. Create an SVG file at `assets/logo.svg` for the splash screen 3. Add this flutter_native_splash configuration to your `pubspec.yaml`: ```yaml flutter_native_splash: color: "#F8F9FD" image: assets/logo.svg ``` This implementation follows Material Design 3 principles while incorporating modern fintech app aesthetics with a clean, functional interface. Add your own SVG logo assets to complete the branding.
Drag to resize
I'll help you create a professional mobile app using Flutter with modern UI/UX design. Let me create a complete example of a financial dashboard app with clean, modern design principles. ## Project Structure First, let's set up the project structure: ```yaml # pubspec.yaml name: modern_finance_app description: A professional finance app with modern UI/UX version: 1.0.0+1 environment: sdk: '>=3.0.0 <4.0.0' flutter: ">=3.10.0" dependencies: flutter: sdk: flutter cupertino_icons: ^1.0.2 google_fonts: ^6.1.0 fl_chart: ^0.65.0 animations: ^2.0.8 provider: ^6.1.1 dev_dependencies: flutter_test: sdk: flutter flutter_lints: ^3.0.0 flutter: uses-material-design: true assets: - assets/images/ ``` ## Core Theme Configuration ```dart // lib/core/theme/app_theme.dart import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; class AppTheme { static const Color primaryColor = Color(0xFF6C5CE7); static const Color secondaryColor = Color(0xFFA29BFE); static const Color accentColor = Color(0xFF00CEC9); static const Color backgroundColor = Color(0xFFF8F9FA); static const Color surfaceColor = Color(0xFFFFFFFF); static const Color errorColor = Color(0xFFE17055); static const Color successColor = Color(0xFF00B894); static const Color warningColor = Color(0xFFFDCB6E); static const Color textPrimary = Color(0xFF2D3436); static const Color textSecondary = Color(0xFF636E72); static const Color textLight = Color(0xFFB2BEC3); static ThemeData get lightTheme { return ThemeData( useMaterial3: true, colorScheme: ColorScheme.fromSeed( seedColor: primaryColor, brightness: Brightness.light, ), textTheme: GoogleFonts.interTextTheme(), scaffoldBackgroundColor: backgroundColor, appBarTheme: AppBarTheme( backgroundColor: Colors.transparent, elevation: 0, scrolledUnderElevation: 0, titleTextStyle: GoogleFonts.inter( fontSize: 20, fontWeight: FontWeight.w600, color: textPrimary, ), iconTheme: const IconThemeData(color: textPrimary), ), cardTheme: CardTheme( color: surfaceColor, elevation: 0, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(16), side: BorderSide( color: Colors.grey.shade200, width: 1, ), ), ), elevatedButtonTheme: ElevatedButtonThemeData( style: ElevatedButton.styleFrom( backgroundColor: primaryColor, foregroundColor: Colors.white, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 24), textStyle: GoogleFonts.inter( fontSize: 16, fontWeight: FontWeight.w600, ), ), ), ); } } ``` ## Custom Widgets ```dart // lib/widgets/custom_card.dart import 'package:flutter/material.dart'; import '../core/theme/app_theme.dart'; class CustomCard extends StatelessWidget { final Widget child; final EdgeInsets? padding; final VoidCallback? onTap; final Color? color; const CustomCard({ Key? key, required this.child, this.padding, this.onTap, this.color, }) : super(key: key); @override Widget build(BuildContext context) { return Container( decoration: BoxDecoration( color: color ?? AppTheme.surfaceColor, borderRadius: BorderRadius.circular(16), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.04), blurRadius: 10, offset: const Offset(0, 4), ), ], ), child: Material( color: Colors.transparent, child: InkWell( onTap: onTap, borderRadius: BorderRadius.circular(16), child: Padding( padding: padding ?? const EdgeInsets.all(20), child: child, ), ), ), ); } } ``` ```dart // lib/widgets/balance_card.dart import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; import '../core/theme/app_theme.dart'; import 'custom_card.dart'; class BalanceCard extends StatelessWidget { final String title; final String amount; final String change; final bool isPositive; final Color? gradientStart; final Color? gradientEnd; const BalanceCard({ Key? key, required this.title, required this.amount, required this.change, required this.isPositive, this.gradientStart, this.gradientEnd, }) : super(key: key); @override Widget build(BuildContext context) { return Container( height: 180, decoration: BoxDecoration( gradient: LinearGradient( colors: [ gradientStart ?? AppTheme.primaryColor, gradientEnd ?? AppTheme.secondaryColor, ], begin: Alignment.topLeft, end: Alignment.bottomRight, ), borderRadius: BorderRadius.circular(20), boxShadow: [ BoxShadow( color: (gradientStart ?? AppTheme.primaryColor).withOpacity(0.3), blurRadius: 20, offset: const Offset(0, 10), ), ], ), child: Padding( padding: const EdgeInsets.all(24), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( title, style: GoogleFonts.inter( fontSize: 16, color: Colors.white.withOpacity(0.9), fontWeight: FontWeight.w500, ), ), const Spacer(), Text( amount, style: GoogleFonts.inter( fontSize: 32, color: Colors.white, fontWeight: FontWeight.w700, ), ), const SizedBox(height: 8), Row( children: [ Icon( isPositive ? Icons.trending_up : Icons.trending_down, color: Colors.white, size: 16, ), const SizedBox(width: 4), Text( change, style: GoogleFonts.inter( fontSize: 14, color: Colors.white.withOpacity(0.9), fontWeight: FontWeight.w500, ), ), ], ), ], ), ), ); } } ``` ```dart // lib/widgets/transaction_item.dart import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; import '../core/theme/app_theme.dart'; import '../models/transaction.dart'; class TransactionItem extends StatelessWidget { final Transaction transaction; const TransactionItem({Key? key, required this.transaction}) : super(key: key); @override Widget build(BuildContext context) { return Container( margin: const EdgeInsets.only(bottom: 12), decoration: BoxDecoration( color: AppTheme.surfaceColor, borderRadius: BorderRadius.circular(16), border: Border.all(color: Colors.grey.shade200), ), child: ListTile( contentPadding: const EdgeInsets.all(16), leading: Container( width: 48, height: 48, decoration: BoxDecoration( color: transaction.category.color.withOpacity(0.1), borderRadius: BorderRadius.circular(12), ), child: Icon( transaction.category.icon, color: transaction.category.color, size: 24, ), ), title: Text( transaction.description, style: GoogleFonts.inter( fontSize: 16, fontWeight: FontWeight.w600, color: AppTheme.textPrimary, ), ), subtitle: Text( transaction.category.name, style: GoogleFonts.inter( fontSize: 14, color: AppTheme.textSecondary, ), ), trailing: Column( crossAxisAlignment: CrossAxisAlignment.end, mainAxisAlignment: MainAxisAlignment.center, children: [ Text( '${transaction.isExpense ? '-' : '+'}\$${transaction.amount.toStringAsFixed(2)}', style: GoogleFonts.inter( fontSize: 16, fontWeight: FontWeight.w600, color: transaction.isExpense ? AppTheme.errorColor : AppTheme.successColor, ), ), Text( transaction.date, style: GoogleFonts.inter( fontSize: 12, color: AppTheme.textLight, ), ), ], ), ), ); } } ``` ## Data Models ```dart // lib/models/transaction.dart import 'package:flutter/material.dart'; class TransactionCategory { final String name; final IconData icon; final Color color; TransactionCategory({ required this.name, required this.icon, required this.color, }); } class Transaction { final String id; final String description; final double amount; final TransactionCategory category; final String date; final bool isExpense; Transaction({ required this.id, required this.description, required this.amount, required this.category, required this.date, required this.isExpense, }); } ``` ## Main Screen ```dart // lib/screens/home_screen.dart import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:animations/animations.dart'; import '../core/theme/app_theme.dart'; import '../widgets/balance_card.dart'; import '../widgets/custom_card.dart'; import '../widgets/transaction_item.dart'; import '../models/transaction.dart'; class HomeScreen extends StatefulWidget { const HomeScreen({Key? key}) : super(key: key); @override State<HomeScreen> createState() => _HomeScreenState(); } class _HomeScreenState extends State<HomeScreen> with TickerProviderStateMixin { late AnimationController _animationController; late Animation<double> _fadeAnimation; late Animation<Offset> _slideAnimation; final List<Transaction> _transactions = [ Transaction( id: '1', description: 'Grocery Shopping', amount: 85.50, category: TransactionCategory( name: 'Food', icon: Icons.local_grocery_store, color: AppTheme.errorColor, ), date: 'Today', isExpense: true, ), Transaction( id: '2', description: 'Salary Deposit', amount: 3500.00, category: TransactionCategory( name: 'Income', icon: Icons.account_balance_wallet, color: AppTheme.successColor, ), date: 'Yesterday', isExpense: false, ), Transaction( id: '3', description: 'Netflix Subscription', amount: 15.99, category: TransactionCategory( name: 'Entertainment', icon: Icons.movie, color: AppTheme.warningColor, ), date: '2 days ago', isExpense: true, ), ]; @override void initState() { super.initState(); _animationController = AnimationController( duration: const Duration(milliseconds: 1000), vsync: this, ); _fadeAnimation = Tween<double>(begin: 0.0, end: 1.0).animate( CurvedAnimation(parent: _animationController, curve: Curves.easeInOut), ); _slideAnimation = Tween<Offset>( begin: const Offset(0, 0.3), end: Offset.zero, ).animate( CurvedAnimation(parent: _animationController, curve: Curves.easeOutCubic), ); _animationController.forward(); } @override void dispose() { _animationController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( body: SafeArea( child: FadeTransition( opacity: _fadeAnimation, child: SlideTransition( position: _slideAnimation, child: CustomScrollView( slivers: [ _buildAppBar(), SliverToBoxAdapter( child: Padding( padding: const EdgeInsets.all(20), child: Column( children: [ _buildBalanceSection(), const SizedBox(height: 32), _buildQuickActions(), const SizedBox(height: 32), _buildTransactionsSection(), ], ), ), ), ], ), ), ), ), floatingActionButton: FloatingActionButton.extended( onPressed: () { // Add transaction functionality }, backgroundColor: AppTheme.primaryColor, foregroundColor: Colors.white, icon: const Icon(Icons.add), label: Text( 'Add Transaction', style: GoogleFonts.inter(fontWeight: FontWeight.w600), ), ), ); } SliverAppBar _buildAppBar() { return SliverAppBar( floating: true, backgroundColor: Colors.transparent, elevation: 0, flexibleSpace: Padding( padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10), child: Row( children: [ Container( width: 48, height: 48, decoration: BoxDecoration( color: AppTheme.primaryColor.withOpacity(0.1), borderRadius: BorderRadius.circular(12), ), child: const Icon( Icons.person, color: AppTheme.primaryColor, ), ), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.center, children: [ Text( 'Good morning,', style: GoogleFonts.inter( fontSize: 14, color: AppTheme.textSecondary, ), ), Text( 'John Doe', style: GoogleFonts.inter( fontSize: 18, fontWeight: FontWeight.w600, color: AppTheme.textPrimary, ), ), ], ), ), IconButton( onPressed: () {}, icon: const Icon(Icons.notifications_outlined), style: IconButton.styleFrom( backgroundColor: AppTheme.surfaceColor, side: BorderSide(color: Colors.grey.shade200), ), ), ], ), ), ); } Widget _buildBalanceSection() { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const BalanceCard( title: 'Total Balance', amount: '\$12,485.50', change: '+2.5% from last month', isPositive: true, ), const SizedBox(height: 16), Row( children: [ Expanded( child: BalanceCard( title: 'Income', amount: '\$8,240', change: '+15%', isPositive: true, gradientStart: AppTheme.successColor, gradientEnd: AppTheme.successColor.withOpacity(0.8), ), ), const SizedBox(width: 16), Expanded( child: BalanceCard( title: 'Expenses', amount: '\$3,890', change: '-8%', isPositive: false, gradientStart: AppTheme.errorColor, gradientEnd: AppTheme.errorColor.withOpacity(0.8), ), ), ], ), ], ); } Widget _buildQuickActions() { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Quick Actions', style: GoogleFonts.inter( fontSize: 20, fontWeight: FontWeight.w600, color: AppTheme.textPrimary, ), ), const SizedBox(height: 16), Row( children: [ Expanded( child: _buildActionButton( icon: Icons.send, label: 'Send', color: AppTheme.primaryColor, ), ), const SizedBox(width: 12), Expanded( child: _buildActionButton( icon: Icons.download, label: 'Request', color: AppTheme.accentColor, ), ), const SizedBox(width: 12), Expanded( child: _buildActionButton( icon: Icons.account_balance, label: 'Bills', color: AppTheme.warningColor, ), ), const SizedBox(width: 12), Expanded( child: _buildActionButton( icon: Icons.more_horiz, label: 'More', color: AppTheme.textSecondary, ), ), ], ), ], ); } Widget _buildActionButton({ required IconData icon, required String label, required Color color, }) { return CustomCard( onTap: () {}, child: Column( children: [ Container( width: 48, height: 48, decoration: BoxDecoration( color: color.withOpacity(0.1), borderRadius: BorderRadius.circular(12), ), child: Icon(icon, color: color, size: 24), ), const SizedBox(height: 8), Text( label, style: GoogleFonts.inter( fontSize: 12, fontWeight: FontWeight.w500, color: AppTheme.textSecondary, ), ), ], ), ); } Widget _buildTransactionsSection() { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( 'Recent Transactions', style: GoogleFonts.inter( fontSize: 20, fontWeight: FontWeight.w600, color: AppTheme.textPrimary, ), ), TextButton( onPressed: () {}, child: Text( 'View All', style: GoogleFonts.inter( fontSize: 14, fontWeight: FontWeight.w600, color: AppTheme.primaryColor, ), ), ), ], ), const SizedBox(height: 16), ListView.builder( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), itemCount: _transactions.length, itemBuilder: (context, index) { return OpenContainer( closedElevation: 0, openElevation: 0, closedShape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(16), ), transitionDuration: const Duration(milliseconds: 300), closedBuilder: (context, action) => TransactionItem( transaction: _transactions[index], ), openBuilder: (context, action) => const TransactionDetailScreen(), ); }, ), ], ); } } class TransactionDetailScreen extends StatelessWidget { const TransactionDetailScreen({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Transaction Details'), ), body: const Center( child: Text('Transaction Detail View'), ), ); } } ``` ## Main App ```dart // lib/main.dart import 'package:flutter/material.dart'; import 'core/theme/app_theme.dart'; import 'screens/home_screen.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp( title: 'Modern Finance App', theme: AppTheme.lightTheme, home: const HomeScreen(), debugShowCheckedModeBanner: false, ); } } ``` ## Key Features of This Modern UI/UX Design: ### 🎨 **Design Principles** - **Clean & Minimal**: Plenty of white space and clean layouts - **Consistent**: Unified color scheme and typography - **Modern**: Latest Material Design 3 principles - **Professional**: Business-ready appearance ### 🌟 **UI/UX Features** - **Gradient Cards**: Beautiful gradient backgrounds for balance cards - **Smooth Animations**: Fade and slide animations for better UX - **Custom Shadows**: Subtle shadows for depth - **Rounded Corners**: Modern rounded design language - **Color Psychology**: Professional color palette - **Typography**: Google Fonts (Inter) for readability ### 📱 **Interactive Elements** - **Floating Action Button**: Easy access to primary actions - **OpenContainer**: Smooth transitions between screens - **Custom Cards**: Reusable card components - **Quick Actions**: Easy access buttons with icons ### 🔧 **Technical Excellence** - **Modular Structure**: Well-organized code architecture - **Reusable Widgets**: Custom components for consistency - **Theme System**: Centralized styling - **Responsive Design**: Adapts to different screen sizes ### 🎭 **Modern Features** - **Material 3**: Latest design system - **Micro-interactions**: Subtle hover effects - **Professional Icons**: Consistent iconography - **Data Visualization Ready**: Structure for charts/graphs This creates a professional, modern financial app with excellent UI/UX that follows current design trends and best practices. The code is well-structured, maintainable, and easily extensible for additional features.
Drag to resize