首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Flutter小课堂-Image篇

Flutter小课堂-Image篇

作者头像
张风捷特烈
发布2020-04-30 15:27:53
4950
发布2020-04-30 15:27:53
举报
前言

图片是一个我们又爱又恨的东西,它是万美之本,也是万恶之源 为阐述清楚Image的使用,专开本文,希望通过本文,你可以学到一个很有用的方法 另外通过最后布局海贼王的悬赏令,基本实现可改头像,名字,悬赏的效果,可缩放


1.Image的简单认识

1.1:Image的属性

首先Image作为组件存在于widgets/image.dart,dart.ui里也有个Image类,别导错了 其次,Image作为一个有状态的组件,继承自StatefulWidget ,所有属性如下:

class Image extends StatefulWidget {
  const Image({
    Key key,
    @required this.image,
    this.semanticLabel,//语义标签
    this.excludeFromSemantics = false,
    this.width,//宽
    this.height,/高
    this.color,//颜色
    this.colorBlendMode,//颜色混合模式
    this.fit,//图片适应模式
    this.alignment = Alignment.center,//对齐
    this.repeat = ImageRepeat.noRepeat,//重复
    this.centerSlice,
    this.matchTextDirection = false,
    this.gaplessPlayback = false,
    this.filterQuality = FilterQuality.low,//滤镜质量
  }) : assert(image != null),
       assert(alignment != null),
       assert(repeat != null),
       assert(filterQuality != null),
       assert(matchTextDirection != null),
       super(key: key);

  final ImageProvider image;
  final double width;
  final Color color;
  final BlendMode colorBlendMode;
  final BoxFit fit;
  final AlignmentGeometry alignment;
  final ImageRepeat repeat;
  final Rect centerSlice;
  final bool matchTextDirection;
  final bool gaplessPlayback;
  final String semanticLabel;
  final bool excludeFromSemantics;

1.2.Image对象的创建

根据不同需求,一共有五种创建Image组件对象的方法

const Image({Key key,@required this.image,//通过ImageProvider创建
Image.network( String src, {//通过网络资源创建
Image.file(File file, { //通过文件创建
Image.asset(String name, //通过资源文件创建
Image.memory(Uint8List bytes, //通过内存创建

1.3:资源图片的访问

Image.asset中有一大段注释介绍如何flutter中使用资源图片

var img = Image.asset(
  'images/icon_head.png',
  width: 50,
  height: 50,
);

1.4:Image的状态

Image是一个有状态的组件,这点确实出乎我意料,我们看看他的状态有哪些

class _ImageState extends State<Image> {
  ImageStream _imageStream;
  ImageInfo _imageInfo;
  bool _isListeningToStream = false;
  bool _invertColors;

2.Image的属性表现
2.1:Image的宽高

将3:2的图片放在一个200*200的容器里,表现效果如下

var img = Image.asset(
  'images/ls.jpg',
  width: 100,
  height: 100,
);

var imgContainer=Container(
  width: 200,
  height: 200,
  color: Colors.cyanAccent,
  child: img,
);

其中可以看出: 1.默认情况下图像会显示完全 2.这里Container定义的长宽,可见Image的长宽是无效的 3.Image组件占据的布局空间并非仅是图片!


2.2: 图片的适应模式:fit

为了方便对比,这里写了一个方法批量生成,可以看出各种模式的特性。

var fitMode = [BoxFit.none, BoxFit.contain, BoxFit.cover,
  BoxFit.fill, BoxFit.fitHeight, BoxFit.fitWidth, BoxFit.scaleDown
];

//循环生成Image控件
form() {
  var imgLi = <Widget>[];
  fitMode.forEach((fit) {
    var img = Container(
        margin: EdgeInsets.all(10),
        width: 150,
        height: 60,
        color: randomRGB(),
        child: Image(
          image: AssetImage("images/ls.jpg"),
          fit: fit,
        ));

    imgLi.add(Column(
      children: <Widget>[img, Text(fit.toString())],
    ));
  });
  return imgLi;
}

var imgBox = Wrap(
  children: form(),
);

Color randomRGB() {
  Random random = new Random();
  int r = 30 + random.nextInt(200);
  int g = 30 + random.nextInt(200);
  int b = 30 + random.nextInt(200);
  return Color.fromARGB(255, r, g, b);
}
复制代码
  • 宽高比2:3测试结果:
  • 宽高比3:2测试结果:
  • 图片小于容器尺寸下的测试结果

根据图片看一下,应该不言而喻了。


2.3:颜色以及混合模式:color,colorBlendMode

同样,也是批量测试一下,一图胜千言,而且感觉高大上一点 这里使用蓝色和头像进行叠合,效果如下:

//混合模式数组
var colorBlendMode = [
  BlendMode.clear,BlendMode.src,BlendMode.dst,
  BlendMode.srcOver,BlendMode.dstOver,BlendMode.srcIn,
  BlendMode.dstIn,BlendMode.srcOut,BlendMode.dstOut,
  BlendMode.srcATop,BlendMode.dstATop,BlendMode.xor,
  BlendMode.plus, BlendMode.modulate,BlendMode.screen,
  BlendMode.overlay,BlendMode.darken,BlendMode.lighten,
  BlendMode.colorDodge,BlendMode.colorBurn,BlendMode.hardLight,
  BlendMode.softLight,BlendMode.difference,BlendMode.exclusion,
  BlendMode.multiply,BlendMode.hue,BlendMode.saturation,
  BlendMode.color, BlendMode.luminosity,
];

//循环生成Image控件
formImgsColorBlendMode() {
  var imgLi = <Widget>[];
  colorBlendMode.forEach((mode) {
    var img = Container(
        margin: EdgeInsets.all(5),
        width:60,
        height: 60,
        child: Image(
          image: AssetImage("images/icon_head.png"),
          color: Colors.blue,
          colorBlendMode: mode,
        ));
    imgLi.add(Column(children: <Widget>[
      img,
      Text(mode.toString().split(".")[1])
    ]));
  });
  return imgLi;
}

var imageColorMode = Wrap(
  children: formImgsColorBlendMode(),
);
复制代码

如果以后有什么需要类比的模式,枚举什么的,都可以通过这种方式批量生成,效果又好又省事。


4. 对齐属性:alignment

有9个静态常量,分别是九个方位,另外也可以通过Alignment的构造方法来进行对齐偏移

var alignments = [
  Alignment.center,  Alignment.centerLeft, Alignment.centerRight,
  Alignment.topCenter,Alignment.topLeft, Alignment.topRight,
  Alignment.bottomCenter,Alignment.bottomLeft,Alignment.bottomRight,
Alignment(0.01,0.01),Alignment(0.5,0.5)
];

//循环生成Image控件
formImgAlignments() {
  var imgLi = <Widget>[];
  alignments.forEach((align) {
    var img = Container( 
        margin: EdgeInsets.all(7),
        width: 150,
        height: 60,
        color: randomRGB(),
        child: Image(
          image: AssetImage("images/wy_300x200_little.jpg"),
          alignment: align,
        ));

    imgLi.add(Column(
      children: <Widget>[img, Text(e.toString())],
    ));
  });
  return imgLi;
}

var imageAlignments = Wrap(
  children: formImgAlignments(),
);

复制代码

2.5.重复模式:repeat

一目了然,不多说

var repeats = [
  ImageRepeat.repeatY,  ImageRepeat.repeatX,
  ImageRepeat.noRepeat,ImageRepeat.repeat
];
//循环生成Image控件
formImgRepeat() {
  var imgLi = <Widget>[];
  repeats.forEach((repeat) {
    var img = Container(
        margin: EdgeInsets.all(7),
        width: 150,
        height: 90,
        color: randomRGB(),
        child: Image(
          image: AssetImage("images/wy_300x200_little.jpg"),
          repeat: repeat,
        ));

    imgLi.add(Column(
      children: <Widget>[img, Text(repeat.toString())],
    ));
  });
  return imgLi;
}

var imageRepeats = Wrap(
  children: formImgRepeat(),
);
复制代码

1.5:缩放质量:filterQuality

源码上说: 使用FilterQuality.low在缩放图片时使用二次线性插值算法 FilterQuality.none 在缩放图片时使用临近算法 FilterQuality.hight 是最好的,也是最慢的,通常是三次插值或更好 FilterQuality.medium 的速度介于low和hight之间,通常是二次线性插值和锥体参数预滤波(mipmaps)的结合。 讲得挺高大上,但用起来感觉也就那回事,hight确实要比none感觉好

var qualitys = [
  FilterQuality.none,FilterQuality.high, 
  FilterQuality.medium, FilterQuality.low,

];
//循环生成Image控件
formImgQualitys() {
  var imgLi = <Widget>[];
  qualitys.forEach((q) {
    var img = Container(
        margin: EdgeInsets.all(7),
        width:110.0*3/2,
        height: 110,
        color: randomRGB(),
        child: Image(
          image: AssetImage("images/wy_300x200.jpg"),
          filterQuality: q,
        ));

    imgLi.add(Column(
      children: <Widget>[img, Text(q.toString())],
    ));
  });
  return imgLi;
}

var imageQualitys = Wrap(
  children: formImgQualitys(),
);
复制代码

3.每日一布局:海贼王悬赏令

暂时没有抽成自定义组件。这里不分析了,有兴趣的小伙伴自己看看,也可以自定义个组件玩玩。

    const double viewRate = 0.663306; //视图宽高比
    const double imgRate = 1.234411;//图片宽高比
    var width =300.0;
    double height = width/viewRate;

    var textWanted= Text('WANTED',
       style: TextStyle(
           fontWeight: FontWeight.bold,
           letterSpacing:width/30,
           fontSize: width/6),
    );

    var name =Text('NA MI',
      style: TextStyle(
          fontWeight: FontWeight.bold,
          fontSize: width/9),
    );

    var price= Text('16,000,000',
      style: TextStyle(
          letterSpacing:width/45,
          fontWeight: FontWeight.bold,
          fontSize: width/10),
    );
    var img =Container(
      decoration: BoxDecoration(
        border: Border.all(color: Colors.black,width: width/100),
      ),
      width: width,
      height: width/imgRate,
      child: Image.asset('images/娜美.jpg',fit: BoxFit.cover,),
    );

    var bottom =Stack(
      children: <Widget>[
        Image.asset('images/bottom.jpg',fit: BoxFit.fitWidth,),
        Container(child: name,alignment: Alignment.topCenter,padding: EdgeInsets.only(top: 6*width/100),),
        Container(child: price,alignment: Alignment.topCenter,padding: EdgeInsets.only(top: 17*width/100),)
      ],);
    var wanted = Container(
      width: width,
      height: height,
      color: Color(0xffded0b5),
      child: Column(
        mainAxisAlignment: MainAxisAlignment.start,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: <Widget>[textWanted,Padding(padding:
        EdgeInsets.fromLTRB(5*width/100,0,5*width/100,5*width/100),child: img,),
          bottom
        ],),
    );
    var result=Card(child:wanted ,elevation: 5*width/100,);//最终组件
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019年07月09日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 1.Image的简单认识
    • 1.1:Image的属性
      • 1.2.Image对象的创建
        • 1.3:资源图片的访问
          • 1.4:Image的状态
          • 2.Image的属性表现
            • 2.1:Image的宽高
              • 2.2: 图片的适应模式:fit
                • 2.3:颜色以及混合模式:color,colorBlendMode
                  • 4. 对齐属性:alignment
                    • 2.5.重复模式:repeat
                      • 1.5:缩放质量:filterQuality
                      • 3.每日一布局:海贼王悬赏令
                      相关产品与服务
                      容器服务
                      腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
                      领券
                      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档