Skip to content

Latest commit

 

History

History
535 lines (426 loc) · 12.2 KB

File metadata and controls

535 lines (426 loc) · 12.2 KB

FlutterX API Guide

This guide provides detailed information about FlutterX adaptive widgets and their usage patterns.

Table of Contents

Core Concepts

Adaptive Design

FlutterX widgets automatically adapt their appearance and behavior based on the target platform:

  • iOS: Uses Cupertino design system (rounded corners, blur effects, native iOS styling)
  • Android/Web/Desktop: Uses Material Design (shadows, elevation, Material 3 styling)

Unified API

All Fx widgets maintain the same API regardless of platform:

// This works identically on iOS and Android
FxButton(
  onPressed: () => print('Pressed'),
  child: Text('Press Me'),
)

Theme Integration

Widgets automatically use FxTheme.of(context) to apply consistent theming:

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final theme = FxTheme.of(context);
    return FxButton(
      color: theme.buttonColor,
      textColor: theme.buttonTextColor,
      child: Text('Themed Button'),
    );
  }
}

Widget Categories

App & Layout Widgets

Widget Description Example
FxApp Root application widget with theming FxApp(home: HomePage(), fxTheme: FxThemeData.light())
FxScaffold Screen layout with app bar and body FxScaffold(appBar: FxAppBar(...), body: ...)
FxSliverAppBar App bar with scroll effects Used for collapsible headers

Interactive Widgets

Widget Description Common Properties
FxButton Primary action button onPressed, color, textColor, disabled
FxTextButton Secondary button onPressed, color, padding
FxIconButton Icon-only button icon, onPressed, color

Form & Input Widgets

Widget Description Validation
FxTextField Text input field controller, validator, decoration
FxSwitch Toggle switch value, onChanged, activeColor
FxSlider Value selection value, onChanged, min, max
FxCheckbox Multiple choice value, onChanged
FxRadio Single choice value, onChanged, groupValue
FxDropdownButton Select from list value, items, onChanged

Navigation Widgets

Widget Description Useful For
FxAppBar Screen header with actions All screens with headers
FxTabBar Tab navigation Multi-tab interfaces
FxTabScaffold Tab-based layout Tabbed applications
FxBottomNavigationBar Bottom navigation Mobile apps

Feedback Widgets

Widget Description Use Case
FxActivityIndicator Loading indicator Asynchronous operations
FxProgressBar Progress display File uploads, long operations
FxSnackBar Toast messages User feedback

Dialog & Modal Widgets

Widget Description Platform Adaptation
FxAlertDialog Modal dialogs Material AlertDialog vs CupertinoAlertDialog
FxModalBottomSheet Bottom sheet modal Platform-specific animations

Platform-Specific Behavior

iOS (Cupertino) Behavior

  • Widgets use rounded corners and blur effects
  • Buttons often use system colors like CupertinoColors.activeBlue
  • Text selection uses iOS-style handles
  • Gestures may use different thresholds
// iOS-specific considerations
FxButton(
  onPressed: onPressed,
  child: Text('Button'),
)
// Renders as CupertinoButton with iOS styling

Android/Web/Desktop (Material) Behavior

  • Widgets use elevation and shadows
  • Material 3 styling with dynamic colors (if enabled)
  • Keyboard shortcuts and mouse interactions
  • Consistent 4dp grid alignment
// Material-specific considerations
FxButton(
  onPressed: onPressed,
  child: Text('Button'),
)
// Renders as ElevatedButton with Material styling

Platform Detection & Manual Control

Use FxPlatform for platform-specific logic:

import 'package:flutterx/flutterx.dart';

// Platform checks
if (FxPlatform.isIOS) {
  // iOS-specific behavior
}

if (FxPlatform.useCupertino) {
  // Show Cupertino-specific UI
} else {
  // Show Material-specific UI
}

// Manual platform override (advanced)
if (FxPlatform.isWeb) {
  return FxMaterial(child: myWidget); // Force Material on web
}

Theming System

FxThemeData Structure

FxThemeData(
  // Color palette
  primaryColor: Colors.blue,
  backgroundColor: Colors.white,
  surfaceColor: Colors.white,

  // Component colors
  buttonColor: Colors.blue,
  buttonTextColor: Colors.white,
  appBarColor: Colors.blue,
  appBarTextColor: Colors.white,

  // Text colors
  textColor: Colors.black,
  secondaryTextColor: Colors.grey[600],
  disabledColor: Colors.grey,

  // Dimensions
  borderRadius: 8.0,
  defaultPadding: EdgeInsets.all(16),

  // Typography
  headlineTextStyle: TextStyle(...),
  bodyTextStyle: TextStyle(...),
)

Built-in Themes

// Predefined themes
FxThemeData.light()  // Light theme with blue accent
FxThemeData.dark()   // Dark theme with blue accent

// Custom themes
FxThemeData(
  primaryColor: Colors.green,
  // ... customize other properties
)

Dynamic Theming

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  bool _isDark = false;

  void _toggleTheme() {
    setState(() {
      _isDark = !_isDark;
    });
  }

  @override
  Widget build(BuildContext context) {
    return FxApp(
      fxTheme: _isDark ? FxThemeData.dark() : FxThemeData.light(),
      home: HomePage(onThemeToggle: _toggleTheme),
    );
  }
}

Best Practices

1. Let FlutterX Handle Platform Adaptation

// ✅ Good - Let FlutterX adapt
FxButton(onPressed: onPressed, child: Text('OK'))

// ❌ Bad - Manual platform switching
Platform.isIOS ? CupertinoButton(...) : ElevatedButton(...)

2. Use Consistent Property Names

// ✅ Good - Fx widgets use consistent APIs
FxTextField(placeholder: 'Enter name')
FxSlider(value: _value, onChanged: _onChanged)

// ❌ Bad - Platform-specific properties
FxTextField(hintText: 'Enter name') // Only works on Android

3. Leverage Theming

// ✅ Good - Theme-based customization
class ThemedCard extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final theme = FxTheme.of(context);
    return Card(
      color: theme.surfaceColor,
      child: FxButton(
        color: theme.primaryColor,
        child: Text(
          'Action',
          style: TextStyle(color: theme.buttonTextColor),
        ),
      ),
    );
  }
}

4. Handle Platform Differences

// ✅ Good - Platform-aware behavior
FxButton(
  onPressed: isLoading ? null : _submit,
  child: Text(isLoading ? 'Submitting...' : 'Submit'),
)

// ✅ Good - Platform-specific features
if (FxPlatform.isIOS) {
  showFxCupertinoPickerDialog(context);
} else {
  showFxMaterialDialog(context);
}

API Reference Details

Common Widget Properties

Layout Properties

  • padding: EdgeInsetsGeometry - Internal spacing
  • margin: EdgeInsetsGeometry - External spacing
  • width: double - Fixed width
  • height: double - Fixed height
  • constraints: BoxConstraints - Size constraints

Visual Properties

  • color: Color - Background color
  • foregroundColor: Color - Text and icon color
  • shadowColor: Color - Shadow color
  • borderRadius: BorderRadius - Corner radius

Interaction Properties

  • onPressed: VoidCallback - Press handler
  • onChanged: ValueChanged - Value change handler
  • enabled: bool - Enable/disable widget
  • autofocus: bool - Auto-focus on build

Advanced Configuration

Custom Styling

FxButton(
  onPressed: onPressed,
  style: FxButtonStyle(
    backgroundColor: Colors.red,
    border: Border.all(color: Colors.white),
    borderRadius: BorderRadius.circular(25),
    padding: EdgeInsets.symmetric(horizontal: 24, vertical: 12),
  ),
  child: Text('Styled Button'),
)

Animation Control

FxButton(
  onPressed: onPressed,
  animationDuration: Duration(milliseconds: 200),
  curve: Curves.easeInOut,
  child: Text('Animated Button'),
)

Accessibility

FxButton(
  onPressed: onPressed,
  semanticLabel: 'Submit form',
  excludeFromSemantics: false,
  child: Text('Submit'),
)

Error Handling

class SafeFxButton extends StatelessWidget {
  final VoidCallback? onPressed;

  const SafeFxButton({required this.onPressed});

  @override
  Widget build(BuildContext context) {
    try {
      return FxButton(
        onPressed: onPressed,
        child: Text('Safe Button'),
      );
    } catch (e) {
      // Fallback for any styling errors
      return TextButton(
        onPressed: onPressed,
        child: Text('Safe Button'),
      );
    }
  }
}

Migration Guide

Migrating from Material/Cupertino Widgets

Before (Material only):

ElevatedButton(
  onPressed: onPressed,
  style: ElevatedButton.styleFrom(
    backgroundColor: Colors.blue,
    foregroundColor: Colors.white,
  ),
  child: Text('Button'),
)

After (Cross-platform):

FxButton(
  onPressed: onPressed,
  color: Colors.blue,
  textColor: Colors.white,
  child: Text('Button'),
)

Theming Migration

Before:

Theme(
  data: ThemeData(
    primaryColor: Colors.blue,
    elevatedButtonTheme: ElevatedButtonThemeData(
      style: ElevatedButton.styleFrom(
        backgroundColor: Colors.blue,
      ),
    ),
  ),
  child: MyApp(),
)

After:

FxApp(
  fxTheme: FxThemeData.light().copyWith(
    primaryColor: Colors.blue,
    buttonColor: Colors.blue,
  ),
  child: MyApp(),
)

Troubleshooting

Common Issues

Widget Not Adapting

  • Ensure you're using Fx widgets (FxButton, not ElevatedButton)
  • Check that FxApp is used as the root widget

Theme Not Applying

  • Verify FxTheme.of(context) is called inside build methods
  • Ensure FxApp(fxTheme: ...) is set

Platform Detection Issues

  • FxPlatform uses defaultTargetPlatform
  • Web detection requires kIsWeb flag

Debug Tips

// Debug platform information
print('Platform: ${FxPlatform.isIOS ? "iOS" : "Android"}');
print('Using Cupertino: ${FxPlatform.useCupertino}');

// Debug theme information
final theme = FxTheme.of(context);
print('Theme primary color: ${theme.primaryColor}');

// Debug widget tree
debugDumpApp();

Performance Considerations

Widget Build Optimization

class OptimizedWidget extends StatelessWidget {
  const OptimizedWidget({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    // ✅ Extract theme once
    final theme = FxTheme.of(context);
    final platform = FxPlatform.useCupertino;

    return FxScaffold(
      appBar: FxAppBar(
        backgroundColor: theme.appBarColor,
        title: Text(
          'Title',
          style: TextStyle(color: theme.appBarTextColor),
        ),
      ),
      body: Column(
        children: [
          FxButton(
            color: theme.buttonColor,
            onPressed: () => debugPrint('Pressed on ${platform ? "iOS" : "Android"}'),
            child: Text('Button'),
          ),
        ],
      ),
    );
  }
}

Avoiding Unnecessary Rebuilds

class SmartFxButton extends StatelessWidget {
  final String label;
  final VoidCallback? onPressed;

  const SmartFxButton({
    Key? key,
    required this.label,
    this.onPressed,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    // Only rebuilds when theme changes, not every parent rebuild
    final theme = FxTheme.of(context);

    return FxButton(
      color: theme.buttonColor,
      onPressed: onPressed,
      child: Text(label),
    );
  }
}

This comprehensive guide covers the core concepts, usage patterns, and best practices for FlutterX. For more detailed API documentation, see the generated docs in the docs/ directory.