flutter中的网络请求和下拉刷新上拉加载,toast的案例
添加依赖
pull_to_refresh: ^1.5.6 dio: ^2.1.0 fluttertoast: ^3.0.1
DioUtil
import 'package:dio/dio.dart'; class DioUtil { static DioUtil _instance; final Dio _mDio = Dio(BaseOptions(baseUrl: "http://192.168.0.60:8080")); Dio get mDio => _mDio; DioUtil._(); static DioUtil getInstance() { if (_instance == null) { _instance = DioUtil._(); _instance._init(); } return _instance; } _init() {} }
Urls
class Urls { static const String getUserUrl = '/user/getAllUserByPage'; }
LogUtils
class LogUtils { static const bool isRelease = const bool.fromEnvironment("dart.vm.product"); static void d(String tag, Object message) { if (!isRelease) _printLog(tag, 'D -> ', message); } static void i(String tag, Object message) { _printLog(tag, 'I -> ', message); } static void e(String tag, Object message, {Exception e}) { _printLog(tag, 'E -> ', message); } static void _printLog(String tag, String level, Object message) { StringBuffer sb = new StringBuffer(); sb..write(level)..write(tag ?? '')..write(': ')..write(message); print(sb.toString()); } }
BaseNetResponseModel
class BaseNetResponseModel<T> { final int code; final String msg; final T data; const BaseNetResponseModel( {this.code, this.msg, this.data, }); }
DataBean
class DataBean { String userid; String job; DataBean.fromJson(Map<String, dynamic> json) { userid = json['userid']; job = json['job']; } }
DataRepository
import './databean.dart'; import 'BaseNetResponseModel.dart'; abstract class DataRepository { Future< BaseNetResponseModel<List<DataBean>>> getUserAll( String pageIndex,String pageSize ); }
NetDataRepository
import 'package:dio/dio.dart'; import 'package:futuredemo/BaseNetResponseModel.dart'; import 'package:futuredemo/DataRepository.dart'; import 'package:futuredemo/DioUtil.dart'; import 'package:futuredemo/databean.dart'; import 'Apis.dart'; class NetDataRepository extends DataRepository { Dio _dio = DioUtil.getInstance().mDio; List<DataBean> companyCustomerList; int code; String msg; Map<String, dynamic> data; @override Future<BaseNetResponseModel<List<DataBean>>> getUserAll( String pageIndex, String pageSize) async { Response response = await _dio.get( Urls.getUserUrl + "?pageIndex=" + pageIndex + "&pageSize=" + pageSize); print(response.data); print(response.data['data']); List userslist = response.data['data']["users"] as List; code = response.data['code']; msg = response.data['msg']; companyCustomerList = userslist.map((customer) { return DataBean.fromJson(customer); }).toList(); return BaseNetResponseModel<List<DataBean>>( code: code, msg: msg, data: companyCustomerList); } }
ToastUtils
import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.dart'; class ToastUtils { static ToastUtils _instance; ToastUtils._(); static ToastUtils getInstance() { if (_instance == null) { _instance = ToastUtils._(); } return _instance; } Future _cancelPreToast() async { await Fluttertoast.cancel(); } static void toastShort(String message) { getInstance()._cancelPreToast(); Fluttertoast.showToast( msg: message, toastLength: Toast.LENGTH_SHORT, gravity: ToastGravity.CENTER, timeInSecForIos: 1, backgroundColor: Colors.grey, textColor: Colors.white, fontSize: 14.0); } static void toastLong(String message) { getInstance()._cancelPreToast(); Fluttertoast.showToast( msg: message, toastLength: Toast.LENGTH_LONG, gravity: ToastGravity.CENTER, timeInSecForIos: 1, backgroundColor: Colors.blue[300], textColor: Colors.white, fontSize: 14.0); } }
PageError
import 'package:flutter/material.dart'; class PageError extends StatelessWidget { final VoidCallback callback; const PageError({Key key, this.callback}) : super(key: key); @override Widget build(BuildContext context) { return Center( child: MaterialButton( child: Text('重新加载', style: TextStyle(color: Theme.of(context).primaryColor),), onPressed: () { if (callback != null) callback(); }), ); } }
PageLoading
import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; class PageLoading extends StatelessWidget { @override Widget build(BuildContext context) { return Center( child: Row( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: <Widget>[ CupertinoActivityIndicator(), ], ), ); } }
JobPage
import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:futuredemo/log_utils.dart'; import 'package:futuredemo/toast_utils.dart'; import './page_error.dart'; import './page_loading.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart'; import 'BaseNetResponseModel.dart'; import 'NetDataRepository.dart'; import 'databean.dart'; class JobPage extends StatefulWidget { @override _JobPageState createState() => _JobPageState(); } class _JobPageState extends State<JobPage> { NetDataRepository _netDataRepository = NetDataRepository(); Future<Map<String, dynamic>> _futureBuilderFuture; List<DataBean> dataList = List(); RefreshController _refreshController = RefreshController(initialRefresh: false); void initState() { super.initState(); _futureBuilderFuture = _loadData(); } void _onRefresh() async { BaseNetResponseModel<List<DataBean>> model = await _netDataRepository.getUserAll("1", "10"); dataList.clear(); dataList.addAll(model.data); // 日志打印 LogUtils.d("tag", model.code); _refreshController.refreshCompleted(); _refreshController.loadComplete(); if (mounted) setState(() {}); } void _onLoading() async { await Future.delayed(Duration(milliseconds: 1000)); if (dataList.length < 30) { dataList.add(dataList[0]); } else { _refreshController.loadNoData(); return; } if (mounted) setState(() {}); _refreshController.loadComplete(); } Future<Map<String, dynamic>> _loadData() async { BaseNetResponseModel<List<DataBean>> model = await _netDataRepository.getUserAll("1", "10"); dataList.clear(); dataList.addAll(model.data); return {"data": 0}; } _refresh() async { setState(() { _futureBuilderFuture = _loadData(); }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( elevation: 0.0, title: Text('职业'), centerTitle: true, ), floatingActionButton: FloatingActionButton( backgroundColor: Theme.of(context).primaryColor, child: Icon( Icons.add, size: 28, color: Colors.white, ), elevation: 4, onPressed: () { //吐司提示 ToastUtils.toastShort("点击了"); }), body: FutureBuilder( builder: (BuildContext context, AsyncSnapshot<Map<String, dynamic>> snapshot) { Widget widget; switch (snapshot.connectionState) { case ConnectionState.none: widget = Container(); break; case ConnectionState.active: case ConnectionState.waiting: widget = PageLoading(); break; case ConnectionState.done: if (snapshot.hasError) { widget = PageError( callback: _refresh, ); } else if (snapshot.hasData) { widget = _buildBody(context); } break; } return widget; }, future: _futureBuilderFuture, ), ); } Column _buildBody(BuildContext context) { return Column( children: <Widget>[ Expanded( child: SmartRefresher( enablePullDown: true, enablePullUp: true, header: WaterDropMaterialHeader( // backgroundColor:Color(OxFF00), ), footer: CustomFooter( builder: (BuildContext context, LoadStatus mode) { Widget body; if (mode == LoadStatus.idle) { body = Row(children: <Widget>[ Expanded( flex: 3, child: Divider( indent: 40, height: 1, ), ), Expanded( flex: 2, child: Container( height: 40.0, child: Center( child: Text("上拉加载更多", style: TextStyle( color: Colors.grey, fontSize: 13))), ), ), Expanded( flex: 3, child: Divider( height: 1, endIndent: 40, ), ) ]); } else if (mode == LoadStatus.loading) { body = CupertinoActivityIndicator(); } else if (mode == LoadStatus.failed) { body = Text("加载失败!", style: TextStyle(color: Colors.grey, fontSize: 13)); } else { body = Row(children: <Widget>[ Expanded( flex: 3, child: Divider( indent: 40, height: 1, ), ), Expanded( flex: 2, child: Container( height: 40.0, child: Center( child: Text("已经到底啦", style: TextStyle( color: Colors.grey, fontSize: 13))), ), ), Expanded( flex: 3, child: Divider( height: 1, endIndent: 40, ), ) ]); } return Container( height: 50.0, child: Center(child: body), ); }, ), controller: _refreshController, onRefresh: _onRefresh, onLoading: _onLoading, child: GridView.builder( padding: EdgeInsets.all(10.0), shrinkWrap: true, itemCount: dataList.length, gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 2, //纵轴间距 mainAxisSpacing: 10.0, //横轴间距 crossAxisSpacing: 10.0, //子组件宽高长度比例 childAspectRatio: 1.5), itemBuilder: (context, index) { // Map<String, dynamic> entry = dataList[index]; return UserItemWidget( title: '${dataList[index].job}', onTap: () {}, ); }), ), ), ], ); } } class UserItemWidget extends StatefulWidget { String title = ""; int type = 1; VoidCallback onTap; UserItemWidget({ Key key, this.title, this.onTap, }) : super(key: key); @override _UserItemWidgetState createState() => _UserItemWidgetState(); } class _UserItemWidgetState extends State<UserItemWidget> { VoidCallback _onTap; @override void initState() { super.initState(); _onTap = widget.onTap; } @override Widget build(BuildContext context) { return InkWell( onTap: _onTap, child: Stack( children: <Widget>[ Container( padding: EdgeInsets.all(8), decoration: new BoxDecoration( color: Colors.white, border: new Border.all(width: 1.0, color: Colors.grey[300]), borderRadius: new BorderRadius.all(new Radius.circular(2)), ), child: Column( mainAxisSize: MainAxisSize.max, children: <Widget>[ Container( margin: EdgeInsets.only(top: 15, bottom: 10, left: 10), alignment: Alignment.centerLeft, child: Text(widget.title == "" ? "未知" : widget.title, style: TextStyle(fontSize: 18)), ), ], ), ), Positioned( top: 0, right: 0, child: Container( color: getTypeColor(widget.type), padding: EdgeInsets.all(5), child: Center( child: Text(getTypeText(widget.type), style: TextStyle( color: Colors.white, fontSize: 13.0, )), ), )) ], ), ); } String getTypeText(int type) { switch (type) { case 1: return "黄金职业"; case 2: return "夕阳职业"; case 3: return "朝阳职业"; } } Color getTypeColor(int type) { switch (type) { case 1: return Color(0xFFFF00FF); case 2: return Color(0xFFC6C6C6); case 3: return Color(0xFF7FC3FD); } } }
效果:
最后,关注【码上加油站】微信公众号后,有疑惑有问题想加油的小伙伴可以码上加入社群,让我们一起码上加油吧!!!
posted on 2019-09-22 18:11 LoaderMan 阅读(1386) 评论(0) 编辑 收藏 举报