flexi_ui 1.0.0 copy "flexi_ui: ^1.0.0" to clipboard
flexi_ui: ^1.0.0 copied to clipboard

A powerful Flutter package for adaptive and responsive UIs with fluid scaling, breakpoints, and component-level responsiveness.

example/flexi_ui_example.dart

import 'package:flexi_ui/flexi_ui.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const FlexiConfig(
      child: MaterialApp(
        debugShowCheckedModeBanner: false,
        themeMode: ThemeMode.light,
        home: HomeScreen(),
      ),
    );
  }
}

class HomeScreen extends StatefulWidget {
  const HomeScreen({super.key});

  @override
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  int _rebuildCount = 0;

  @override
  Widget build(BuildContext context) {
    _rebuildCount++;
    return Scaffold(
      appBar: AppBar(
        title: const Text('Flexi UI Performance Demo'),
        backgroundColor: Colors.deepPurple,
        foregroundColor: Colors.white,
      ),
      body: SingleChildScrollView(
        padding: const EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            _buildSectionTitle('Performance Proof (Resize Window!)'),
            const SizedBox(height: 10),
            const Text(
              'The green card is a heavy widget marked as "const". It should not rebuild even when the window is resized, whereas the blue card will.',
              style: TextStyle(fontSize: 12, color: Colors.grey),
            ),
            const SizedBox(height: 16),
            Row(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Expanded(
                  child: _PerformanceCard(
                    title: 'Responsive Card',
                    subtitle: 'Subscribes to width',
                    color: Colors.blue.shade50,
                    child: Builder(builder: (context) {
                      return Text(
                        'Width: ${100.w(context).toStringAsFixed(1)}',
                        style: const TextStyle(fontWeight: FontWeight.bold),
                      );
                    }),
                  ),
                ),
                const SizedBox(width: 16),
                const Expanded(
                  child: _PerformanceCard(
                    title: 'Heavy Const Widget',
                    subtitle: 'Cached by Flutter',
                    color: Colors.green,
                    child: HeavyConstWidget(),
                  ),
                ),
              ],
            ),
            const SizedBox(height: 32),
            _buildSectionTitle('Discrete Responsiveness'),
            const SizedBox(height: 10),
            const Text(
              'Uses BreakpointValue to change values in steps (+ color change).',
              style: TextStyle(fontSize: 12, color: Colors.grey),
            ),
            const SizedBox(height: 16),
            const BreakpointDemo(),
            const SizedBox(height: 32),
            const SizedBox(height: 32),
            _buildSectionTitle('Fluid Scaling (Proportional)'),
            const SizedBox(height: 10),
            const Text(
              'Uses Tuple2.aw(context) to scale values proportionally between 360px and 1440px width.',
              style: TextStyle(fontSize: 12, color: Colors.grey),
            ),
            const SizedBox(height: 16),
            const FluidScalingDemo(),
            const SizedBox(height: 32),
            _buildSectionTitle('Nested Parent Scaling'),
            const SizedBox(height: 10),
            const ResponsiveLayout(
              targetWidth: 400,
              child: Padding(
                padding: EdgeInsets.all(16.0),
                child: ColorGrid(),
              ),
            ),
            const SizedBox(height: 40),
            Center(
              child: Container(
                padding:
                    const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
                decoration: BoxDecoration(
                  color: Colors.black.withValues(alpha: 0.05),
                  borderRadius: BorderRadius.circular(20),
                ),
                child: Text(
                  'HomeScreen Build Sequence: $_rebuildCount',
                  style: TextStyle(
                      color: Colors.grey.shade600,
                      fontSize: 13,
                      fontWeight: FontWeight.bold),
                ),
              ),
            ),
            const SizedBox(height: 20),
          ],
        ),
      ),
    );
  }

  Widget _buildSectionTitle(String title) {
    return Text(
      title,
      style: const TextStyle(
          fontSize: 20, fontWeight: FontWeight.bold, letterSpacing: -0.5),
    );
  }
}

class _PerformanceCard extends StatelessWidget {
  final String title;
  final String subtitle;
  final Widget child;
  final Color color;

  const _PerformanceCard({
    required this.title,
    required this.subtitle,
    required this.child,
    required this.color,
  });

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.all(16),
      decoration: BoxDecoration(
        color: color,
        borderRadius: BorderRadius.circular(16),
        boxShadow: [
          BoxShadow(
            color: Colors.black.withValues(alpha: 0.05),
            blurRadius: 10,
            offset: const Offset(0, 4),
          ),
        ],
      ),
      child: Column(
        children: [
          Text(title, style: const TextStyle(fontWeight: FontWeight.bold)),
          Text(subtitle,
              style: const TextStyle(fontSize: 10, color: Colors.black54)),
          const Divider(height: 24),
          child,
        ],
      ),
    );
  }
}

class HeavyConstWidget extends StatefulWidget {
  const HeavyConstWidget({super.key});

  @override
  State<HeavyConstWidget> createState() => _HeavyConstWidgetState();
}

class _HeavyConstWidgetState extends State<HeavyConstWidget> {
  int _builds = 0;

  @override
  Widget build(BuildContext context) {
    _builds++;
    // Simulate expensive computation
    for (int i = 0; i < 500000; i++) {
      // Loop
    }
    return Column(
      children: [
        const Icon(Icons.verified, color: Colors.green, size: 32),
        const SizedBox(height: 8),
        Text(
          'Builds: $_builds',
          style: const TextStyle(
              fontSize: 22, fontWeight: FontWeight.bold, color: Colors.green),
        ),
      ],
    );
  }
}

class BreakpointDemo extends StatelessWidget {
  const BreakpointDemo({super.key});

  @override
  Widget build(BuildContext context) {
    const label = BreakpointValue<String>(
      mobile: 'MOBILE',
      tablet: 'TABLET / LANDSCAPE',
      desktop: 'DESKTOP',
    );
    const bgColor = BreakpointValue<Color>(
      mobile: Colors.orange,
      tablet: Colors.blue,
      desktop: Colors.purple,
    );

    return Container(
      height: 120,
      width: double.infinity,
      decoration: BoxDecoration(
        color: bgColor.v(context).withValues(alpha: 0.1),
        borderRadius: BorderRadius.circular(16),
        border: Border.all(color: bgColor.v(context), width: 2),
      ),
      child: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(
              label.v(context),
              style: TextStyle(
                color: bgColor.v(context),
                fontSize: 24,
              ),
            ),
            const Text('Discrete Breakpoint Triggered',
                style: TextStyle(fontSize: 10)),
          ],
        ),
      ),
    );
  }
}

class ColorGrid extends StatelessWidget {
  const ColorGrid({super.key});

  @override
  Widget build(BuildContext context) {
    return Row(
      children: [
        _colorBlock(context, Colors.red, 100),
        const SizedBox(width: 8),
        _colorBlock(context, Colors.green, 100),
        const SizedBox(width: 8),
        _colorBlock(context, Colors.blue, 100),
      ],
    );
  }

  Widget _colorBlock(BuildContext context, Color color, double width) {
    return Expanded(
      child: Container(
        height: 60,
        decoration: BoxDecoration(
          color: color,
          borderRadius: BorderRadius.circular(8),
        ),
        child: Center(
          child: Text(
            '${width.fw(context).toInt()}',
            style: const TextStyle(
                color: Colors.white, fontWeight: FontWeight.bold),
          ),
        ),
      ),
    );
  }
}

class FluidScalingDemo extends StatelessWidget {
  const FluidScalingDemo({super.key});

  @override
  Widget build(BuildContext context) {
    // 1. Fluid Typography
    final fontSize = 16.aw(32, context);
    // 2. Fluid Padding
    final padding = 12.aw(24, context);
    // 3. Fluid Spacing
    final spacing = 8.aw(16, context);
    // 4. Fluid Height
    final containerHeight = 120.aw(240, context);

    return Column(
      children: [
        Container(
          width: double.infinity,
          height: containerHeight,
          padding: EdgeInsets.all(padding),
          decoration: BoxDecoration(
            gradient: LinearGradient(
              colors: [Colors.indigo.shade400, Colors.blue.shade300],
            ),
            borderRadius: BorderRadius.circular(16),
            boxShadow: [
              BoxShadow(
                color: Colors.indigo.withValues(alpha: 0.2),
                blurRadius: 15,
                offset: const Offset(0, 8),
              )
            ],
          ),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text(
                'Universal Fluid Scaling',
                style: TextStyle(
                  fontSize: fontSize,
                  fontWeight: FontWeight.bold,
                  color: Colors.white,
                  letterSpacing: -0.5,
                ),
              ),
              SizedBox(height: spacing),
              Container(
                padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
                decoration: BoxDecoration(
                  color: Colors.white24,
                  borderRadius: BorderRadius.circular(4),
                ),
                child: Text(
                  'Padding: ${padding.toStringAsFixed(1)} | Spacing: ${spacing.toStringAsFixed(1)}',
                  style: const TextStyle(color: Colors.white, fontSize: 10),
                ),
              ),
            ],
          ),
        ),
        const SizedBox(height: 12),
        const Text(
          'Everything above (Font, Padding, Height, Spacing) updates with zero lag using granular width subscriptions.',
          textAlign: TextAlign.center,
          style: TextStyle(
              fontSize: 10, color: Colors.grey, fontStyle: FontStyle.italic),
        ),
      ],
    );
  }
}
8
likes
0
points
615
downloads

Publisher

unverified uploader

Weekly Downloads

A powerful Flutter package for adaptive and responsive UIs with fluid scaling, breakpoints, and component-level responsiveness.

Repository (GitHub)
View/report issues

Topics

#responsive #adaptive-ui #flutter-layout #screen-scaling #breakpoints

License

unknown (license)

Dependencies

flutter, tuple

More

Packages that depend on flexi_ui