1.FutureBuilder
Very useful widget for handling asynchronous operations and building interfaces. It is typically used with Future objects to build the interface after an asynchronous operation has completed.
import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget {<!-- --> @override Widget build(BuildContext context) {<!-- --> return MaterialApp( home: MyHomePage(), ); } } class MyHomePage extends StatelessWidget {<!-- --> Future<String> fetchData() async {<!-- --> // Simulate asynchronous operations, such as requesting data from the network await Future.delayed(Duration(seconds: 2)); return "Hello, World!"; } @override 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}")); } }, ), ); } }
If a FutureBuilder is rebuilt frequently while building, it can cause performance issues. Make sure not to nest a FutureBuilder inside a frequently rebuilt widget to avoid unnecessary performance overhead.
2.StreamController
To implement streaming refresh, you usually need to use Stream and StreamBuilder to listen and update data.
import 'dart:async'; import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget {<!-- --> @override Widget build(BuildContext context) {<!-- --> return MaterialApp( home: MyHomePage(), ); } } class MyHomePage extends StatefulWidget {<!-- --> @override _MyHomePageState createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> {<!-- --> StreamController<int> _dataStreamController = StreamController<int>(); int_data = 0; @override void initState() {<!-- --> super.initState(); // Simulate a data source and generate new data every second Timer.periodic(Duration(seconds: 1), (timer) {<!-- --> _dataStreamController.sink.add(_data + + ); }); } @override void dispose() {<!-- --> _dataStreamController.close(); // Close the stream super.dispose(); } @override 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
Used to monitor value changes of ValueListenable objects and build interfaces. It allows you to update the interface when values change without rebuilding the entire widget tree.
import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class CounterModel extends ValueNotifier<int> {<!-- --> CounterModel(int value) : super(value); } class MyApp extends StatelessWidget {<!-- --> @override 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
Used to obtain the constraint information of the parent widget and customize the build interface based on the constraint information. It is often used to create widgets that dynamically adjust based on parent dimensions, such as adaptive layouts.
import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget {<!-- --> @override 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)}\ Height: ${<!-- -->constraints.maxHeight.toStringAsFixed(2)}', style: TextStyle(color: Colors.white), ), ); }, ), ), ), ), ); } }
5.AnimatedBuilder
A widget used to listen for value changes during animation execution and build the interface. Typically, it is used with an AnimationController or other animation object to update the interface during animation execution.
import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget {<!-- --> @override Widget build(BuildContext context) {<!-- --> return MaterialApp( home:Scaffold( appBar: AppBar( title: Text('AnimatedBuilder Example'), ), body: Center( child: MyAnimationWidget(), ), ), ); } } class MyAnimationWidget extends StatefulWidget {<!-- --> @override _MyAnimationWidgetState createState() => _MyAnimationWidgetState(); } class _MyAnimationWidgetState extends State<MyAnimationWidget> with SingleTickerProviderStateMixin {<!-- --> AnimationController _controller; Animation<double> _animation; @override void initState() {<!-- --> super.initState(); _controller = AnimationController( vsync: this, duration: Duration(seconds: 2), ); _animation = Tween(begin: 0.0, end: 1.0).animate(_controller) ..addListener(() {<!-- --> //Rebuild the interface when the animation value changes setState(() {<!-- -->}); }); _controller.forward(); } @override void dispose() {<!-- --> _controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) {<!-- --> return AnimatedBuilder( animation: _controller, builder: (BuildContext context, Widget child) {<!-- --> returnOpacity( 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
Widget for customizing page transition animations, typically used with Navigator. It allows you to create customized page switching effects, including sliding, gradient, zoom and other animation effects.
import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget {<!-- --> @override Widget build(BuildContext context) {<!-- --> return MaterialApp( home: MyHomePage(), ); } } class MyHomePage extends StatelessWidget {<!-- --> @override 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 {<!-- --> @override 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
A widget for performing animations when switching between different widgets. It allows you to apply custom entry and exit animation effects when switching widgets.
import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget {<!-- --> @override Widget build(BuildContext context) {<!-- --> return MaterialApp( home: MyHomePage(), ); } } class MyHomePage extends StatefulWidget {<!-- --> @override _MyHomePageState createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> {<!-- --> bool _showFirstWidget = true; void _toggleWidget() {<!-- --> setState(() {<!-- --> _showFirstWidget = !_showFirstWidget; }); } @override Widget build(BuildContext context) {<!-- --> return Scaffold( appBar: AppBar( title: Text('AnimatedSwitcher Example'), ), body: Center( child: AnimatedSwitcher( duration: Duration(milliseconds: 500), // The duration of the switching animation child: _showFirstWidget ?FirstWidget( key: ValueKey<int>(1), //Specify different keys to distinguish different widgets ) : SecondWidget( key: ValueKey<int>(2), //Specify different keys to distinguish different widgets ), ), ), floatingActionButton: FloatingActionButton( onPressed: _toggleWidget, child: Icon(Icons.swap_horiz), ), ); } } class FirstWidget extends StatelessWidget {<!-- --> FirstWidget({<!-- -->Key key}) : super(key: key); @override 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); @override 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 is a Flutter plugin that simplifies the creation and processing of forms. It makes form management easier by creating form fields and validation logic.
dependencies: flutter_form_builder: ^9.1.1
final GlobalKey<FormBuilderState> _formKey = GlobalKey<FormBuilderState>(); @override 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, // Automatic verification mode 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()) {<!-- --> // Form verification passes, perform submission operation print(_formKey.currentState.value); } }, child: Text('Submit'), ), ], ), ), ), ); }