|
13 | 13 | ## ✨ Features |
14 | 14 |
|
15 | 15 | - 📱 **Responsive Scaling**: Automatic scaling of width, height, font size, and more |
16 | | -- 🎯 **CSS-like Breakpoints**: Media query-style breakpoints (Bootstrap, Tailwind, Material Design) |
| 16 | +- ⚡ **InheritedWidget-Based Scope**: Efficient, targeted rebuilds with `ScreenUtilPlusScope` |
| 17 | +- 🎯 **Context-Aware Extensions**: New `context.w()`, `context.h()`, `context.sp()` for optimal performance |
| 18 | +- 🎨 **CSS-like Breakpoints**: Media query-style breakpoints (Bootstrap, Tailwind, Material Design) |
17 | 19 | - 📐 **SwiftUI-like Size Classes**: Compact/Regular size classes for adaptive layouts |
18 | | -- 🎨 **Adaptive Widgets**: Breakpoint-aware containers, text, and builders |
19 | | -- 🚀 **Performance Optimized**: Intelligent rebuild detection with Equatable |
| 20 | +- 🧩 **Adaptive Widgets**: Breakpoint-aware containers, text, and builders |
| 21 | +- 🚀 **Performance Optimized**: Intelligent rebuild detection with optional `autoRebuild: false` |
20 | 22 | - 🎭 **Responsive Theme**: Automatic text style scaling in themes |
21 | 23 | - 📦 **Zero Configuration**: Works out of the box with sensible defaults |
22 | | -- 🧪 **Well Tested**: 98.3% code coverage with 500+ tests |
| 24 | +- 🧪 **Well Tested**: 99.2% code coverage with 619 tests |
23 | 25 |
|
24 | 26 | ## 📦 Installation |
25 | 27 |
|
26 | 28 | Add this to your package's `pubspec.yaml` file: |
27 | 29 |
|
28 | 30 | ```yaml |
29 | 31 | dependencies: |
30 | | - flutter_screenutil_plus: ^1.3.2 |
| 32 | + flutter_screenutil_plus: ^1.4.0 |
31 | 33 | ``` |
32 | 34 |
|
33 | 35 | Then run: |
@@ -83,6 +85,106 @@ Container( |
83 | 85 | ) |
84 | 86 | ``` |
85 | 87 |
|
| 88 | +### 2. Use Responsive Extensions |
| 89 | + |
| 90 | +```dart |
| 91 | +Container( |
| 92 | + width: 100.w, // Responsive width |
| 93 | + height: 50.h, // Responsive height |
| 94 | + padding: EdgeInsets.all(16.r), // Responsive padding |
| 95 | + child: Text( |
| 96 | + 'Hello World', |
| 97 | + style: TextStyle(fontSize: 16.sp), // Responsive font |
| 98 | + ), |
| 99 | +) |
| 100 | +``` |
| 101 | + |
| 102 | +### 3. **NEW in v1.4.0**: Context-Aware Extensions (Recommended) |
| 103 | + |
| 104 | +For better performance with `autoRebuild: false`, use context-aware extensions: |
| 105 | + |
| 106 | +```dart |
| 107 | +Container( |
| 108 | + width: context.w(100), // Context-aware width |
| 109 | + height: context.h(50), // Context-aware height |
| 110 | + padding: context.edgeInsets(all: 16), // Context-aware padding |
| 111 | + child: Text( |
| 112 | + 'Hello World', |
| 113 | + style: TextStyle(fontSize: context.sp(16)), // Context-aware font |
| 114 | + ), |
| 115 | +) |
| 116 | +``` |
| 117 | + |
| 118 | +## 🚀 Performance Optimization (v1.4.0) |
| 119 | + |
| 120 | +### InheritedWidget-Based Scope |
| 121 | + |
| 122 | +Version 1.4.0 introduces `ScreenUtilPlusScope` for efficient, targeted rebuilds: |
| 123 | + |
| 124 | +```dart |
| 125 | +ScreenUtilPlusInit( |
| 126 | + designSize: const Size(360, 690), |
| 127 | + autoRebuild: false, // 🎯 NEW: Disable automatic tree-wide rebuilds |
| 128 | + builder: (context, child) { |
| 129 | + return MaterialApp( |
| 130 | + home: child, |
| 131 | + ); |
| 132 | + }, |
| 133 | + child: HomePage(), |
| 134 | +) |
| 135 | +``` |
| 136 | + |
| 137 | +**Benefits of `autoRebuild: false`:** |
| 138 | + |
| 139 | +- ⚡ **Significantly faster** - Only widgets that need responsive values rebuild |
| 140 | +- 🎯 **Targeted updates** - Only widgets using `context.w()`, `context.su`, or R-widgets rebuild |
| 141 | +- 🔄 **Backward compatible** - Defaults to `true` for existing apps |
| 142 | + |
| 143 | +### Context-Aware Extensions |
| 144 | + |
| 145 | +When using `autoRebuild: false`, use context-aware extensions for optimal performance: |
| 146 | + |
| 147 | +```dart |
| 148 | +// ✅ Recommended with autoRebuild: false |
| 149 | +context.w(100) // Scale width |
| 150 | +context.h(50) // Scale height |
| 151 | +context.r(20) // Scale radius |
| 152 | +context.sp(16) // Scale font size |
| 153 | +context.spMin(12) // Scale font with minimum |
| 154 | +context.dg(100) // Scale diagonal |
| 155 | +context.dm(100) // Scale diameter |
| 156 | +
|
| 157 | +// Spacing helpers |
| 158 | +context.verticalSpace(20) // Vertical spacing |
| 159 | +context.horizontalSpace(20) // Horizontal spacing |
| 160 | +
|
| 161 | +// Complex values |
| 162 | +context.edgeInsets(all: 16) // Scaled EdgeInsets |
| 163 | +context.edgeInsets( // Custom EdgeInsets |
| 164 | + horizontal: 16, |
| 165 | + vertical: 8, |
| 166 | +) |
| 167 | +context.borderRadius(all: 12) // Scaled BorderRadius |
| 168 | +
|
| 169 | +// Access ScreenUtilPlus instance |
| 170 | +final su = context.su; // Get ScreenUtilPlus instance |
| 171 | +``` |
| 172 | + |
| 173 | +### Migration to Context-Aware Extensions |
| 174 | + |
| 175 | +```dart |
| 176 | +// ❌ Old way (still works, but rebuilds entire tree) |
| 177 | +Container(width: 100.w, height: 50.h) |
| 178 | +
|
| 179 | +// ✅ New way (efficient with autoRebuild: false) |
| 180 | +Container(width: context.w(100), height: context.h(50)) |
| 181 | +``` |
| 182 | + |
| 183 | +**When to use each:** |
| 184 | + |
| 185 | +- **`autoRebuild: true`** (default): Use `.w`, `.h`, `.sp` extensions - simpler syntax |
| 186 | +- **`autoRebuild: false`**: Use `context.w()`, `context.h()`, `context.sp()` - better performance |
| 187 | + |
86 | 188 | ## 📚 Core Features |
87 | 189 |
|
88 | 190 | ### Responsive Extensions |
@@ -393,6 +495,7 @@ ScreenUtilPlusInit( |
393 | 495 | | Property | Type | Default Value | Description | |
394 | 496 | | ----------------- | ---------------- | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | |
395 | 497 | | designSize | Size | Size(360,690) | The size of the device screen in the design draft, in dp | |
| 498 | +| autoRebuild | bool | true | **NEW in v1.4.0**: When false, only widgets using context-aware extensions or `context.su` rebuild on screen changes (improves performance) | |
396 | 499 | | builder | Function | null | Return widget that uses the library in a property (ex: MaterialApp's theme) | |
397 | 500 | | child | Widget | null | A part of builder that its dependencies/properties don't use the library | |
398 | 501 | | rebuildFactor | RebuildFactor | RebuildFactors.size | Function that takes old and new screen metrics and returns whether to rebuild or not when changes occur. See [RebuildFactors](#rebuild-factors) | |
@@ -529,15 +632,32 @@ switch (deviceType) { |
529 | 632 |
|
530 | 633 | #### Context Extensions |
531 | 634 |
|
532 | | -| Extension | Description | Example | |
533 | | -| ---------------------- | ----------------------------- | ------------------------------------------------- | |
534 | | -| `context.breakpoint` | Current breakpoint | `context.breakpoint` | |
535 | | -| `context.isAtLeast()` | Check if at least breakpoint | `context.isAtLeast(Breakpoint.md)` | |
536 | | -| `context.isLessThan()` | Check if less than breakpoint | `context.isLessThan(Breakpoint.lg)` | |
537 | | -| `context.isBetween()` | Check if between breakpoints | `context.isBetween(Breakpoint.sm, Breakpoint.lg)` | |
538 | | -| `context.sizeClasses` | Get size classes | `context.sizeClasses` | |
539 | | -| `context.adaptive()` | Get AdaptiveValues | `context.adaptive()` | |
540 | | -| `context.responsive()` | Get ResponsiveQuery | `context.responsive()` | |
| 635 | +| Extension | Description | Example | |
| 636 | +| --------------------------- | ----------------------------- | ------------------------------------------------- | |
| 637 | +| **Context-Aware (v1.4.0)** | | | |
| 638 | +| `context.w(value)` | Scale width | `context.w(100)` | |
| 639 | +| `context.h(value)` | Scale height | `context.h(50)` | |
| 640 | +| `context.r(value)` | Scale radius | `context.r(20)` | |
| 641 | +| `context.sp(value)` | Scale font size | `context.sp(16)` | |
| 642 | +| `context.spMin(value)` | Scale font with minimum | `context.spMin(12)` | |
| 643 | +| `context.dg(value)` | Scale diagonal | `context.dg(100)` | |
| 644 | +| `context.dm(value)` | Scale diameter | `context.dm(100)` | |
| 645 | +| `context.verticalSpace()` | Create vertical spacing | `context.verticalSpace(20)` | |
| 646 | +| `context.horizontalSpace()` | Create horizontal spacing | `context.horizontalSpace(20)` | |
| 647 | +| `context.edgeInsets()` | Create scaled EdgeInsets | `context.edgeInsets(all: 16)` | |
| 648 | +| `context.borderRadius()` | Create scaled BorderRadius | `context.borderRadius(all: 12)` | |
| 649 | +| `context.su` | Get ScreenUtilPlus instance | `context.su` | |
| 650 | +| **Breakpoints** | | | |
| 651 | +| `context.breakpoint` | Current breakpoint | `context.breakpoint` | |
| 652 | +| `context.isAtLeast()` | Check if at least breakpoint | `context.isAtLeast(Breakpoint.md)` | |
| 653 | +| `context.isLessThan()` | Check if less than breakpoint | `context.isLessThan(Breakpoint.lg)` | |
| 654 | +| `context.isBetween()` | Check if between breakpoints | `context.isBetween(Breakpoint.sm, Breakpoint.lg)` | |
| 655 | +| **Size Classes** | | | |
| 656 | +| `context.sizeClasses` | Get size classes | `context.sizeClasses` | |
| 657 | +| **Utilities** | | | |
| 658 | +| `context.adaptive()` | Get AdaptiveValues | `context.adaptive()` | |
| 659 | +| `context.responsive()` | Get ResponsiveQuery | `context.responsive()` | |
| 660 | +| `context.mediaQueryData` | Get MediaQueryData | `context.mediaQueryData` | |
541 | 661 |
|
542 | 662 | #### Widgets |
543 | 663 |
|
|
0 commit comments