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.

Responsive Wrapper #

A comprehensive Flutter package for building responsive UIs that adapt to different screen sizes, device types, and orientations. This package provides a clean and flexible API for creating responsive layouts with automatic device detection and orientation handling.

Features #

  • Device Type Detection: Automatically detects phone, tablet, and desktop devices
  • Orientation Support: Handle portrait and landscape orientations with different layouts
  • Custom Breakpoints: Configure your own breakpoints for device type detection
  • Parameterized Widgets: Pass data and state to your responsive layouts
  • Pre-builders: Wrap responsive content with state management, themes, and more
  • Responsive Values: Define different values for different device types and orientations
  • Easy to Use: Simple API with comprehensive documentation and examples

Getting Started #

Add this to your package's pubspec.yaml file:

dependencies:
  responsive_wrapper: ^1.0.2

Then run:

flutter pub get

Usage #

Basic Responsive Wrapper #

The simplest way to create responsive layouts:

import 'package:responsive_wrapper/responsive_wrapper.dart';

ResponsiveWrapper(
  builder: (context, screenInfo) {
    return Container(
      padding: EdgeInsets.all(
        screenInfo.isPhone ? 16.0 : 24.0,
      ),
      child: Text(
        'Device: ${screenInfo.deviceType.name}',
        style: TextStyle(
          fontSize: screenInfo.isPhone ? 16.0 : 20.0,
        ),
      ),
    );
  },
)

Responsive Layout #

Define different layouts for different device types:

import 'package:responsive_wrapper/layout.dart';

ResponsiveLayout(
  phone: (context) => PhoneLayout(),
  tablet: (context) => TabletLayout(),
  desktop: (context) => DesktopLayout(),
)

Orientation-Aware Layouts #

Handle different orientations with specific layouts:

import 'package:responsive_wrapper/orientation_layout.dart';

ResponsiveOrientationLayout(
  phonePortrait: (context) => PhonePortraitLayout(),
  phoneLandscape: (context) => PhoneLandscapeLayout(),
  tabletPortrait: (context) => TabletPortraitLayout(),
  tabletLandscape: (context) => TabletLandscapeLayout(),
  desktop: (context) => DesktopLayout(),
)

Parameterized Widgets #

Pass data to your responsive layouts:

ResponsiveWrapperWith<UserData>(
  initialParam: userData,
  builder: (context, screenInfo, userData) {
    return UserProfile(user: userData);
  },
)

Responsive Values #

Define different values for different device types and orientations:

final fontSize = ResponsiveOrientationValue<double>(
  phonePortrait: 16.0,
  phoneLandscape: 14.0,
  tabletPortrait: 20.0,
  tabletLandscape: 18.0,
  desktop: 24.0,
).getValue(context);

Custom Breakpoints #

Configure your own breakpoints:

ResponsiveWrapper(
  breakpoints: const ResponsiveBreakpoints(
    phone: 480,  // Custom phone breakpoint
    tablet: 800, // Custom tablet breakpoint
  ),
  builder: (context, screenInfo) {
    // Your responsive content
  },
)

Pre-builders #

Pre-builders allow you to wrap responsive content with additional functionality like state management, themes, or other wrapper widgets. They are executed before the main responsive builder and can provide context, state, or styling to your responsive layouts.

Basic Pre-builder

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 Text('Responsive content with gradient background');
  },
)

State Management with Pre-builder

ResponsiveWrapper(
  preBuilder: (context, child) => BlocBuilder<AppCubit, AppState>(
    builder: (context, state) {
      return state.isLoading 
        ? CircularProgressIndicator()
        : child;
    },
  ),
  builder: (context, screenInfo) {
    return Text('Content that depends on app state');
  },
)

Theme and Styling Wrappers

ResponsiveWrapper(
  preBuilder: (context, child) => Theme(
    data: Theme.of(context).copyWith(
      cardTheme: CardTheme(
        elevation: 8,
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(16),
        ),
      ),
    ),
    child: Card(child: child),
  ),
  builder: (context, screenInfo) {
    return Padding(
      padding: EdgeInsets.all(screenInfo.isPhone ? 16.0 : 24.0),
      child: Text('Themed responsive content'),
    );
  },
)

Parameterized Pre-builder

For widgets that need to pass parameters to responsive layouts:

ResponsiveLayoutWith<String>(
  preBuilder: (context, childBuilder) {
    // Pre-builder can determine what parameter to pass
    final user = UserService.getCurrentUser();
    final userName = user?.name ?? 'Guest';
    
    return Container(
      decoration: BoxDecoration(
        border: Border.all(color: Colors.blue),
        borderRadius: BorderRadius.circular(8),
      ),
      child: childBuilder(userName), // Pass parameter to child
    );
  },
  phone: (context, userName) => Text('Hello $userName on phone!'),
  tablet: (context, userName) => Text('Hello $userName on tablet!'),
  desktop: (context, userName) => Text('Hello $userName on desktop!'),
)

Common Pre-builder Patterns

1. Loading States:

ResponsiveWrapper(
  preBuilder: (context, child) => FutureBuilder<Data>(
    future: dataService.fetchData(),
    builder: (context, snapshot) {
      if (snapshot.connectionState == ConnectionState.waiting) {
        return Center(child: CircularProgressIndicator());
      }
      if (snapshot.hasError) {
        return Center(child: Text('Error: ${snapshot.error}'));
      }
      return child;
    },
  ),
  builder: (context, screenInfo) => DataWidget(data: snapshot.data),
)

2. Authentication Wrappers:

ResponsiveWrapper(
  preBuilder: (context, child) => Consumer<AuthProvider>(
    builder: (context, auth, child) {
      if (!auth.isAuthenticated) {
        return LoginScreen();
      }
      return child;
    },
  ),
  builder: (context, screenInfo) => AuthenticatedContent(),
)

3. Error Boundaries:

ResponsiveWrapper(
  preBuilder: (context, child) => ErrorBoundary(
    onError: (error, stackTrace) => ErrorScreen(error: error),
    child: child,
  ),
  builder: (context, screenInfo) => RiskyWidget(),
)

4. Analytics and Tracking:

ResponsiveWrapper(
  preBuilder: (context, child) => AnalyticsWrapper(
    screenName: 'responsive_screen',
    properties: {
      'device_type': screenInfo.deviceType.name,
      'orientation': screenInfo.orientation.name,
    },
    child: child,
  ),
  builder: (context, screenInfo) => TrackedContent(),
)

Understanding Pre-builders #

Pre-builders are a powerful feature that allows you to wrap your responsive content with additional functionality. They are executed before the main responsive builder and provide a way to inject state, context, or styling into your responsive layouts.

How Pre-builders Work #

  1. Execution Order: Pre-builder runs first, then the main responsive builder
  2. Child Parameter: The pre-builder receives the responsive widget as a child parameter
  3. Flexibility: You can conditionally render, wrap, or transform the child widget
  4. Parameterized Pre-builders: For ResponsiveWrapperWith and ResponsiveLayoutWith, pre-builders receive a childBuilder function that can be called with different parameters

When to Use Pre-builders #

  • State Management: Wrap responsive content with BLoC, Provider, or other state management solutions
  • Loading States: Show loading indicators while data is being fetched
  • Authentication: Check user authentication before showing content
  • Theming: Apply consistent styling or themes across responsive layouts
  • Error Handling: Implement error boundaries or fallback UI
  • Analytics: Track screen views and user interactions
  • Data Fetching: Load data that multiple responsive layouts need

Pre-builder vs Regular Builder #

Aspect Pre-builder Regular Builder
Purpose Wrap/enhance responsive content Build responsive content
Execution Runs first Runs after pre-builder
Access to Context only Context + ScreenInfo
Use Case State, theming, loading Device-specific layouts
Child Receives built widget Builds the widget

API Reference #

Core Classes #

  • ResponsiveWrapper: Main responsive wrapper widget
  • ResponsiveWrapperWith<T>: Parameterized responsive wrapper
  • ResponsiveLayout: Device-specific layout wrapper
  • ResponsiveLayoutWith<T>: Parameterized layout wrapper
  • ResponsiveOrientationLayout: Orientation-aware layout wrapper
  • ResponsiveOrientationLayoutWith<T>: Parameterized orientation layout wrapper

Utility Classes #

  • ResponsiveBreakpoints: Breakpoint configuration
  • ScreenInfo: Screen information data class
  • ResponsiveValue<T>: Responsive value utility
  • ResponsiveOrientationValue<T>: Orientation-aware value utility
  • DeviceType: Device type enumeration

Builder Types #

  • ResponsiveBuilder: Basic responsive builder function
  • ResponsivePreBuilder: Pre-builder wrapper function
  • ResponsiveLayoutBuilder: Layout builder function
  • ResponsiveBuilderWith<T>: Parameterized builder function
  • ResponsivePreBuilderWith<T>: Parameterized pre-builder function
  • ResponsiveOrientationLayoutBuilder: Orientation layout builder function

Real-World Examples #

Complete App with Pre-builders #

Here's a comprehensive example showing how to build a responsive app with pre-builders:

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: ResponsiveLayoutWith<UserData>(
        preBuilder: (context, childBuilder) {
          return BlocBuilder<AuthCubit, AuthState>(
            builder: (context, authState) {
              if (authState.isLoading) {
                return LoadingScreen();
              }
              
              if (!authState.isAuthenticated) {
                return LoginScreen();
              }
              
              // User is authenticated, get user data
              return FutureBuilder<UserData>(
                future: UserService.getUserData(authState.userId),
                builder: (context, snapshot) {
                  if (snapshot.connectionState == ConnectionState.waiting) {
                    return LoadingScreen();
                  }
                  
                  if (snapshot.hasError) {
                    return ErrorScreen(error: snapshot.error);
                  }
                  
                  // Pass user data to responsive layouts
                  return childBuilder(snapshot.data!);
                },
              );
            },
          );
        },
        phone: (context, userData) => PhoneDashboard(userData: userData),
        tablet: (context, userData) => TabletDashboard(userData: userData),
        desktop: (context, userData) => DesktopDashboard(userData: userData),
      ),
    );
  }
}

E-commerce Product Page #

class ProductPage extends StatelessWidget {
  final String productId;
  
  @override
  Widget build(BuildContext context) {
    return ResponsiveWrapper(
      preBuilder: (context, child) => BlocBuilder<ProductCubit, ProductState>(
        builder: (context, state) {
          if (state.isLoading) {
            return Center(child: CircularProgressIndicator());
          }
          
          if (state.hasError) {
            return ErrorWidget(state.error);
          }
          
          return child;
        },
      ),
      builder: (context, screenInfo) {
        return screenInfo.isPhone
          ? PhoneProductLayout(productId: productId)
          : screenInfo.isTablet
          ? TabletProductLayout(productId: productId)
          : DesktopProductLayout(productId: productId);
      },
    );
  }
}

Settings Screen with Theme Management #

class SettingsScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ResponsiveWrapper(
      preBuilder: (context, child) => Consumer<ThemeProvider>(
        builder: (context, themeProvider, child) {
          return Theme(
            data: themeProvider.currentTheme,
            child: Container(
              decoration: BoxDecoration(
                gradient: themeProvider.isDarkMode
                  ? LinearGradient(colors: [Colors.grey[900]!, Colors.grey[800]!])
                  : LinearGradient(colors: [Colors.blue[50]!, Colors.white]),
              ),
              child: child,
            ),
          );
        },
      ),
      builder: (context, screenInfo) {
        return screenInfo.isPhone
          ? PhoneSettingsLayout()
          : TabletSettingsLayout();
      },
    );
  }
}

Contributing #

Contributions are welcome! Please feel free to submit a Pull Request.

License #

This project is licensed under the MIT License - see the LICENSE file for details.

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