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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Flutter实现上拉刷新的方法可以通过ListView的ScrollController属性来判断是否滑动到了底部来做加载更多的处理。具体实现步骤如下: 1. 首先,在ListView的外部包裹一个RefreshIndicator组件,用于实现下拉刷新。 2. 在RefreshIndicator的onRefresh属性添加一个监听方法,用于监听下拉刷新的操作。 3. 在ListView的itemBuilder,根据列表的长度生成相应的列表项。 4. 在滑动到ListView底部时,触发加载更多的操作。 5. 在加载更多操作的方法,发送网络请求获取新的数据,并更新列表的数据源。 下面是一个示例代码,可以参考其的实现方式: ```dart import 'package:flutter/material.dart'; import 'package:dio/dio.dart'; class MyPage extends StatefulWidget { @override _MyPageState createState() => _MyPageState(); } class _MyPageState extends State<MyPage> { List _list = []; int _page = 1; @override void initState() { super.initState(); _getData(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("上拉刷新示例"), ), body: _list.length > 0 ? RefreshIndicator( onRefresh: _onRefresh, child: ListView.builder( itemCount: _list.length, itemBuilder: (context, index) { return ListTile( title: Text(_list[index]["email"], maxLines: 1), ); }, ), ) : Text("加载..."), ); } Future<void> _onRefresh() async { print('执行刷新'); _getData(); await Future.delayed(Duration(seconds: 3)); } _getData() async { var apiUrl = "https://jsonplaceholder.typicode.com/posts/$_page/comments"; Response result = await Dio().get(apiUrl); setState(() { _list.addAll(result.data); _page++; }); print("获取数据操作"); } } ``` 这样,你就可以在Flutter实现上拉刷新的功能了。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [Flutter 实现下拉刷新和上拉加载](https://blog.csdn.net/weixin_44911775/article/details/124985084)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [Flutter 实现下拉刷新上拉加载的示例代码](https://download.csdn.net/download/weixin_38586279/12744666)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值