-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathflutter
More file actions
185 lines (163 loc) · 6.01 KB
/
flutter
File metadata and controls
185 lines (163 loc) · 6.01 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
---
description: Enforces best practices for Flutter development, focusing on context-aware code generation, widget design, state management, and performance optimization. Provides comprehensive guidelines for writing clean, efficient Flutter code with proper context.
globs: **/*.dart
---
# Flutter Best Practices
You are an expert in Flutter development, Dart programming, and mobile application architecture.
You understand modern Flutter development practices, architectural patterns, and the importance of providing complete context in code generation.
### Context-Aware Code Generation
- Always provide complete widget context including imports and class definitions
- Include relevant configuration files (pubspec.yaml) when generating projects
- Generate complete widget signatures with proper parameters and documentation
- Include comprehensive documentation explaining the purpose, parameters, and state management
- Provide context about the widget's role in the larger application architecture
### Widget Design and Structure
- Follow clean code principles with meaningful names and proper documentation
- Structure widgets in logical hierarchies following composition over inheritance
- Implement proper separation of concerns (UI, business logic, data access)
- Use modern Flutter features (null safety, extension methods) appropriately
- Maintain consistent code formatting using dartfmt or similar tools
### State Management
- Use appropriate state management solutions (Provider, Riverpod, Bloc, GetX)
- Implement proper dependency injection and inversion of control
- Configure proper routing with Navigator 2.0 or Go Router
- Use proper widget composition and stateful/stateless patterns
- Implement proper error boundaries and error handling
### Testing and Quality
- Write comprehensive widget tests with proper test context
- Include integration tests for critical paths
- Use proper mocking strategies with Mockito
- Implement E2E tests with Flutter Driver or integration_test
- Include performance tests for critical components
- Maintain high test coverage for core business logic
### Performance Optimization
- Implement proper widget rebuilding strategies
- Use const constructors where appropriate
- Configure proper image caching and loading
- Implement proper list virtualization with ListView.builder
- Use proper memory management techniques
- Optimize animations and transitions
### Platform Integration
- Implement proper platform channel usage
- Use proper platform-specific code with conditional imports
- Configure proper permissions handling
- Implement proper deep linking
- Use proper native feature integration
### Build and Deployment
- Use proper dependency management (pub)
- Implement proper CI/CD pipelines
- Configure proper environment variables
- Implement proper logging and monitoring
- Use proper deployment strategies for app stores
### Examples
```dart
/// A reusable button widget with customizable appearance and behavior.
///
/// This widget encapsulates common button styling and behavior patterns
/// while allowing for customization through parameters.
import 'package:flutter/material.dart';
class CustomButton extends StatelessWidget {
final String title;
final VoidCallback onPress;
final Color? backgroundColor;
final double borderRadius;
final EdgeInsets padding;
const CustomButton({
Key? key,
required this.title,
required this.onPress,
this.backgroundColor,
this.borderRadius = 8.0,
this.padding = const EdgeInsets.all(12.0),
}) : super(key: key);
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: backgroundColor ?? theme.primaryColor,
padding: padding,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(borderRadius),
),
),
onPressed: onPress,
child: Text(
title,
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
);
}
}
/// Example of proper state management with StatefulWidget
class ProfileScreen extends StatefulWidget {
final String userId;
const ProfileScreen({Key? key, required this.userId}) : super(key: key);
@override
_ProfileScreenState createState() => _ProfileScreenState();
}
class _ProfileScreenState extends State<ProfileScreen> {
String? photoUrl;
bool isLoading = false;
@override
void initState() {
super.initState();
_loadUserProfile();
}
Future<void> _loadUserProfile() async {
setState(() => isLoading = true);
try {
// Fetch user profile data
// photoUrl = await userRepository.getUserPhotoUrl(widget.userId);
} catch (e) {
// Handle error appropriately
} finally {
setState(() => isLoading = false);
}
}
Future<void> takePhoto() async {
setState(() => isLoading = true);
try {
final picker = ImagePicker();
final image = await picker.pickImage(source: ImageSource.camera);
if (image != null) {
setState(() {
photoUrl = image.path;
});
// await userRepository.updateUserPhoto(widget.userId, image.path);
}
} catch (e) {
// Handle error appropriately
} finally {
setState(() => isLoading = false);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Profile')),
body: isLoading
? const Center(child: CircularProgressIndicator())
: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (photoUrl != null)
CircleAvatar(
radius: 100,
backgroundImage: FileImage(File(photoUrl!)),
),
const SizedBox(height: 16),
CustomButton(
title: 'Take Photo',
onPress: takePhoto,
),
],
),
),
);
}
}