博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
flutter 使用Bloc和refresh 进行搭建页面
阅读量:6826 次
发布时间:2019-06-26

本文共 10045 字,大约阅读时间需要 33 分钟。

主要解决问题是 页面请求数据 数据进行动态刷新 (刷新某些控件)

首先进行创建bloc

//bloc基类import 'package:flutter/material.dart';class BaseBlocWidget{  Stream streams() => null;  Widget streamBuilder
({ T initalData, Function success, Function error, Function loading, Function finished, Stream
stream, }) { return StreamBuilder(//StreamBuilder 这个是比较主要的 stream: stream, initialData: initalData, builder: (context, AsyncSnapshot
snapshot) { if (finished != null) { finished(); } if (snapshot.hasData) { if (success != null) return success(snapshot.data); } else if (snapshot.hasError) { if (error != null) return error(snapshot.hasError); } else { if (loading != null) return loading(); } }); }}复制代码
import 'package:flutter/widgets.dart';import 'package:flutter_tticar/ui/bloc/BaseBlocWidget.dart';import 'package:flutter_tticar/ui/comment/http/TTicarWork.dart';import 'package:flutter_tticar/ui/setting/bean/GoodsCollectBean.dart';import 'package:rxdart/rxdart.dart';class CounterBloc extends BaseBlocWidget {//GoodsCollectBean 为网络接口请求返回 解析的bean  final _fetcher = new PublishSubject
(); streams() => _fetcher.stream; void dispose() { if (!_fetcher.isClosed) { _fetcher.close(); } } void fetchQueryList(String pageNum) async {//解析数据 _refreshDate(pageNum, (map) => GoodsCollectBean.fromJson(map)); } void _refreshDate(String pageNum, Function handleData) async { new TTicarWork().loadCollectGood(pageNum, "20").listen((request) { try{ _fetcher.sink.add(handleData(request)); //异步回调 }catch(e){//解析异常等 _fetcher.sink.addError(e,null); } }, onError: (e) {//请求异常等 _fetcher.sink.addError(e, null); }); }}复制代码

页面基本逻辑操作

import 'package:flutter/material.dart';import 'package:flutter_tticar/ui/comment/http/TTicarWork.dart';import 'package:flutter_tticar/ui/comment/status/StatusView.dart';import 'package:flutter_tticar/ui/setting/bean/BaseRequestBean.dart';import 'package:flutter_tticar/ui/setting/bean/GoodsCollectBean.dart';import 'package:flutter_tticar/ui/setting/collect/item/GoodsItem.dart';import 'package:flutter_tticar/ui/setting/myCollectBloc/CounterBloc.dart';import "package:pull_to_refresh/pull_to_refresh.dart";import 'package:flutter_slidable/flutter_slidable.dart';import 'package:fluttertoast/fluttertoast.dart';class GoodsCollectPage extends StatefulWidget {  @override  GoodsCollectPageState createState() => new GoodsCollectPageState();}class GoodsCollectPageState extends State
{ CounterBloc _blocProvider = new CounterBloc(); StatusView _statusView = new StatusView(); RefreshController _refreshController; ScrollController _scrollController; int pageNum = 1; //设置页数 int pageSize = 1; //设置页数 bool refreshUp = true; //判断时候是上拉加载还是下拉刷新 bool refresh = false; //判断是第几次(解决 pull_to_refresh 出现的问题) List
dataList = []; @override void initState() { //设置初始数据 super.initState(); _blocProvider.fetchQueryList("$pageNum"); _scrollController = new ScrollController(); _refreshController = new RefreshController(); } @override void dispose() { _blocProvider.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return _buildData(); } Widget _buildData() { return _blocProvider.streamBuilder
( //数据返回回调 success: (data) { var request = data as GoodsCollectBean; if (null != request.result && request.success) { //判断有数据 pageSize = int.parse(request.result.size); if (pageNum == 1) { dataList.clear(); } dataList.addAll(request.result.list); } else if (pageNum == 1 && request.success && request.result.list.length == 0) { // 第一页 无数据 return _statusView.empty("喜欢就藏起来啊,别客气~"); } else { // 服务器有异常 return _statusView.empty(request.msg); } if (refresh) { _refreshController.sendBack(refreshUp, RefreshStatus.completed); } _refreshController.sendBack( false, pageSize > pageNum ? RefreshStatus.canRefresh : RefreshStatus.completed); return new SmartRefresher( enablePullDown: true, enablePullUp: true, controller: _refreshController, onRefresh: _onRefresh, headerBuilder: (context, mode) { return new ClassicIndicator( //这个可以定义公共组件 mode: mode, height: 45.0, releaseText: '松开手刷新', refreshingText: '刷新中', completeText: '刷新完成', failedText: '刷新失败', idleText: '下拉刷新', ); }, footerBuilder: (context, mode) { return new ClassicIndicator( mode: mode, height: 45, completeText: "加载完成"); }, child: new ListView.builder( controller: _scrollController, itemCount: dataList.length, itemBuilder: (context,index){ return _getDatas(dataList[index]); }, )); }, stream: _blocProvider.streams(), //必须设置的属性 error: (msg) { return _statusView.error(msg); //解析或者接口异常页面 }, loading: () { return _statusView.showLoading(); //加载页 }); } void _onRefresh(bool up) { refreshUp = up; refresh = true; if (up) { pageNum = 1; //headerIndicator callback _refreshDate("$pageNum"); } else { if (pageSize > pageNum) { pageNum++; //footerIndicator Callback _refreshDate("$pageNum"); } } } //请求数据 void _refreshDate(String pageNum) { _blocProvider.fetchQueryList(pageNum); } Widget _getDatas(ListBean item) { return new Card( color: Colors.white, elevation: 0, margin: new EdgeInsets.only(left: 10, right: 10, top: 10), child:new Text("自己添加列表数据"), ); }}复制代码

缺省页工具类

import 'package:flutter/material.dart';import 'package:flutter_tticar/ui/comment/utile/FrameAnimationImage.dart';//缺省页工具类class StatusView {  AnimationController controller;  Animation
animation; List
images = []; Widget showLoading() { for (var i = 0; i < 12; i++) { images.add("static/images/donghua_000$i.png"); } return new Container( color: Colors.white, child: new Center( child: new Column( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children:
[ new FrameAnimationImage( assetList: images, width: 100, height: 100, interval: 100, ), Text("正在加载中……") ], ), ), ); } Widget error(Exception msg) { String errMsg=""; return new Container( child: new Center( child: new Column( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children:
[ Image.asset("static/images/ic_status_view_empty_data.png", width: 100, height: 100), Text("服务器出现异常请稍后再试"), ], ), ), ); } Widget empty(msg) { return new Container( child: new Center( child: new Column( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children:
[ Image.asset("static/images/icon_no_collection.png", width: 100, height: 100), Text("${msg}"), ], ), ), ); }}复制代码

设置帧动画

/// Flutter FrameAnimation 逐帧动画(这个是在别处引用的 具体地址忘了)import 'package:flutter/material.dart';class FrameAnimationImage extends StatefulWidget {  final List
assetList; final double width; final double height; final int interval; FrameAnimationImage( {this.assetList, this.width, this.height, this.interval = 200}); @override State
createState() { return _FrameAnimationImageState(); }}class _FrameAnimationImageState extends State
with SingleTickerProviderStateMixin { // 动画控制 Animation
_animation; AnimationController _controller; int interval = 200; @override void initState() { super.initState(); if (widget.interval != null) { interval = widget.interval; } final int imageCount = widget.assetList.length; final int maxTime = interval * imageCount; // 启动动画controller _controller = new AnimationController( duration: Duration(milliseconds: maxTime), vsync: this); _controller.addStatusListener((AnimationStatus status) { if (status == AnimationStatus.completed) { _controller.forward(from: 0.0); // 完成后重新开始 } }); _animation = new Tween
(begin: 0, end: imageCount.toDouble()) .animate(_controller) ..addListener(() { setState(() { // the state that has changed here is the animation object’s value }); }); _controller.forward(); } @override void dispose() { _controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { int ix = _animation.value.floor() % widget.assetList.length; List
images = []; // 把所有图片都加载进内容,否则每一帧加载时会卡顿 for (int i = 0; i < widget.assetList.length; ++i) { if (i != ix) { images.add(Image.asset( widget.assetList[i], width: 0, height: 0, )); } } images.add(Image.asset( widget.assetList[ix], width: widget.width, height: widget.height, )); return Stack(alignment: AlignmentDirectional.center, children: images); }}复制代码

网络请求请参考

具体效果如下

转载于:https://juejin.im/post/5cc7fc21f265da036b4a71c1

你可能感兴趣的文章
jquery3.1.1报错Uncaught TypeError: a.indexOf is not a function
查看>>
树莓派Raspberry实践笔记-安装使用minicom
查看>>
使用emmet如何生成lipsum的随机内容
查看>>
从0开始安装fedora23的笔记-- 以及使用fedora的常规问题-2
查看>>
理解ClassLoader基本原理
查看>>
Java并发基础06. 线程范围内共享数据
查看>>
PHP实验三
查看>>
Python-序列号和模块复习-64
查看>>
查找目录下的所有文件中是否含有某个字符串
查看>>
12月6号,jQuery 序列化form
查看>>
aardio修改IDE里代码的字体
查看>>
FJNU2018低程F jq解救fuls (贪心乱搞)题解
查看>>
线程池原理及其实现
查看>>
HttpWebRequest发送数据 post
查看>>
MySQL的Root用户密码
查看>>
pip 使用
查看>>
_stdcall与_cdecl区别
查看>>
Ubuntu jsp平台使用JDBC来连接MySQL数据库
查看>>
Kinect For Windows V2开发日志四:使用OpenCV显示深度图像
查看>>
正则表达式 -- 常用元字符
查看>>