Flutter中的各种刷新小部件
1.FutureBuilder
用于处理异步操作和构建界面的非常有用的小部件。它通常与 Future 对象一起使用,用于在异步操作完成后构建界面。
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
Future<String> fetchData() async {
// 模拟异步操作,例如从网络请求数据
await Future.delayed(Duration(seconds: 2));
return "Hello, World!";
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("FutureBuilder Example"),
),
body: FutureBuilder<String>(
future: fetchData(),
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
} else if (snapshot.hasError) {
return Center(child: Text("Error: ${snapshot.error}"));
} else {
return Center(child: Text("Data: ${snapshot.data}"));
}
},
),
);
}
}
如果 FutureBuilder 在构建时频繁重建,可能会导致性能问题。确保不要将 FutureBuilder 嵌套在频繁重建的小部件内部,以避免不必要的性能开销。
2.StreamController
要实现流式刷新,通常需要使用 Stream 和 StreamBuilder 来监听和更新数据。
import 'dart:async';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
StreamController<int> _dataStreamController = StreamController<int>();
int _data = 0;
void initState() {
super.initState();
// 模拟一个数据源,每秒生成一个新数据
Timer.periodic(Duration(seconds: 1), (timer) {
_dataStreamController.sink.add(_data++);
});
}
void dispose() {
_dataStreamController.close(); // 关闭流
super.dispose();
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("StreamBuilder Example"),
),
body: StreamBuilder<int>(
stream: _dataStreamController.stream,
builder: (BuildContext context, AsyncSnapshot<int> snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
} else if (snapshot.hasError) {
return Center(child: Text("Error: ${snapshot.error}"));
} else {
return Center(child: Text("Data: ${snapshot.data}"));
}
},
),
);
}
}
3.ValueListenableBuilder
用于监听 ValueListenable 对象的值变化并构建界面。它允许你在值发生变化时更新界面,而无需重建整个小部件树。
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class CounterModel extends ValueNotifier<int> {
CounterModel(int value) : super(value);
}
class MyApp extends StatelessWidget {
Widget build(BuildContext context) {
final counterModel = CounterModel(0);
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('ValueListenableBuilder Example'),
),
body: Center(
child: ValueListenableBuilder<int>(
valueListenable: counterModel,
builder: (BuildContext context, int value, Widget child) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Counter Value: $value'),
ElevatedButton(
onPressed: () {
counterModel.value++;
},
child: Text('Increment'),
),
],
);
},
),
),
),
);
}
}
4.LayoutBuilder
用于获取父级小部件的约束信息并根据约束信息自定义构建界面。它通常用于创建根据父级尺寸动态调整的小部件,如自适应布局。
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('LayoutBuilder Example'),
),
body: Center(
child: Container(
color: Colors.blue,
width: 200.0,
height: 200.0,
child: LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
return Center(
child: Text(
'Width: ${constraints.maxWidth.toStringAsFixed(2)}nHeight: ${constraints.maxHeight.toStringAsFixed(2)}',
style: TextStyle(color: Colors.white),
),
);
},
),
),
),
),
);
}
}
5.AnimatedBuilder
用于在动画执行过程中监听值的变化并构建界面的小部件。通常,它与 AnimationController 或其他动画对象一起使用,以便在动画执行期间更新界面。
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('AnimatedBuilder Example'),
),
body: Center(
child: MyAnimationWidget(),
),
),
);
}
}
class MyAnimationWidget extends StatefulWidget {
_MyAnimationWidgetState createState() => _MyAnimationWidgetState();
}
class _MyAnimationWidgetState extends State<MyAnimationWidget>
with SingleTickerProviderStateMixin {
AnimationController _controller;
Animation<double> _animation;
void initState() {
super.initState();
_controller = AnimationController(
vsync: this,
duration: Duration(seconds: 2),
);
_animation = Tween(begin: 0.0, end: 1.0).animate(_controller)
..addListener(() {
// 当动画值发生变化时重建界面
setState(() {});
});
_controller.forward();
}
void dispose() {
_controller.dispose();
super.dispose();
}
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: _controller,
builder: (BuildContext context, Widget child) {
return Opacity(
opacity: _animation.value,
child: Container(
color: Colors.blue,
width: 200.0,
height: 200.0,
child: Center(
child: Text(
'Opacity: ${_animation.value.toStringAsFixed(2)}',
style: TextStyle(color: Colors.white),
),
),
),
);
},
);
}
}
6.PageRouteBuilder
用于自定义页面过渡动画的小部件,通常与 Navigator 一起使用。它允许你创建自定义的页面切换效果,包括滑动、渐变、缩放等动画效果。
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('PageRouteBuilder Example'),
),
body: Center(
child: ElevatedButton(
onPressed: () {
Navigator.of(context).push(
PageRouteBuilder(
pageBuilder: (context, animation, secondaryAnimation) {
return SecondPage();
},
transitionsBuilder: (context, animation, secondaryAnimation, child) {
const begin = Offset(1.0, 0.0);
const end = Offset.zero;
const curve = Curves.easeInOut;
var tween = Tween(begin: begin, end: end).chain(CurveTween(curve: curve));
var offsetAnimation = animation.drive(tween);
return SlideTransition(
position: offsetAnimation,
child: child,
);
},
),
);
},
child: Text('Go to Second Page'),
),
),
);
}
}
class SecondPage extends StatelessWidget {
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Second Page'),
),
body: Center(
child: ElevatedButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text('Back to First Page'),
),
),
);
}
}
7.AnimatedSwitcher
用于在切换不同小部件时执行动画的小部件。它允许你在切换小部件时应用自定义的入场和出场动画效果。
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
bool _showFirstWidget = true;
void _toggleWidget() {
setState(() {
_showFirstWidget = !_showFirstWidget;
});
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('AnimatedSwitcher Example'),
),
body: Center(
child: AnimatedSwitcher(
duration: Duration(milliseconds: 500), // 切换动画的持续时间
child: _showFirstWidget
? FirstWidget(
key: ValueKey<int>(1), // 指定不同的 key 以区分不同的小部件
)
: SecondWidget(
key: ValueKey<int>(2), // 指定不同的 key 以区分不同的小部件
),
),
),
floatingActionButton: FloatingActionButton(
onPressed: _toggleWidget,
child: Icon(Icons.swap_horiz),
),
);
}
}
class FirstWidget extends StatelessWidget {
FirstWidget({Key key}) : super(key: key);
Widget build(BuildContext context) {
return Container(
key: key,
width: 200,
height: 200,
color: Colors.blue,
child: Center(
child: Text(
'First Widget',
style: TextStyle(color: Colors.white),
),
),
);
}
}
class SecondWidget extends StatelessWidget {
SecondWidget({Key key}) : super(key: key);
Widget build(BuildContext context) {
return Container(
key: key,
width: 200,
height: 200,
color: Colors.green,
child: Center(
child: Text(
'Second Widget',
style: TextStyle(color: Colors.white),
),
),
);
}
}
8.FormBuilder
FormBuilder 是一个 Flutter 插件,用于简化表单的创建和处理。它通过创建表单字段和验证逻辑,让表单管理更容易。
dependencies:
flutter_form_builder: ^9.1.1
final GlobalKey<FormBuilderState> _formKey = GlobalKey<FormBuilderState>();
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Login Form'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: FormBuilder(
key: _formKey,
autovalidateMode: AutovalidateMode.always, // 自动验证模式
child: Column(
children: <Widget>[
FormBuilderTextField(
name: 'username',
decoration: InputDecoration(labelText: 'Username'),
validator: FormBuilderValidators.required(context),
),
FormBuilderTextField(
name: 'password',
decoration: InputDecoration(labelText: 'Password'),
validator: FormBuilderValidators.required(context),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: () {
if (_formKey.currentState.saveAndValidate()) {
// 表单验证通过,执行提交操作
print(_formKey.currentState.value);
}
},
child: Text('Submit'),
),
],
),
),
),
);
}