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,
            ),
          )

你可能感兴趣的:(flutter,android,dart,android,ios,flutter,android,studio,swift)