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'),
            ),
          ],
        ),
      ),
    ),
  );
}