当编写高质量的Flutter代码时,以下每个方法都附有详细的代码示例。代码示例中将包括高效和普通对比示例。
1. 使用有意义的变量和方法命名
// 不好的示例
var a = 10;
var b = calculate(a);
// 好的示例
var initialNumber = 10;
var calculatedResult = calculate(initialNumber);
2. 使用const关键字来定义不可变对象
// 不好的示例
final myNumber = new MyNumber();
// 好的示例
const myNumber = MyNumber();
3. 遵循Dart代码风格指南
// 不好的示例
int result=calculate(5);
// 好的示例
int calculate(int number) {
// code here
return result;
}
4. 使用async/await处理异步任务
// 不好的示例
http.get('https://example.com').then((response) {
print(response.body);
});
// 好的示例
void fetchData() async {
var response = await http.get('https://example.com');
print(response.body);
}
5. 使用正确的数据类型
// 不好的示例
var count = "10";
// 好的示例
int count = 10;
6. 减少widget的build方法中的逻辑
// 不好的示例
Widget build(BuildContext context) {
if (condition1) {
// code here
} else if (condition2) {
// code here
} else {
// code here
}
}
// 好的示例
Widget build(BuildContext context) {
if (condition1) {
return Widget1();
}
if (condition2) {
return Widget2();
}
return Widget3();
}
7. 使用keys来优化列表操作
// 不好的示例
List<Widget> buildList() {
var items = <Widget>[];
for (var i = 0; i < data.length; i++) {
items.add(Widget(item: data[i]));
}
return items;
}
// 好的示例
List<Widget> buildList() {
return data.map((item) => Widget(item: item)).toList();
}
8. 使用Builder构建局部刷新widget
// 不好的示例
Widget build(BuildContext context) {
return Container(
child: SomeWidget(),
);
}
// 好的示例
Widget build(BuildContext context) {
return Container(
child: Builder(
builder: (context) => SomeWidget(),
),
);
}
9. 使用Expanded或Flexible来管理布局
// 不好的示例
Row(
children: [
Widget1(),
Widget2(),
Widget3(),
],
);
// 好的示例
Row(
children: [
Expanded(child: Widget1()),
Expanded(child: Widget2()),
Widget3(),
],
);
10. 使用Keys来在列表中标识唯一性
// 不好的示例
ListView.builder(
itemCount: data.length,
itemBuilder: (context, index) {
return Widget(data: data[index]);
},
);
// 好的示例
ListView.builder(
itemCount: data.length,
itemBuilder: (context, index) {
return Widget(
key: Key(data[index].id),
data: data[index],
);
},
);
11. 使用函数式编程来简化代码
// 不好的示例
for (var item in list) {
if (item.condition) {
item.process();
}
}
// 好的示例
list.where((item) => item.condition).forEach((item) => item.process());
12. 使用继承或混入来重用代码
// 不好的示例
class MyWidget1 extends StatelessWidget {
// code here
}
class MyWidget2 extends StatelessWidget {
// code here
}
// 好的示例
class BaseWidget extends StatelessWidget {
// code here
}
class MyWidget1 extends BaseWidget {
// code here
}
class MyWidget2 extends BaseWidget {
// code here
}
13. 避免在build方法中进行重复计算
// 不好的示例
Widget build(BuildContext context) {
var result = calculateResult(); // 假设计算耗时较长
return Text(result.toString());
}
// 好的示例
Widget build(BuildContext context) {
var result = useMemoizedResult(() => calculateResult());
return Text(result.toString());
}
14. 使用函数回调处理用户交互
// 不好的示例
void onButtonPressed() {
// code here
}
Widget build(BuildContext context) {
return RaisedButton(
onPressed: onButtonPressed(),
child: Text('Button'),
);
}
// 好的示例
void onButtonPressed() {
// code here
}
Widget build(BuildContext context) {
return RaisedButton(
onPressed: onButtonPressed,
child: Text('Button'),
);
}
15. 及时释放资源
// 不好的示例
void fetchData() async {
var httpClient = HttpClient();
// code here
}
// 好的示例
void fetchData() async {
var httpClient = HttpClient();
try {
// code here
} finally {
httpClient.close(); // 及时关闭
}
}
16. 封装常用的UI组件
// 不好的示例
Widget build(BuildContext context) {
return Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
// code here
);
}
// 好的示例
Widget build(BuildContext context) {
return FullScreenContainer(
// code here
);
}
class FullScreenContainer extends StatelessWidget {
final Widget child;
const FullScreenContainer({Key key, this.child}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
child: child,
);
}
}
17. 使用List.generate构建动态列表
// 不好的示例
ListView.builder(
itemCount: data.length,
itemBuilder: (context, index) {
return Widget(item: data[index]);
},
);
// 好的示例
ListView(
children: List.generate(data.length, (index) {
return Widget(item: data[index]);
}),
);
18. 使用带默认值的构造函数
// 不好的示例
class Person {
final String name;
final String age;
Person({this.name, this.age});
}
var person = Person(name: 'John');
// 好的示例
class Person {
final String name;
final String age;
Person({this.name, this.age = ''});
}
var person = Person(name: 'John');
19. 使用Dart的强类型系统
// 不好的示例
Map data = jsonDecode(response.body);
// 好的示例
Map<String, dynamic> data = jsonDecode(response.body);
20. 隔离和重用样式
// 不好的示例
Text(
'Hello',
style: TextStyle(
color: Colors.red,
fontSize: 16,
fontWeight: FontWeight.bold,
),
);
// 好的示例
Text(
'Hello',
style: myTextStyle,
);
final myTextStyle = TextStyle(
color: Colors.red,
fontSize: 16,
fontWeight: FontWeight.bold,
);
21. 使用扩展方法增强现有类
// 不好的示例
String capitalize(String input) {
return input[0].toUpperCase() + input.substring(1);
}
var name = capitalize('john');
// 好的示例
extension StringExtension on String {
String capitalize() {
return this[0].toUpperCase() + substring(1);
}
}
var name = 'john'.capitalize();
22. 使用final和const关键字声明常量
// 不好的示例
var PI = 3.14;
// 好的示例
final double PI = 3.14;
23. 使用导航器管理页面路由
// 不好的示例
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondPage()),
);
// 好的示例
Navigator.pushNamed(context, '/second');
24. 使用Mixin实现代码重用
// 不好的示例
class MyWidget1 extends StatelessWidget {
// code here
}
class MyWidget2 extends StatelessWidget {
// code here
}
// 好的示例
mixin CommonMixin {
// common code here
}
class MyWidget1 extends StatelessWidget with CommonMixin {
// code here
}
class MyWidget2 extends StatelessWidget with CommonMixin {
// code here
}
25. 使用Builder分离复杂的UI构建逻辑
// 不好的示例
Widget build(BuildContext context) {
return Container(
child: Column(
children: [
SomeWidget(),
AnotherWidget(),
],
),
);
}
// 好的示例
Widget build(BuildContext context) {
return Container(
child: Builder(
builder: (context) {
return Column(
children: [
SomeWidget(),
AnotherWidget(),
],
);
},
),
);
}
26. 使用默认参数简化方法调用
// 不好的示例
void printMessage(String message, {String prefix = '', String suffix = ''}) {
print(prefix + message + suffix);
}
printMessage('Hello', prefix: '[', suffix: ']');
// 好的示例
void printMessage(String message, {String prefix = '', String suffix = ''}) {
print(prefix + message + suffix);
}
printMessage('Hello', prefix: '[', suffix: ']');
27. 使用适当的状态管理方案
// 不好的示例
class MyApp extends StatelessWidget {
final String data;
MyApp({Key key, this.data}) : super(key: key);
@override
Widget build(BuildContext context) {
return Text(data);
}
}
// 好的示例
class MyApp extends StatefulWidget {
final String data;
MyApp({Key key, this.data}) : super(key: key);
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return Text(widget.data);
}
}
28. 使用闭包进行私有变量封装
// 不好的示例
class Counter {
var count = 0;
void increment() {
count++;
}
void decrement() {
count--;
}
}
// 好的示例
class Counter {
int count = 0;
void Function() get increment {
return () {
count++;
};
}
void Function() get decrement {
return () {
count--;
};
}
}
29. 使用自定义Painter创建自定义UI
// 不好的示例
Widget build(BuildContext context) {
return Container(
color: Colors.blue,
child: CustomPaint(
painter: MyPainter(),
child: Container(),
),
);
}
class MyPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
// code here
}
@override
bool shouldRepaint(MyPainter oldDelegate) => true;
}
// 好的示例
Widget build(BuildContext context) {
return Container(
color: Colors.blue,
child: CustomPaint(
painter: MyPainter(),
),
);
}
class MyPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
// code here
}
@override
bool shouldRepaint(MyPainter oldDelegate) => false;
}
30. 使用位操作来处理多选状态
// 不好的示例
bool option1Selected = false;
bool option2Selected = false;
void toggleOption1() {
option1Selected = !option1Selected;
}
void toggleOption2() {
option2Selected = !option2Selected;
}
// 好的示例
int options = 0;
void toggleOption(int option) {
options ^= (1 << option);
}
bool isOptionSelected(int option) {
return (options & (1 << option)) != 0;
}
31. 使用FutureBuilder处理异步数据
// 不好的示例
Widget build(BuildContext context) {
return FutureBuilder(
future: fetchData(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return Text(snapshot.data.toString());
}
return CircularProgressIndicator();
},
);
}
// 好的示例
Widget build(BuildContext context) {
return FutureBuilder(
future: fetchData(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasData) {
return Text(snapshot.data.toString());
}
return Text('No data');
}
return CircularProgressIndicator();
},
);
}
32. 使用Clipper创建自定义的剪切区域
// 不好的示例
Widget build(BuildContext context) {
return ClipRRect(
borderRadius: BorderRadius.circular(10),
child: Container(
// code here
),
);
}
// 好的示例
Widget build(BuildContext context) {
return ClipPath(
clipper: MyClipper(),
child: Container(
// code here
),
);
}
class MyClipper extends CustomClipper<Path> {
@override
Path getClip(Size size) {
// code here
return path;
}
@override
bool shouldReclip(CustomClipper<Path> oldClipper) => false;
}
33. 使用Hero动画创建过渡效果
// 不好的示例
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondPage()),
);
// 好的示例
Navigator.push(
context,
MaterialPageRoute(builder: (context) => HeroPage()),
);
class HeroPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Hero(
tag: 'image',
child: Image.asset('image.png'),
),
);
}
}
34. 使用InheritedWidget来共享数据
// 不好的示例
class MyApp extends StatelessWidget {
final String title;
MyApp(this.title);
@override
Widget build(BuildContext context) {
return Text(title);
}
}
// 好的示例
class MyApp extends StatelessWidget {
final String title;
MyApp(this.title);
@override
Widget build(BuildContext context) {
return InheritedTitle(
title: title,
child: Text(title),
);
}
}
class InheritedTitle extends InheritedWidget {
final String title;
InheritedTitle({Key key, @required this.title, @required Widget child})
: super(key: key, child: child);
@override
bool updateShouldNotify(InheritedTitle oldWidget) => title != oldWidget.title;
}
35. 使用SingleTickerProviderStateMixin管理动画控制器
// 不好的示例
class MyWidget extends StatefulWidget {
@override
_MyWidgetState createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
AnimationController controller;
@override
void initState() {
super.initState();
controller = AnimationController(
duration: Duration(seconds: 1),
vsync: this, // 需要手动指定vsync参数
);
}
@override
void dispose() {
controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Container();
}
}
// 好的示例
class MyWidget extends StatefulWidget {
@override
_MyWidgetState createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> with SingleTickerProviderStateMixin {
AnimationController controller;
@override
void initState() {
super.initState();
controller = AnimationController(
duration: Duration(seconds: 1),
vsync: this, // 自动使用当前State作为vsync
);
}
@override
void dispose() {
controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Container();
}
}
36. 遵循命名规范: 使用一致的命名约定,以增加代码的可读性和可维护性。例如,使用驼峰式命名法CamelCase来命名类和方法,使用小写字母和下划线来命名变量和函数。
// 不良示例
var c = Container();
// 良好示例
var container = Container();
37. 减少小部件的重建: 尽可能使用const修饰符创建不可变小部件,以减少不必要的小部件重建,提高性能。
// 不良示例
Widget build(BuildContext context) {
return Text('Hello World');
}
// 良好示例
Widget build(BuildContext context) {
return const Text('Hello World');
}
38. 使用关键字:nnn进行空安全声明: 在声明变量时,使用空安全的关键字?和!,以帮助在编译时捕获空引用错误。
// 不良示例
String name;
// 良好示例
String? name;
39. 使用类型推断: 让Dart自动推断变量的类型,以减少不必要的类型注释,使代码更简洁。
// 不良示例
List<String> fruits = [];
// 良好示例
var fruits = <String>[];
40. 使用final和const进行不可变声明: 标记不需要修改的变量为final或const,以提醒自己和其他开发人员该变量的不可变性。
// 不良示例
var name = 'John';
name = 'Mike'; // 可修改
// 良好示例
final name = 'John';
const age = 25;
41. 避免冗余的小部件嵌套: 最小化小部件的嵌套层次,以提高代码的清晰度和执行效率。
// 不良示例
Column(
children: [
Container(
child: Row(
children: [
Text('Hello World'),
],
),
),
],
)
// 良好示例
Row(
children: [
Text('Hello World'),
],
)
42. 使用Key标识唯一小部件: 当列表中的小部件需要更新时,为它们分配唯一的Key,以确保正确的渲染和状态更新。
// 不良示例
ListView.builder(
itemBuilder: (context, index) => Text('Item'),
)
// 良好示例
ListView.builder(
itemBuilder: (context, index) => Text('Item', key: Key('$index')),
)
43. 使用async和await处理异步任务: 使用async和await关键字来优雅地处理异步任务,提高代码的可读性。
// 不良示例(回调风格)
fetchData((data) {
processData(data, (result) {
setState(() {
this.result = result;
});
});
});
// 良好示例(async/await风格)
final data = await fetchData();
final result = processData(data);
setState(() {
this.result = result;
});
44. 处理小部件生命周期: 当使用有状态小部件时,妥善处理生命周期方法,避免出现内存泄漏或不必要的资源消耗。
@override
void dispose() {
_controller.dispose();
super.dispose();
}
45. 抽象常用样式为主题: 使用Theme小部件将常用的样式属性抽象为主题数据,以便在应用程序中共享和重复使用。
```dart
// 不良示例
Text('Hello World', style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold))
// 良好示例
Text('Hello World', style: Theme.of(context).textTheme.headline6)
```
46. 避免在构建方法中执行昂贵的操作: 在构建方法中尽量避免执行耗时或昂贵的操作,以避免影响性能。
```dart
// 不良示例
Widget build(BuildContext context) {
final result = fetchData(); // 昂贵的操作
return Text('Result: $result');
}
// 良好示例
Widget build(BuildContext context) {
return FutureBuilder(
future: fetchData(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Text('Result: ${snapshot.data}');
}
return CircularProgressIndicator();
},
);
}
```
47. 使用final替代var: 在可能的情况下,使用final关键字而不是var关键字声明变量,以提高代码的可读性。
```dart
// 不良示例
var fruits = <String>[];
// 良好示例
final fruits = <String>[];
```
48. 封装经常使用的小部件: 创建自定义小部件来封装经常使用的复杂小部件,以提高代码的重用性和可维护性。
```dart
class CustomButton extends StatelessWidget {
final String text;
final VoidCallback onPressed;
const CustomButton({required this.text, required this.onPressed});
@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: onPressed,
child: Text(text),
);
}
}
```
49. 使用builder构造器简化小部件树: 使用builder构造器来简化小部件树的构建,减少嵌套。
```dart
// 不良示例
Widget build(BuildContext context) {
return Container(
child: Padding(
child: Text('Hello World'),
padding: EdgeInsets.all(16),
),
);
}
// 良好示例
Widget build(BuildContext context) {
return Container(
child: Builder(
builder: (context) {
return Padding(
padding: EdgeInsets.all(16),
child: Text('Hello World'),
);
},
),
);
}
```
50. 使用enum管理状态: 使用enum集中管理各种状态,以减少硬编码的同时提高代码可读性。
```dart
enum ViewState { idle, loading, error, success }
class MyWidget extends StatefulWidget {
@override
_MyWidgetState createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
ViewState _state = ViewState.idle;
@override
Widget build(BuildContext context) {
if (_state == ViewState.loading) {
return CircularProgressIndicator();
} else if (_state == ViewState.error) {
return Text('Error occurred.');
} else if (_state == ViewState.success) {
return Text('Success!');
}
return Text('Idle');
}
}
```