Flutter局部刷新

在Flutter中,如果我们想要更新页面中的某个widget的状态的话,一般会使用setState方法重走build方法来刷新。当页面布局复杂的时候,这样肯定是不行的。

下面提供了两种局部刷新的方式,通过providerStreamBuilder来实现局部刷新

1、通过provider刷新

首先在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(
            builder: (context) => TimerModel(),
            child: Consumer(builder: (context, timerModel, _) {
              return RaisedButton(
                onPressed: () async {
                  if (timerModel.count == 0) {
                    timerModel.startTimer();
                  }
                },

                child: Text(
                  timerModel.count == 0 ? "获取验证码" : '${timerModel.count} 秒后重发',
                  style: timerModel.count == 0
                      ? TextStyle(color: Colors.blue, fontSize: 14)
                      : TextStyle(color: Colors.grey, fontSize: 14),
                ),
              );
            }),
          ),
        ),
      )
    );
  }
}

可以看到MyApp是继承自 StatelessWidget的,是一个没有状态的widget。

通过在TimerModel中调用notifyListeners();实现刷新的效果。

2、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();

  int count = 10;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text("短信倒计时"),
        ),
        body: Center(
          child: StreamBuilder(
              stream: _streamController.stream,
              initialData: 0,
              builder: (BuildContext context, AsyncSnapshot snapshot) {
                return RaisedButton(
                  onPressed: () async {
                    if (snapshot.data == 0) {
                      startTimer();
                    }
                  },

                  child: Text(
                    snapshot.data == 0 ? "获取验证码" : '${snapshot
                        .data} 秒后重发',
                    style: snapshot.data == 0
                        ? TextStyle(color: Colors.blue, fontSize: 14)
                        : TextStyle(color: Colors.grey, fontSize: 14),
                  ),
                );
              }
          ),
        ),
      )
    );
  }


  startTimer(){
    count = 10;
    Observable.periodic(Duration(seconds: 1))
        .take(10)
        .listen((t){
        _streamController.sink.add(--count);
    });
  }
}

使用StreamBuilder来局部刷新,通过sink.add方法向streamController.sink中添加一个事件流,这个流会被StreamBuilderstream接收,然后触发builder方法。
最后在页面销毁的时候释放资源。

效果图

Flutter局部刷新_第1张图片

你可能感兴趣的:(Flutter开发)