Flutter: 使用流来分离数据和UI

"lib\main.dart"

import 'package:flutter/material.dart';
import 'package:english_words/english_words.dart';
import 'package:flutter_demo/src/list.dart';

void main() {
  final list = ListService();
  runApp(MyApp(list: list));
}

class MyApp extends StatelessWidget {
  MyApp({Key key, this.list}) : super(key: key);

  ListService list;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyHome(list: list),
    );
  }
}

class MyHome extends StatefulWidget {
  MyHome({Key key, this.list}) : super(key: key);

  final ListService list;

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

class _MyHomeState extends State<MyHome> {
  @override
  void dispose() {
    widget.list.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter Demo'),
      ),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.add),
        onPressed: () =>
            widget.list.addOneWord(generateWordPairs().take(1).elementAt(0)),
      ),
      body: StreamBuilder<Set<WordPair>>(
        stream: widget.list.lists,
        initialData: Set<WordPair>(),
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting) {
            return Center(
              child: CircularProgressIndicator(),
            );
          }

          return ListView(
            children: <Widget>[
              for (WordPair w in snapshot.data)
                ListTile(
                  title: Text(
                    w.asLowerCase,
                    style: TextStyle(fontSize: 28),
                  ),
                  trailing: IconButton(
                    onPressed: () => widget.list.delOneWord.add(w),
                    icon: Icon(Icons.close),
                  ),
                ),
            ],
          );
        },
      ),
    );
  }
}

"lib\src\list.dart":

import 'dart:async';
import 'package:rxdart/rxdart.dart';
import 'package:english_words/english_words.dart';

class ListService {
  Stream<Set<WordPair>> get lists => _listsSubject.stream;
  // BehaviorSubject: Subject的变体,需要初始值并在订阅时发出其当前值。
  final _listsSubject = BehaviorSubject<Set<WordPair>>();
  var _lists = Set<WordPair>();

  Sink<WordPair> get delOneWord => _delOneWordController.sink;
  // StreamController: 该控制器允许在其流上发送数据
  final _delOneWordController = StreamController<WordPair>();

  ListService() {
    _getList().then((_) {
      _listsSubject.add(_lists);
    });

    _delOneWordController.stream.listen((WordPair w) {
      _lists.remove(w);
      _listsSubject.add(_lists);
    });
  }

  void dispose() {
    _delOneWordController.close();
  }

  // 模拟异步获取列个列表数据
  Future<Null> _getList() async {
    await Future.delayed(Duration(seconds: 4));
    _lists = generateWordPairs().take(5).toSet();
  }

  /// 向列表添加单个数据
  void addOneWord(WordPair w) {
    _lists.add(w);
    _listsSubject.add(_lists);
  }

  /// 删除列表的指定数据
  // void delOneWord(WordPair w) {
  //   _lists.remove(w);
  //   _listsSubject.add(_lists);
  // }
}

在StatefulWidget中初始化流服务

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: DashPage(),
    );
  }
}

class DashPage extends StatefulWidget {
  @override
  _DashPageState createState() => _DashPageState();
}

class _DashPageState extends State<DashPage> {
  int _currentIndex = 0;
  final PageController _controller = PageController();
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      bottomNavigationBar: BottomNavigationBar(
        type: BottomNavigationBarType.fixed,
        currentIndex: _currentIndex,
        fixedColor: Colors.purple,
        onTap: (int index) {
          setState(() {
            _currentIndex = index;
            _controller.jumpToPage(index);
          });
        },
        items: <BottomNavigationBarItem>[
          BottomNavigationBarItem(
              icon: Icon(Icons.home),
              activeIcon: Icon(Icons.home),
              title: Text("Home")),
          BottomNavigationBarItem(
              icon: Icon(Icons.search),
              activeIcon: Icon(Icons.search),
              title: Text("Search")),
        ],
      ),
      body: PageView(
        controller: _controller,
        onPageChanged: (int index) {
          setState(() {
            _currentIndex = index;
          });
        },
        children: <Widget>[
          HomePage(),
          Center(child: Text('Search Page')),
        ],
      ),
    );
  }
}

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  HomeService homeService;

  @override
  void initState() {
    super.initState();
    homeService = HomeService();
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('demo'),
      ),
      body: StreamBuilder<int>(
        stream: homeService.index$,
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting) {
            return Text('0');
          }
          int index = snapshot.data;
          return Column(
            children: <Widget>[
              Text(index.toString()),
              OutlineButton(
                child: Text('add'),
                onPressed: () {
                  homeService.add(index + 1);
                },
              ),
            ],
          );
        },
      ),
    );
  }
}

class HomeService {
  Stream<int> get index$ => _indexSubject.stream;
  final _indexSubject = BehaviorSubject<int>.seeded(0);
  Function(int) get add => _indexSubject.sink.add;

  dispose() {
    _indexSubject.close();
  }
}

转载于:https://www.cnblogs.com/ajanuw/p/10933780.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值