responsive_wrapper 1.0.2 copy "responsive_wrapper: ^1.0.2" to clipboard
responsive_wrapper: ^1.0.2 copied to clipboard

A Flutter package for building responsive UIs that adapt to different screen sizes, device types, and orientations with automatic detection.

example/lib/main.dart

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

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

/// A comprehensive example app demonstrating all features of the responsive_wrapper package.
class ResponsiveWrapperExampleApp extends StatelessWidget {
  const ResponsiveWrapperExampleApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Responsive Wrapper Examples',
      theme: ThemeData(primarySwatch: Colors.blue, useMaterial3: true),
      home: const ResponsiveWrapperExampleHome(),
    );
  }
}

/// The main example page that demonstrates different responsive wrapper features.
class ResponsiveWrapperExampleHome extends StatefulWidget {
  const ResponsiveWrapperExampleHome({super.key});

  @override
  State<ResponsiveWrapperExampleHome> createState() =>
      _ResponsiveWrapperExampleHomeState();
}

class _ResponsiveWrapperExampleHomeState
    extends State<ResponsiveWrapperExampleHome> {
  int _selectedExample = 0;
  String _userName = 'John Doe';
  int _counter = 0;

  final List<String> _examples = [
    'Basic ResponsiveWrapper',
    'ResponsiveWrapper with PreBuilder',
    'ResponsiveWrapperWith (Parameterized)',
    'ResponsiveLayout',
    'ResponsiveLayoutWith (Parameterized)',
    'ResponsiveOrientationLayout',
    'ResponsiveOrientationLayoutWith (Parameterized)',
    'ResponsiveOrientationValue',
    'Custom Breakpoints',
    'Orientation Handling',
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Responsive Wrapper Examples'),
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
      ),
      body: Column(
        children: [
          // Example selector
          Container(
            padding: const EdgeInsets.all(16),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                const Text(
                  'Select Example:',
                  style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
                ),
                const SizedBox(height: 8),
                DropdownButton<int>(
                  value: _selectedExample,
                  isExpanded: true,
                  items: _examples.asMap().entries.map((entry) {
                    return DropdownMenuItem<int>(
                      value: entry.key,
                      child: Text(entry.value),
                    );
                  }).toList(),
                  onChanged: (value) {
                    setState(() {
                      _selectedExample = value!;
                    });
                  },
                ),
              ],
            ),
          ),
          // Example content
          Expanded(child: _buildExampleContent()),
        ],
      ),
    );
  }

  Widget _buildExampleContent() {
    switch (_selectedExample) {
      case 0:
        return _buildBasicResponsiveWrapper();
      case 1:
        return _buildResponsiveWrapperWithPreBuilder();
      case 2:
        return _buildResponsiveWrapperWith();
      case 3:
        return _buildResponsiveLayout();
      case 4:
        return _buildResponsiveLayoutWith();
      case 5:
        return _buildResponsiveOrientationLayout();
      case 6:
        return _buildResponsiveOrientationLayoutWith();
      case 7:
        return _buildResponsiveOrientationValue();
      case 8:
        return _buildCustomBreakpoints();
      case 9:
        return _buildOrientationHandling();
      default:
        return const Center(child: Text('Select an example'));
    }
  }

  /// Example 1: Basic ResponsiveWrapper
  Widget _buildBasicResponsiveWrapper() {
    return ResponsiveWrapper(
      builder: (context, screenInfo) {
        return Container(
          padding: EdgeInsets.all(screenInfo.isPhone ? 16.0 : 24.0),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Icon(
                screenInfo.isPhone
                    ? Icons.phone_android
                    : screenInfo.isTablet
                    ? Icons.tablet
                    : Icons.desktop_windows,
                size: screenInfo.isPhone ? 48.0 : 64.0,
                color: screenInfo.isPhone
                    ? Colors.blue
                    : screenInfo.isTablet
                    ? Colors.green
                    : Colors.orange,
              ),
              const SizedBox(height: 16),
              Text(
                'Device Type: ${screenInfo.deviceType.name}',
                style: TextStyle(
                  fontSize: screenInfo.isPhone ? 18.0 : 24.0,
                  fontWeight: FontWeight.bold,
                ),
              ),
              const SizedBox(height: 8),
              Text(
                'Screen Size: ${screenInfo.width.toInt()} x ${screenInfo.height.toInt()}',
                style: TextStyle(fontSize: screenInfo.isPhone ? 14.0 : 16.0),
              ),
              const SizedBox(height: 8),
              Text(
                'Orientation: ${screenInfo.orientation.name}',
                style: TextStyle(fontSize: screenInfo.isPhone ? 14.0 : 16.0),
              ),
            ],
          ),
        );
      },
    );
  }

  /// Example 2: ResponsiveWrapper with PreBuilder
  Widget _buildResponsiveWrapperWithPreBuilder() {
    return ResponsiveWrapper(
      preBuilder: (context, child) => Container(
        decoration: BoxDecoration(
          gradient: LinearGradient(
            colors: [Colors.blue.shade100, Colors.purple.shade100],
            begin: Alignment.topLeft,
            end: Alignment.bottomRight,
          ),
        ),
        child: child,
      ),
      builder: (context, screenInfo) {
        return Container(
          padding: EdgeInsets.all(screenInfo.isPhone ? 16.0 : 24.0),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text(
                'With PreBuilder',
                style: TextStyle(
                  fontSize: screenInfo.isPhone ? 20.0 : 28.0,
                  fontWeight: FontWeight.bold,
                  color: Colors.blue.shade800,
                ),
              ),
              const SizedBox(height: 16),
              Text(
                'This example shows how to wrap responsive content with additional widgets.',
                textAlign: TextAlign.center,
                style: TextStyle(fontSize: screenInfo.isPhone ? 14.0 : 16.0),
              ),
            ],
          ),
        );
      },
    );
  }

  /// Example 3: ResponsiveWrapperWith (Parameterized)
  Widget _buildResponsiveWrapperWith() {
    return ResponsiveWrapperWith<String>(
      initialParam: _userName,
      builder: (context, screenInfo, userName) {
        return Container(
          padding: EdgeInsets.all(screenInfo.isPhone ? 16.0 : 24.0),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text(
                'Hello, $userName!',
                style: TextStyle(
                  fontSize: screenInfo.isPhone ? 20.0 : 28.0,
                  fontWeight: FontWeight.bold,
                ),
              ),
              const SizedBox(height: 16),
              Text(
                'This is a parameterized responsive wrapper.',
                textAlign: TextAlign.center,
                style: TextStyle(fontSize: screenInfo.isPhone ? 14.0 : 16.0),
              ),
              const SizedBox(height: 16),
              ElevatedButton(
                onPressed: () {
                  setState(() {
                    _userName = _userName == 'John Doe'
                        ? 'Jane Smith'
                        : 'John Doe';
                  });
                },
                child: const Text('Change Name'),
              ),
            ],
          ),
        );
      },
    );
  }

  /// Example 4: ResponsiveLayout
  Widget _buildResponsiveLayout() {
    return ResponsiveLayout(
      phone: (context) => _buildPhoneLayout(),
      tablet: (context) => _buildTabletLayout(),
      desktop: (context) => _buildDesktopLayout(),
    );
  }

  /// Example 5: ResponsiveLayoutWith (Parameterized)
  Widget _buildResponsiveLayoutWith() {
    return ResponsiveLayoutWith<int>(
      initialParam: _counter,
      phone: (context, counter) => _buildPhoneLayoutWithCounter(counter),
      tablet: (context, counter) => _buildTabletLayoutWithCounter(counter),
      desktop: (context, counter) => _buildDesktopLayoutWithCounter(counter),
    );
  }

  /// Example 6: ResponsiveOrientationLayout
  Widget _buildResponsiveOrientationLayout() {
    return ResponsiveOrientationLayout(
      phonePortrait: (context) => _buildPhonePortraitLayout(),
      phoneLandscape: (context) => _buildPhoneLandscapeLayout(),
      tabletPortrait: (context) => _buildTabletPortraitLayout(),
      tabletLandscape: (context) => _buildTabletLandscapeLayout(),
      desktop: (context) => _buildDesktopLayout(),
    );
  }

  /// Example 7: ResponsiveOrientationLayoutWith (Parameterized)
  Widget _buildResponsiveOrientationLayoutWith() {
    return ResponsiveOrientationLayoutWith<String>(
      initialParam: _userName,
      phonePortrait: (context, userName) =>
          _buildPhonePortraitLayoutWithUser(userName),
      phoneLandscape: (context, userName) =>
          _buildPhoneLandscapeLayoutWithUser(userName),
      tabletPortrait: (context, userName) =>
          _buildTabletPortraitLayoutWithUser(userName),
      tabletLandscape: (context, userName) =>
          _buildTabletLandscapeLayoutWithUser(userName),
      desktop: (context, userName) => _buildDesktopLayoutWithUser(userName),
    );
  }

  /// Example 8: ResponsiveOrientationValue
  Widget _buildResponsiveOrientationValue() {
    return ResponsiveWrapper(
      builder: (context, screenInfo) {
        final fontSize = ResponsiveOrientationValue<double>(
          phonePortrait: 16.0,
          phoneLandscape: 14.0,
          tabletPortrait: 20.0,
          tabletLandscape: 18.0,
          desktop: 24.0,
        ).getValue(context);

        final padding = ResponsiveOrientationValue<EdgeInsets>(
          phonePortrait: const EdgeInsets.all(16.0),
          phoneLandscape: const EdgeInsets.symmetric(
            horizontal: 24.0,
            vertical: 12.0,
          ),
          tabletPortrait: const EdgeInsets.all(24.0),
          tabletLandscape: const EdgeInsets.all(20.0),
          desktop: const EdgeInsets.all(32.0),
        ).getValue(context);

        return Container(
          padding: padding,
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text(
                'Responsive Values',
                style: TextStyle(
                  fontSize: fontSize,
                  fontWeight: FontWeight.bold,
                ),
              ),
              const SizedBox(height: 16),
              Text(
                'Font Size: ${fontSize.toInt()}px',
                style: TextStyle(fontSize: fontSize * 0.8),
              ),
              const SizedBox(height: 8),
              Text(
                'Padding: ${padding.left.toInt()}px',
                style: TextStyle(fontSize: fontSize * 0.8),
              ),
            ],
          ),
        );
      },
    );
  }

  /// Example 9: Custom Breakpoints
  Widget _buildCustomBreakpoints() {
    return ResponsiveWrapper(
      breakpoints: const ResponsiveBreakpoints(
        phone: 480, // Custom phone breakpoint
        tablet: 800, // Custom tablet breakpoint
      ),
      builder: (context, screenInfo) {
        return Container(
          padding: const EdgeInsets.all(16),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text(
                'Custom Breakpoints',
                style: TextStyle(
                  fontSize: screenInfo.isPhone ? 18.0 : 24.0,
                  fontWeight: FontWeight.bold,
                ),
              ),
              const SizedBox(height: 16),
              Text(
                'Phone: < 480px\nTablet: 480px - 800px\nDesktop: > 800px',
                textAlign: TextAlign.center,
                style: TextStyle(fontSize: screenInfo.isPhone ? 14.0 : 16.0),
              ),
              const SizedBox(height: 16),
              Text(
                'Current: ${screenInfo.deviceType.name} (${screenInfo.width.toInt()}px)',
                style: TextStyle(
                  fontSize: screenInfo.isPhone ? 14.0 : 16.0,
                  color: Colors.blue,
                ),
              ),
            ],
          ),
        );
      },
    );
  }

  /// Example 10: Orientation Handling
  Widget _buildOrientationHandling() {
    return ResponsiveWrapper(
      treatLandscapePhoneAsTablet: true,
      treatPortraitTabletAsPhone: true,
      builder: (context, screenInfo) {
        return Container(
          padding: const EdgeInsets.all(16),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text(
                'Orientation Handling',
                style: TextStyle(
                  fontSize: screenInfo.isPhone ? 18.0 : 24.0,
                  fontWeight: FontWeight.bold,
                ),
              ),
              const SizedBox(height: 16),
              Text(
                'Landscape phones treated as tablets\nPortrait tablets treated as phones',
                textAlign: TextAlign.center,
                style: TextStyle(fontSize: screenInfo.isPhone ? 14.0 : 16.0),
              ),
              const SizedBox(height: 16),
              Text(
                'Device Type: ${screenInfo.deviceType.name}',
                style: TextStyle(
                  fontSize: screenInfo.isPhone ? 14.0 : 16.0,
                  color: Colors.green,
                ),
              ),
              const SizedBox(height: 8),
              Text(
                'Orientation: ${screenInfo.orientation.name}',
                style: TextStyle(
                  fontSize: screenInfo.isPhone ? 14.0 : 16.0,
                  color: Colors.blue,
                ),
              ),
            ],
          ),
        );
      },
    );
  }

  // Layout builders for different device types
  Widget _buildPhoneLayout() {
    return Container(
      padding: const EdgeInsets.all(16),
      child: const Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Icon(Icons.phone_android, size: 48, color: Colors.blue),
          SizedBox(height: 16),
          Text(
            'Phone Layout',
            style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
          ),
          SizedBox(height: 8),
          Text('Optimized for small screens'),
        ],
      ),
    );
  }

  Widget _buildTabletLayout() {
    return Container(
      padding: const EdgeInsets.all(24),
      child: const Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Icon(Icons.tablet, size: 64, color: Colors.green),
          SizedBox(height: 16),
          Text(
            'Tablet Layout',
            style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
          ),
          SizedBox(height: 8),
          Text('Optimized for medium screens'),
        ],
      ),
    );
  }

  Widget _buildDesktopLayout() {
    return Container(
      padding: const EdgeInsets.all(32),
      child: const Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Icon(Icons.desktop_windows, size: 80, color: Colors.orange),
          SizedBox(height: 16),
          Text(
            'Desktop Layout',
            style: TextStyle(fontSize: 28, fontWeight: FontWeight.bold),
          ),
          SizedBox(height: 8),
          Text('Optimized for large screens'),
        ],
      ),
    );
  }

  // Layout builders with counter parameter
  Widget _buildPhoneLayoutWithCounter(int counter) {
    return Container(
      padding: const EdgeInsets.all(16),
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          const Icon(Icons.phone_android, size: 48, color: Colors.blue),
          const SizedBox(height: 16),
          const Text(
            'Phone Layout',
            style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
          ),
          const SizedBox(height: 8),
          Text('Counter: $counter'),
          const SizedBox(height: 16),
          ElevatedButton(
            onPressed: () => setState(() => _counter++),
            child: const Text('Increment'),
          ),
        ],
      ),
    );
  }

  Widget _buildTabletLayoutWithCounter(int counter) {
    return Container(
      padding: const EdgeInsets.all(24),
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          const Icon(Icons.tablet, size: 64, color: Colors.green),
          const SizedBox(height: 16),
          const Text(
            'Tablet Layout',
            style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
          ),
          const SizedBox(height: 8),
          Text('Counter: $counter'),
          const SizedBox(height: 16),
          ElevatedButton(
            onPressed: () => setState(() => _counter++),
            child: const Text('Increment'),
          ),
        ],
      ),
    );
  }

  Widget _buildDesktopLayoutWithCounter(int counter) {
    return Container(
      padding: const EdgeInsets.all(32),
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          const Icon(Icons.desktop_windows, size: 80, color: Colors.orange),
          const SizedBox(height: 16),
          const Text(
            'Desktop Layout',
            style: TextStyle(fontSize: 28, fontWeight: FontWeight.bold),
          ),
          const SizedBox(height: 8),
          Text('Counter: $counter'),
          const SizedBox(height: 16),
          ElevatedButton(
            onPressed: () => setState(() => _counter++),
            child: const Text('Increment'),
          ),
        ],
      ),
    );
  }

  // Orientation-specific layout builders
  Widget _buildPhonePortraitLayout() {
    return Container(
      padding: const EdgeInsets.all(16),
      child: const Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Icon(Icons.phone_android, size: 48, color: Colors.blue),
          SizedBox(height: 16),
          Text(
            'Phone Portrait',
            style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
          ),
          SizedBox(height: 8),
          Text('Vertical layout for phones'),
        ],
      ),
    );
  }

  Widget _buildPhoneLandscapeLayout() {
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12),
      child: const Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Icon(Icons.phone_android, size: 48, color: Colors.blue),
          SizedBox(width: 16),
          Column(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text(
                'Phone Landscape',
                style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
              ),
              SizedBox(height: 4),
              Text('Horizontal layout for phones'),
            ],
          ),
        ],
      ),
    );
  }

  Widget _buildTabletPortraitLayout() {
    return Container(
      padding: const EdgeInsets.all(24),
      child: const Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Icon(Icons.tablet, size: 64, color: Colors.green),
          SizedBox(height: 16),
          Text(
            'Tablet Portrait',
            style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
          ),
          SizedBox(height: 8),
          Text('Vertical layout for tablets'),
        ],
      ),
    );
  }

  Widget _buildTabletLandscapeLayout() {
    return Container(
      padding: const EdgeInsets.all(20),
      child: const Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Icon(Icons.tablet, size: 64, color: Colors.green),
          SizedBox(width: 20),
          Column(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text(
                'Tablet Landscape',
                style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
              ),
              SizedBox(height: 8),
              Text('Horizontal layout for tablets'),
            ],
          ),
        ],
      ),
    );
  }

  // Orientation-specific layout builders with user parameter
  Widget _buildPhonePortraitLayoutWithUser(String userName) {
    return Container(
      padding: const EdgeInsets.all(16),
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          const Icon(Icons.phone_android, size: 48, color: Colors.blue),
          const SizedBox(height: 16),
          Text(
            'Hello $userName!',
            style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
          ),
          const SizedBox(height: 8),
          const Text('Phone Portrait Layout'),
        ],
      ),
    );
  }

  Widget _buildPhoneLandscapeLayoutWithUser(String userName) {
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          const Icon(Icons.phone_android, size: 48, color: Colors.blue),
          const SizedBox(width: 16),
          Column(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text(
                'Hello $userName!',
                style: const TextStyle(
                  fontSize: 18,
                  fontWeight: FontWeight.bold,
                ),
              ),
              const SizedBox(height: 4),
              const Text('Phone Landscape Layout'),
            ],
          ),
        ],
      ),
    );
  }

  Widget _buildTabletPortraitLayoutWithUser(String userName) {
    return Container(
      padding: const EdgeInsets.all(24),
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          const Icon(Icons.tablet, size: 64, color: Colors.green),
          const SizedBox(height: 16),
          Text(
            'Hello $userName!',
            style: const TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
          ),
          const SizedBox(height: 8),
          const Text('Tablet Portrait Layout'),
        ],
      ),
    );
  }

  Widget _buildTabletLandscapeLayoutWithUser(String userName) {
    return Container(
      padding: const EdgeInsets.all(20),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          const Icon(Icons.tablet, size: 64, color: Colors.green),
          const SizedBox(width: 20),
          Column(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text(
                'Hello $userName!',
                style: const TextStyle(
                  fontSize: 24,
                  fontWeight: FontWeight.bold,
                ),
              ),
              const SizedBox(height: 8),
              const Text('Tablet Landscape Layout'),
            ],
          ),
        ],
      ),
    );
  }

  Widget _buildDesktopLayoutWithUser(String userName) {
    return Container(
      padding: const EdgeInsets.all(32),
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          const Icon(Icons.desktop_windows, size: 80, color: Colors.orange),
          const SizedBox(height: 16),
          Text(
            'Hello $userName!',
            style: const TextStyle(fontSize: 28, fontWeight: FontWeight.bold),
          ),
          const SizedBox(height: 8),
          const Text('Desktop Layout'),
        ],
      ),
    );
  }
}
3
likes
160
points
233
downloads

Publisher

verified publishersaktepe.com

Weekly Downloads

A Flutter package for building responsive UIs that adapt to different screen sizes, device types, and orientations with automatic detection.

Homepage
Repository (GitHub)
View/report issues

Topics

#responsive #layout #adaptive #orientation #breakpoints

Documentation

API reference

License

MIT (license)

Dependencies

flutter

More

Packages that depend on responsive_wrapper