Flutter圈子Android开发Android开发经验谈

Flutter实现网络请求

2019-03-27  本文已影响34人  元创造力
            {
                "movieId":"135808",
                "movieName":"新喜剧之王",
                "pic_url":"http:\/\/img5.mtime.cn\/mt\/2019\/02\/02\/113216.53857992_182X243X4.jpg"
            },
    
TodayFilmBean类

        //TodayFilmBean.g.dart将在我们运行生成命令之后自动生成
        part 'TodayFilmBean.g.dart';
        
        //这个标注是告诉生成器,这个类是要生成的Model类
        @JsonSerializable()
        class TodayFilmBean{
          String movieId;
          String movieName;
          String pic_url;
          
           //构造函数
          TodayFilmBean(this.movieId,this.movieName,this.pic_url);
          
          //json转换为bean对象
          factory TodayFilmBean.fromJson(Map<String,dynamic> json) => _$todayFilmBeanFromJson(json);
          
          //bean对象转换为json
          Map<String,dynamic> toJson() => _$todayFilmBeanToJson(this);
        }
生成的TodayFilmBean.g.dart类是这样的

        part of 'TodayFilmBean.dart';
        
        //json转换为bean对象
        TodayFilmBean _$todayFilmBeanFromJson(Map<String,dynamic> json) {
          return TodayFilmBean(json['movieId'] as String,json['movieName'] as String,
              json['pic_url'] as String);
        }
        
        //bean对象转换为json
        Map<String,dynamic> _$todayFilmBeanToJson(TodayFilmBean instance) =>
            <String,dynamic> {
              'movieId': instance.movieId,
              'movieName': instance.movieName,
              'pic_url':instance.pic_url
        };
有两种运行代码生成器的方法:
1.一次性生成
  通过在我们的项目根目录下运行flutter packages pub run build_runner build,我们可以在需要时为我们的model生成json序列化代码。这触发了一次性构建,它通过我们的源文件,挑选相关的并为它们生成必要的序列化代码。

虽然这非常方便,但如果我们不需要每次在model类中进行更改时都要手动运行构建命令的话会更好。

2.持续生成
使用_watcher_可以使我们的源代码生成的过程更加方便。它会监视我们项目中文件的变化,并且在需要时自动构建必要的文件。我们可以通过flutter packages pub run build_runner watch 在项目根目录下运行来启动_watcher_。

只需启动一次观察器,然后并让它在后台运行,这是安全的。

执行序列化只需执行
    
    //把json数据转化为了bean对象
    var filmBean = TodayFilmBean.fromJson(json); 

上面是初始化网络请求,在请求到数据后,调用setState刷新UI

      //State的build方法,调用setState方法后,此方法就会被触发
      //用来刷新UI
      @override
      Widget build(BuildContext context) {
    
        return Scaffold(
          appBar: AppBar(
    
            title: Text(widget.title),
          ),
          
          //如果mData.length == 0,展示一个loading框,否则展示数据
          body: mData.length == 0
              ? new Center(child: new CircularProgressIndicator()):
              //创建GridView对象
              new GridView.builder(
    
              gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                  crossAxisCount: 3, //每行2个
                  mainAxisSpacing: 1.0, //主轴(竖直)方向间距
                  crossAxisSpacing: 1.0, //纵轴(水平)方向间距
                  childAspectRatio: 0.7 //纵轴缩放比例
              ),
              //item数量
              itemCount:mData.length,

              //创建每个item
              itemBuilder: (BuildContext context,int index) {
                return _getWidget(index);
              }),
        );
      }

  _getWidget(int index) {
    //添加要展示的item内容
      return new Column(
        children: <Widget>[
          new Expanded(child: new CardItem(color: Colors.black12,child: _getChild(index)),flex: 8,),
          //显示网络请求文本
          new Expanded(child: new Text(mData[index].movieName,
            textAlign: TextAlign.end,
            maxLines: 1,
          ),
              flex:1)
        ]);
  }

  _getChild(int i) {
    return new Padding(padding: new EdgeInsets.all(1.0),
        //显示网络请求的图片
        child: new Image(image: NetworkImage(mData[i].pic_url)));
  }

一个自定义的CardItem

class CardItem extends StatelessWidget{
  final Widget child;
  final EdgeInsets margin;
  final Color color;
  final RoundedRectangleBorder shape;
  final double elevation;

  CardItem({@required this.color,this.child,this.elevation = 5.0,this.shape,this.margin});

  @override
  Widget build(BuildContext context) {
    EdgeInsets margin = this.margin;
    RoundedRectangleBorder shape = this.shape;
    Color color = this.color;
    margin ??= EdgeInsets.only(left: 2.0,top: 2.0,right: 2.0,bottom: 2.0);
    shape ??= new RoundedRectangleBorder(borderRadius: new BorderRadius.all(Radius.circular(4.0)));
    color ??= new Color(0xffeeff);
    return new Card(elevation: elevation,shape: shape,color: color,margin: margin,child: child,);
  }
}

好了,Flutter网络请求并且展示数据就这样实现的。
最后附上demo地址:https://github.com/xinhuashi/flutter_http_demo.git

上一篇下一篇

猜你喜欢

热点阅读