responsive_theme 0.0.1 copy "responsive_theme: ^0.0.1" to clipboard
responsive_theme: ^0.0.1 copied to clipboard

Adaptive Styles – from DARK to BRIGHT. Powerful Theme Solution for Flutter Apps. "#flutter" "#responsive" "#theme"

Responsive Theme #

A Flutter package designed to simplify responsive theming in your applications, allowing you to create beautiful, consistent UIs that adapt to different screen sizes and device themes.

pub package license

Responsive Theme

Features #

  • 🎨 Theming System: Easy light/dark mode implementation
  • 📱 Responsiveness: Adaptive UI components based on screen size
  • 🔤 Typography: Predefined text styles for consistent typography
  • 🔲 Spacing Utilities: Standardized spacing components
  • 📐 Border Radius Helpers: Consistent rounded corners
  • 🧩 Padding Utilities: Simplified padding implementation
  • 🎯 Precise Scaling: Screen-aware size calculations

Installation #

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

dependencies:
  responsive_theme:

Then run:

flutter pub get

Usage #

Basic Setup #

  1. First, create your color configurations:
import 'package:responsive_theme/responsive_theme.dart';
import 'package:flutter/material.dart';

// Define you colors
class AppColors {
  final Color background;
  final Color primary;
  final Color secondary;
  final Color accent;
  final Color error;
  final Color success;

  const AppColors({
    required this.background,
    required this.primary,
    required this.secondary,
    required this.accent,
    required this.error,
    required this.success,
  });
  

  /// Important for responsive_theme
  ThemeColor toThemeColor() {
    return {
      'background': background,
      'primary': primary,
      'secondary': secondary,
      'accent': accent,
      'error': error,
      'success': success,
    };
  }

  // Colors for light theme
  factory AppColors.light() => AppColors(
    background: Color(0xFFFFFFFF),
    primary: Color(0xFF6200EE),
    secondary: Color(0xFF03DAC6),
    accent: Color(0xFF3700B3),
    error: Color(0xFFB00020),
    success: Color(0xFF4CAF50),
  );

  // Colors for dark theme
  factory AppColors.dark() => AppColors(
    background: Color(0xFF121212),
    primary: Color(0xFFBB86FC),
    secondary: Color(0xFF03DAC6),
    accent: Color(0xFF03DAC5),
    error: Color(0xFFCF6679),
    success: Color(0xFF4CAF50),
  );
}

/// this extention make easy to access colors
extension ThemeColorKey on ThemeColor {
  Color get background => this['background']!;
  Color get primary => this['primary']!;
  Color get secondary => this['secondary']!;
  Color get accent => this['accent']!;
  Color get error => this['error']!;
  Color get success => this['success']!;

  ThemeColor toThemeColor() => this;
}

  1. Wrap your app with AppResponsiveTheme:
import 'package:responsive_theme/responsive_theme.dart';
import 'package:flutter/material.dart';


void main() {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(
    MultiProvider(
      providers: [ChangeNotifierProvider(create: (context) => ThemeProvider())],
      child: MyApp(),
    ),
  );
}

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

class _MyAppState extends State<MyApp> {
  @override
  void initState() {
    super.initState();
    /// TODO : must implement '[ThemeConfig.init]' to make responsive design
    ThemeConfig.init(context);
    WidgetsBinding.instance.addPostFrameCallback((_) {
      context.themeProvider.loadCurrentTheme(context);
    });
  }

  @override
  Widget build(BuildContext context) {
    /// show Theme Switching section
    return Consumer<ThemeProvider>(builder: (context, state, _) {
      return AppResponsiveTheme(
        themeMode: state.theme,
        config: ColorConfig(
          lightColors: AppColors.light().toThemeColor(),
          darkColors: AppColors.dark().toThemeColor(),
        ),
        child: MaterialApp(
          title: 'Responsive Theme App',
          home: MyHomePage(),
        ),
      );
    }
    );
  }
}

  1. Access theme data in your widgets:
import 'package:responsive_theme/responsive_theme.dart';
import 'package:flutter/material.dart';

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: context.colors['background'],
      appBar: AppBar(
        title: Txt.title18('My App'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Txt.title24(
              'Welcome to Responsive Theme',
              color: context.colors.primary,
            ),
            VGap.medium16(),
            Txt.regular16(
              'Build beautiful responsive apps with ease',
              color: context.colors.black80,
            ),
          ],
        ),
      ),
    );
  }
}

Theme Switching #

You can implement theme switching using a ChangeNotifier (or use any other state management technique): (You can copy and paste in your project and customize as per your need.)


import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import "package:responsive_theme/responsive_theme.dart";

class ThemeProvider with ChangeNotifier {
  ThemeProvider();

  bool get darkTheme => _darkTheme;
  bool _darkTheme = false;

  AppThemeMode get theme => _darkTheme ? AppThemeMode.dark : AppThemeMode.light;

  void toggleTheme({bool? isDark}) async {
    _darkTheme = isDark ?? !_darkTheme;
    // Shared Pref for store theme 
    final sp = await SharedPreferences.getInstance();
    sp.setBool("isDarkTheme", _darkTheme);
    notifyListeners();
  }

  void loadCurrentTheme(BuildContext context, {ThemeMode themeMode = ThemeMode.system}) async {
    final sp = await SharedPreferences.getInstance();
    final isDarkMode = sp.getBool("isDarkTheme");
    if (isDarkMode == null) {
      final useDarkTheme = switch(themeMode){
        ThemeMode.system => AppResponsiveTheme.colorModeOf(context) == AppThemeMode.dark,
        ThemeMode.light => false,
        ThemeMode.dark => true,
      };
      _darkTheme = useDarkTheme;
    } else {
      _darkTheme = isDarkMode;
    }
    notifyListeners();
  }
}

Load current theme :

class _MyAppState extends State<MyApp> {
  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addPostFrameCallback((_) {
      context.read<ThemeProvide>().loadCurrentTheme(context);
    });
  }
  /// .... other codes ...
  /// ...

Toggle theme :

onPressed: () {
  context.read<ThemeProvider>().toggleTheme();
}

// set to specific dark
onPressed: () {
  context.read<ThemeProvider>().toggleTheme(isDark: true);
}

Then use it with AppResponsiveTheme:

AppResponsiveTheme(
  themeMode: themeProvider.theme,
  config: ColorConfig(
    lightColors: AppColors.light().toThemeColor(),
    darkColors: AppColors.dark().toThemeColor(),
  ),
  child: MaterialApp(
    // ...
  ),
)

Key Components #

Text Components #

Use the Txt widget for consistent typography:

// Different text styles
Txt.titleX('Extra Large Title')
Txt.title32('Large Title')
Txt.title24('Medium Title')
Txt.title18('Small Title')
Txt.regular16('Regular text')
Txt.regular14('Regular smaller text')
Txt.small13('Small text')
Txt.tiny12('Tiny text')

// Specialized styles
Txt.appbar('App Bar Title')
Txt.button('Button Text')

// With additional styling
Txt.title24(
  'Styled Title',
  color: context.colors.primary,
  maxLines: 2,
  textAlign: TextAlign.center,
)

Spacing Components #

Use VGap and HGap for consistent vertical and horizontal spacing:

Column(
  children: [
    Txt.title24('Title'),
    VGap.medium16(), // 16px vertical gap
    Txt.regular16('Description'),
    VGap.large24(), // 24px vertical gap
    Row(
      children: [
        Icon(Icons.star),
        HGap.xsmall8(), // 8px horizontal gap
        Txt.small13('Rating'),
      ],
    ),
  ],
)

Border Radius Extensions #

Use border radius extensions for consistent rounded corners:

Container(
  decoration: BoxDecoration(
    color: context.colors.primary,
    borderRadius: RadiusSize.medium16.borderRadiusCircular,
  ),
  child: Text('Rounded Container'),
)

// Available radius sizes
RadiusSize.zero
RadiusSize.xsmall4
RadiusSize.small8
RadiusSize.medium16
RadiusSize.medium20
RadiusSize.medium24
RadiusSize.medium28
RadiusSize.big44
RadiusSize.custom(value)

Padding Extensions #

Use padding extensions for consistent spacing:

Container(
  padding: Insets.medium16.paddingAll,
  child: Text('Padded text'),
)

Container(
  padding: Insets.medium16.paddingHorizontal,
  child: Text('Horizontally padded text'),
)

// Available padding sizes
Insets.zero
Insets.xxsmall4
Insets.xsmall8
Insets.small10
Insets.small12
Insets.medium16
Insets.medium18
Insets.medium20
Insets.large24
Insets.xlarge32
Insets.xxlarge40
Insets.xxxlarge66
Insets.xxxxlarge80
Insets.custom(value)

Responsive Scaling #

Use the extension methods to scale dimensions based on screen size:

// Width-based scaling (scales with screen width)
Container(width: 20.w, height: 30.h)

// Relative scaling (considers both dimensions)
Container(width: 15.r, height: 15.r)

// Text scaling (adjusts for different screen sizes)
Text('Responsive Text', style: TextStyle(fontSize: 18.t))

Context Extensions #

Access theme data from any widget with context extensions:

// Access colors
final primaryColor = context.colors.primary;
final backgroundColor = context.colors['background']; //or use with extension : context.colors.background

// Access typography theme
final titleStyle = context.textTheme?.title24;

// Check device theme
final isDarkMode = context.isDeviceThemeDark;

Advanced Configuration #

Theme Config for Responsive Design #

Use ThemeConfig to handle different screen sizes:

// Initialize in your app's root
void main() {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(
    MultiProvider(
      providers: [ChangeNotifierProvider(create: (context) => ThemeProvider())],
      child: MyApp(),
    ),
  );
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // Initialize ThemeConfig
    ThemeConfig.init(context);
    
    return AppResponsiveTheme(
      // ...
    );
  }
}

// Use responsive values
Container(
  padding: EdgeInsets.all(
    ThemeConfig().value(16, tablet: 24, desktop: 32)
  ),
  // ...
)

Tips for Effective Use #

  1. Be Consistent: Use the predefined text styles, spacing, and radius values for a consistent look.

  2. Responsive Design: Use the .w, .h, .r, and .t extensions to create layouts that adapt to different screen sizes.

  3. Theme Toggling: Implement a theme provider that allows users to toggle between light and dark modes.

  4. Organization: Create a dedicated theme configuration file where you define all your colors and theme settings.

  5. Reusable Components: Build reusable UI components that leverage the theme system for consistent styling.

🌟 Love this package? Give it a ⭐ on GitHub & show some 💖 — your support means everything!
~ 👤 Nayan Parmar

Example Project #

Check out the example project for a complete implementation of responsive_theme.

License #

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

3
likes
150
points
284
downloads

Publisher

verified publishertcircle.kesug.com

Weekly Downloads

Adaptive Styles – from DARK to BRIGHT. Powerful Theme Solution for Flutter Apps. "#flutter" "#responsive" "#theme"

Repository (GitHub)

Documentation

API reference

License

MIT (license)

Dependencies

equatable, flutter

More

Packages that depend on responsive_theme