diff --git a/CHANGELOG.md b/CHANGELOG.md index 7216964..3973cb9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -## 1.0.5 +## 1.0.6 * Fixed LTR issue diff --git a/README.md b/README.md index cbca832..f65cf65 100644 --- a/README.md +++ b/README.md @@ -130,6 +130,33 @@ class _MyHomePageState extends State { } ``` +## Important Implementation Note + +When using FlexibleWrap with dynamic dimensions (height, width, or item count), you should add a ValueKey to force widget rebuilds when these properties change: + +```dart +FlexibleWrap( + key: ValueKey('$itemHeight-$itemWidth-$itemCount'), // Force rebuild when dimensions change + spacing: spacing, + runSpacing: runSpacing, + isOneRowExpanded: isOneRowExpanded, + textDirection: isRTL ? TextDirection.rtl : TextDirection.ltr, + children: [ + // Your widgets here + ], +) +``` + +**Why is this needed?** + +The ValueKey ensures that Flutter recognizes the widget as "changed" when dimensions are updated, forcing a complete rebuild of the render object. This is particularly important when: + +- Child widget dimensions change dynamically +- The number of children changes +- Layout properties are modified at runtime + +Without the ValueKey, Flutter's widget tree optimization might prevent the render object from properly updating, leading to visual inconsistencies where dimension changes don't immediately reflect in the UI. + ## Customization FlexibleWrap offers several customization options to tailor the layout to your needs: diff --git a/example/lib/main.dart b/example/lib/main.dart index 053bec7..f1aae9a 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -192,37 +192,68 @@ class _MyHomePageState extends State { child: SizedBox( width: wrapWidth, child: FlexibleWrap( + key: ValueKey( + '$itemHeight-$itemWidth-$itemCount'), // Force rebuild when dimensions change spacing: spacing, runSpacing: spacing, isOneRowExpanded: isOneRowExpanded, textDirection: isRTL ? TextDirection.rtl : TextDirection.ltr, children: List.generate(itemCount, (int index) { - return SizedBox( + return Container( height: itemHeight, width: itemWidth, - child: ListTile( - tileColor: Colors.blue, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(8.0)), - title: const Text( - "Lorem Ipsum is simply dummy text", - style: TextStyle(color: Colors.white), - overflow: TextOverflow.ellipsis, - ), - subtitle: const Text( - "Lorem Ipsum has been the industry's standard", - style: TextStyle(color: Colors.white), - overflow: TextOverflow.ellipsis, - ), - leading: Icon( - Icons.insert_emoticon, - color: Colors.white, - size: itemWidth / 5, - ), - trailing: const Icon( - Icons.favorite, - color: Colors.white, + decoration: BoxDecoration( + color: Colors.blue, + borderRadius: BorderRadius.circular(8.0), + ), + child: Material( + color: Colors.transparent, + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Row( + children: [ + Icon( + Icons.insert_emoticon, + color: Colors.white, + size: (itemWidth / 5).clamp(16.0, 48.0), + ), + const SizedBox(width: 8), + Expanded( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Text( + "Lorem Ipsum is simply dummy text", + style: const TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + ), + overflow: TextOverflow.ellipsis, + maxLines: itemHeight > 80 ? 2 : 1, + ), + if (itemHeight > 60) + Text( + "Lorem Ipsum has been the industry's standard", + style: const TextStyle( + color: Colors.white70, + fontSize: 12, + ), + overflow: TextOverflow.ellipsis, + maxLines: itemHeight > 100 ? 2 : 1, + ), + ], + ), + ), + const Icon( + Icons.favorite, + color: Colors.white, + size: 20, + ), + ], + ), ), ), );