flutter刷新页面的方法

1.setState(){}

这种方法最常见,但是有些地方引用的话,刷新的成本比较大,刷新的是整个页面,数据太多加载太慢的话,会有闪烁的现象

2.利用GlobalKey进行局部刷新

参考链接:https://blog.csdn.net/mubowen666/article/details/103988777
其他类似文章:https://www.jianshu.com/p/23a2e8a96a79

这种方法类似于iOS中的set方法,通过设置某个属性的时候,去刷新某个控件。在flutter中这种刷新方式,是对上面setState(){}方法的改进,根本的方法还是setState(){},只不过是通过方法去刷新某个控件。如下:

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State {
  int count = 0;
  GlobalKey<_TextWidgetState> textKey = GlobalKey();
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Demo'),
      ),
      body: Container(
        alignment: Alignment.center,
        child: Column(
          children: [
            TextWidget(textKey), //需要更新的Text
            FlatButton(
              child: new Text('按钮 $count'),
              color: Theme.of(context).accentColor,
              onPressed: () {
                count++; // 这里我们只给他值变动,状态刷新交给下面的Key事件
                textKey.currentState.onPressed(count);  //其实这个count值已经改变了 但是没有重绘所以我们看到的只是我们定义的初始值
              },
            ),
          ],
        ),
      ),
    );
  }
}

//封装的widget
class TextWidget extends StatefulWidget {
  final Key key;

  const TextWidget(this.key);

  @override
  _TextWidgetState createState() => _TextWidgetState();
}

class _TextWidgetState extends State {
  String text = "0";

  void onPressed(int count) {
    setState((){
      text = count.toString();
    });
  }

  @override
  Widget build(BuildContext context) {
    return new Text(text);
  }
}

3.通过provider进行局部刷新

内容来源:https://cloud.tencent.com/developer/article/1719264

首先在pubspec.yaml中添加provider依赖

# provider 
provider: ^3.1.0

下面通过provider来实现一个发送验证码的案例。

创建一个TimerModel文件

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:rxdart/rxdart.dart';

class TimerModel extends ChangeNotifier{

 StreamSubscription _subscription;
 int _count = 0;///当前计数

 int get count =  10 - _count;///剩余时间

 _setCount(){
 _count++;
 notifyListeners();
 }

 startTimer(){
 _count = 0;
 _subscription = Observable.periodic(Duration(seconds: 1))
  .startWith(10)
  .take(10)
  .listen((t){
  _setCount();
 });
 }

 @override
 void dispose() {
 _subscription?.cancel();
 super.dispose();
 }

页面布局如下:

void main() =  runApp(MyApp());

class MyApp extends StatelessWidget {
 @override
 Widget build(BuildContext context) {
 return MaterialApp(
  home: Scaffold(
  appBar: AppBar(
   title: Text("短信倒计时"),
  ),
  body: Center(
   child: ChangeNotifierProvider

可以看到MyApp是继承自 StatelessWidget的,是一个没有状态的widget。
通过在TimerModel中调用notifyListeners();实现刷新的效果。

这种刷新方法,有点类似于iOS中的通知、观察者模式(KVO),通过监听某个属性的变化,对页面进行相应的处理。

4.StreamBuilder实现局部刷新

承接第3点,作者文章后半部分提到了结合StreamBuilder对页面进行刷新:
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:rxdart/rxdart.dart';

void main() =  runApp(MyApp());

class MyApp extends StatelessWidget {

 final StreamController _streamController = StreamController

此方法是通过sink.add方法向streamController.sink中添加一个事件流,StreamBuilder接收到这个stream流后,触发builder方法,去重绘页面,最后在页面小会的时候释放掉资源。

StreamBuilder其实有更多的用处,不单单说是简单的局部刷新用处,例如下面的,一个网络请求方法不断的接收stream图片流事件,需要将这些图片流展示在Image控件上,这样就能够实现让图片变成视频的效果:flutter一次请求多次接收值

你可能感兴趣的:(flutter刷新页面的方法)