Adaptive UI UX
A Flutter package for creating adaptive UIs that automatically adjust based on user interaction patterns. This package helps build interfaces that evolve to better serve your users by tracking widget usage and reorganizing layouts to prioritize frequently used elements.
Features
- AdaptiveWidget: Wrap any Flutter widget to track user interactions (taps, long presses, hover, etc.)
- AdaptiveLayout: Container that intelligently rearranges child widgets based on real usage patterns
- Interaction Tracking: Built-in system for monitoring how users interact with your interface
- Layout Storage: Automatically persists optimized layouts using SharedPreferences
- Rule Engine: Configurable system with multiple optimization strategies
- Zero User Configuration: Works automatically in the background with sensible defaults
Getting Started
Installation
Add this package to your pubspec.yaml file:
dependencies:
adaptive_ui_ux: ^0.0.1
Run the following command to install:
flutter pub get
Initialization
Initialize the package in your main.dart
file:
import 'package:flutter/material.dart';
import 'package:adaptive_ui_ux/adaptive_ui_ux.dart';
void main() async {
// Ensure Flutter is initialized
WidgetsFlutterBinding.ensureInitialized();
// Initialize AdaptiveUIUX
await AdaptiveUIUX.init(
customConfig: AdaptiveConfig(
threshold: 10, // How many interactions before layout changes
layoutMode: LayoutMode.stacked, // Use stacked layout
enableAutoAdjust: true, // Auto-adjust layouts
enableDebugLogging: true, // Log events for debugging
),
);
runApp(MyApp());
}
Basic Usage
Example App
Here's a simple example showing how to use the core features:
import 'package:flutter/material.dart';
import 'package:adaptive_ui_ux/adaptive_ui_ux.dart';
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Adaptive UI UX Demo')),
body: AdaptiveLayout(
// Automatically adjust layout after 10 interactions
enableAutoAdjustments: true,
minInteractionsBeforeAdjust: 10,
children: [
// Create adaptive widgets
AdaptiveWidget(
id: 'button1',
child: ElevatedButton(
onPressed: () {},
child: Text('Buy Now'),
),
),
AdaptiveWidget(
id: 'button2',
child: ElevatedButton(
onPressed: () {},
child: Text('Button 2'),
),
),
AdaptiveWidget(
id: 'button3',
child: ElevatedButton(
onPressed: () {},
child: Text('Button 3'),
),
),
],
),
);
}
}
Advanced Usage
Custom Layout Store
// Initialize a custom layout store
final layoutStore = LayoutStore();
// Use it with your AdaptiveLayout
AdaptiveLayout(
layoutStore: layoutStore,
// ...
)
Custom Rules
// Create a rule engine with custom rules
final ruleEngine = RuleEngine(
rules: [
MostUsedFirstRule(),
HighlightOutliersRule(threshold: 1.5),
],
);
// Or set rules later
ruleEngine.setRules([
MostUsedFirstRule(),
PreserveOrderRule(['important_widget_id']),
]);
Configuration Options
// Initialize with custom configuration
await AdaptiveUIUX.init(
customConfig: AdaptiveConfig(
threshold: 15, // Change layout after 15 interactions
layoutMode: LayoutMode.grid, // Use grid layout instead of stacked
enableAutoAdjust: true, // Enable automatic layout adjustments
enableDebugLogging: true, // Log interactions and layout changes
),
);
// Reset adaptive UI data and settings
await AdaptiveUIUX.reset();
Component Documentation
AdaptiveWidget
The AdaptiveWidget
is the core building block that wraps your existing Flutter widgets to make them trackable and adaptable.
Properties
Property | Type | Default | Description |
---|---|---|---|
id |
String | Required | Unique identifier for the widget |
child |
Widget | Required | The widget to wrap and track |
trackTaps |
bool | true | Whether to track tap interactions |
trackLongPress |
bool | true | Whether to track long press interactions |
trackHover |
bool | false | Whether to track hover interactions |
trackFocus |
bool | false | Whether to track focus interactions |
onInteraction |
Function | null | Callback when interaction occurs |
constraints |
BoxConstraints | null | Optional sizing constraints |
Example
AdaptiveWidget(
id: 'unique_widget_id',
trackTaps: true, // Track tap events
trackLongPress: true, // Track long press events
trackHover: false, // Track hover events
trackFocus: false, // Track focus events
onInteraction: (event) {
print('Interaction: ${event.type} on ${event.widgetId}');
},
constraints: BoxConstraints(maxWidth: 200),
child: ElevatedButton(
onPressed: () {},
child: Text('Click Me'),
),
)
Auto ID Generation
You can also let the system generate a unique ID for you:
AdaptiveWidget.auto(
child: ElevatedButton(
onPressed: () {},
child: Text('Auto ID Button'),
),
)
AdaptiveLayout
The AdaptiveLayout
container arranges and manages AdaptiveWidget
children, automatically reordering them based on usage patterns.
Properties
Property | Type | Default | Description |
---|---|---|---|
children |
List | Required | Widgets to arrange adaptively |
direction |
Axis | Axis.vertical | Layout orientation |
enableAutoAdjustments |
bool | true | Whether to auto-adapt layout |
autoAdjustInterval |
Duration | 30 seconds | Time between layout evaluations |
minInteractionsBeforeAdjust |
int | 10 | Interactions needed before adaptation |
rules |
List | null | Custom layout rules |
layoutStore |
LayoutStore | null | Custom layout storage |
tracker |
InteractionTracker | null | Custom interaction tracker |
padding |
EdgeInsetsGeometry | null | Padding around the layout |
Example
AdaptiveLayout(
direction: Axis.vertical,
enableAutoAdjustments: true,
autoAdjustInterval: Duration(seconds: 30),
minInteractionsBeforeAdjust: 10,
padding: EdgeInsets.all(16),
onLayoutChanged: (layout) {
print('Layout changed: ${layout.id}');
},
children: [
// Your AdaptiveWidgets here
],
)
Rule Engine
The RuleEngine
is the brain that analyzes interaction data and applies rules to optimize layout. You generally don't need to interact with it directly, as AdaptiveLayout
manages it for you.
Built-in Rules
Rule | Description |
---|---|
MostUsedFirstRule |
Prioritizes widgets with the most interactions |
LeastUsedFirstRule |
Prioritizes widgets with the fewest interactions |
HighlightOutliersRule |
Identifies widgets with usage patterns significantly different from others |
Custom Rules
You can create custom rules by implementing the LayoutRule
interface:
class MyCustomRule implements LayoutRule {
@override
List<String> apply(Map<String, int> interactionCounts) {
// Your custom logic here
// Return a list of widget IDs in your preferred order
return [...];
}
}
Manual Control
If you need direct control over the rule engine:
// Create a rule engine
final ruleEngine = RuleEngine(
tracker: InteractionTracker.instance,
layoutStore: LayoutStore.instance,
rules: [MostUsedFirstRule()],
minInteractions: 5,
);
// Start automatic adjustments
ruleEngine.startAutoAdjustments(interval: Duration(seconds: 30));
// Manually evaluate rules
await ruleEngine.evaluateAndApplyRules();
Advanced Usage Examples
E-commerce Product Page
AdaptiveLayout(
minInteractionsBeforeAdjust: 5,
children: [
AdaptiveWidget(id: 'buy_now', child: BuyNowButton()),
AdaptiveWidget(id: 'add_to_cart', child: AddToCartButton()),
AdaptiveWidget(id: 'add_to_wishlist', child: WishlistButton()),
AdaptiveWidget(id: 'share_product', child: ShareButton()),
AdaptiveWidget(id: 'reviews', child: ReviewsSection()),
],
)
Settings Screen
AdaptiveLayout(
direction: Axis.vertical,
padding: EdgeInsets.all(16.0),
children: [
AdaptiveWidget(id: 'account_settings', child: AccountSettingsCard()),
AdaptiveWidget(id: 'notification_settings', child: NotificationSettingsCard()),
AdaptiveWidget(id: 'privacy_settings', child: PrivacySettingsCard()),
AdaptiveWidget(id: 'appearance_settings', child: AppearanceSettingsCard()),
AdaptiveWidget(id: 'about', child: AboutCard()),
],
)
Example App
Check the /example
folder for a complete example app demonstrating:
- AdaptiveWidgets with tap tracking
- AdaptiveLayout with auto-adjustments
- Layout adaptations based on usage
- Manual layout reset
Requirements
- Flutter 2.0.0 or higher
- Dart 2.17.0 or higher
- Android, iOS, Web, macOS, Windows, or Linux
License
This project is licensed under the MIT License - see the LICENSE file for details.
Libraries
- adaptive_layout
- adaptive_ui_ux
- A Flutter package for adaptive UX that adjusts layout based on user interaction patterns.
- adaptive_ui_ux_instance
- adaptive_widget
- backends/local_store
- layout_store
- models/interaction_event
- models/layout_config
- rule_engine
- tracker