Flutter学习五之网络请求和轮播图的实现
上期讲到了,怎样实现一个下拉刷新和加载更多的列表,数据更新,需要使用到网络请求,在flutter中,怎样实现一个网络请求呢 官方使用的是dart io中的HttpClient发起的请求,但HttpClient本身功能较弱,很多常用功能都不支持。所以这里我们直接使用国内的开源库 dio,dio是一个强大的Dart Http请求库,支持Restful API、FormData、拦截器、请求取消、Cookie管理、文件上传/下载、超时、自定义适配器等功能。
首先我们导入开源库dio,目前的最新版本是 dio: ^3.0.9
, 具体用发可以参考github上的开源项目,文档还是比较详细的。
这里就拿我写的一个首页轮播图的网络请求来介绍一下,首先我们定义一个全局的dio实例,可以在具体代码如下:
// 或者通过传递一个 `options`来创建dio实例BaseOptions options = BaseOptions( baseUrl: "https://www.wanandroid.com/", connectTimeout: 10000, receiveTimeout: 5000,) ;Dio dio=Dio(options);
通过这个实例可以拿到get,post,pull
等方式进行网络请求,这里我们用get请求获取一个轮播图的数据,数据来源于玩Android开放api,通过get方法获取一个Response
对象,在Response对象中我们可以拿到返回值,然后就可以更新我们的UI了,这里更新UI的时候需要调用setState
方法,在setState方法中去更新UI
,代码如下:
getBanner() async { ///轮播图接口请求 Response responseBanner = await dio.get("banner/json"); ///接口调用成功后更新数据需要调用setState()方法 setState(() { ///轮播图实体解析 BannerBaenEntity bannerEntity = BannerBaenEntity().fromJson(jsonDecode(responseBanner.toString())); _banners = bannerEntity.data; }); }
这里要注意的是,接口请求一般都是异步的,所以要声明此方法为async
方法,然后用await
修饰dio.get
方法来获取response
对象。此时不需要我们手动去切换到主线程,这里和kotlin
的协程用法还是蛮像的。
这里我们还需要自定义一个轮播图控件,采用的是官方的控件PageView
,类似Android的ViewPage,但是此控件并不支持循环播放和自动切换功能,轮播图是需要支持循环播放和自动切换功能,并且手动滑动的时候要停止自动切换功能,手指拿开后再开始自动切换。
1.首先来实现一下循环自动播放功能,利用Timer.periodic实现一个定时器,每隔3秒自动切换到下一张图片,同时加一个滑动动画效果,具体代码如下:
_timer = Timer.periodic(Duration(seconds: 3), (t) { _curIndex++; //执行滑动动画 _pageController.animateToPage( _curIndex, duration: Duration(milliseconds: 300), curve: Curves.linear, );
这里要注意一下,如果我们不给PageView.builder设置itemCount的情况下,pageview是长度是无限的,默认是支持无限右边滑动的,所以我们只需要在pageView滑动监听的时候,判断当前滑动位置如果是0的时候,将当前图片位置设置为轮播图数据的长度,即可实现轮播图滑动到左边的时候可以继续滑动的循环效果。同时为来避免第一次创建轮播图的时候,用户手动像左边滑动的情况,我们在创建的时候,需要指定轮播图的索引为数据的N倍。具体代码:
//轮播图初始化设置 @override void initState() { super.initState(); _curIndex = widget._banners.length * 5; //设置轮播图的初始索引位置 _pageController = PageController(initialPage: _curIndex); //初始化轮播图控制器 _initTimer(); } //构造一个pageview组件 PageView.builder( controller: _pageController, //设置pageview控制器 onPageChanged: (index) { //刷新pageview数据 setState(() { _curIndex = index; //重新设置pageview的索引位置 if (index == 0) { _curIndex = length; _changePage(); } }); })
2.我们需要监听item图片的用户手势,当用户手指按下并且滑动时,我们需要停止计时器,手指拿开时开启计时器,经过测试发现,手指按下滑动时,可以监听到,但是手机拿开时监听不到,所以这里暂时只监听手指按下时,停止计时器,并且在此启动计时器。具体代码如下:
//取消计时器 _cancelTimer() { if (_timer != null) { _timer.cancel(); _timer = null; _initTimer();//在此启动计时器,3秒后执行切换 } } GestureDetector( //手指按下并滑动时执行此方法 onPanDown: (details) { _cancelTimer(); }, //手指点击执行的方法,点击轮播图跳转页面 onTap: () { Navigator.of(context).push(MaterialPageRoute(builder: (_) { return WebViewPage(widget._banners[index%length].url); })); }, //设置轮播图item,这里就是一张网络图片加载。 child: Image.network( widget._banners[index % length].imagePath, fit: BoxFit.cover, ), )
更多相关文章
- Android(安卓)自定义view仿IOS开关
- Android如何通过TextView实现超链接的跳转
- 关于安卓活动的生命周期
- Android自定义控件之自定义属性
- Android(安卓)jni编程浅入深出之-- 与原生代码通信
- Android(安卓)ActivityManagerService(AMS)的启动分析
- Android之——任意时刻从子线程切换到主线程的实现(插曲)
- Android(安卓)----SQLiteDate(Cursor接口)
- Android(安卓)sax解析XML数据