Flutter小课堂

编程入门 行业动态 更新时间:2024-10-12 16:29:10

Flutter小<a href=https://www.elefans.com/category/jswz/34/1769265.html style=课堂"/>

Flutter小课堂

前言

图片是一个我们又爱又恨的东西,它是万美之本,也是万恶之源
为阐述清楚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创建
Imagework( 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,);//最终组件
复制代码

本文到此接近尾声了,如果想快速尝鲜Flutter,《Flutter七日》会是你的必备佳品;如果想细细探究它,那就跟随我的脚步,完成一次Flutter之旅。
另外本人有一个Flutter微信交流群,欢迎小伙伴加入,共同探讨Flutter的问题,本人微信号:zdl1994328,期待与你的交流与切磋。

更多推荐

Flutter小课堂

本文发布于:2024-02-10 22:39:05,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1677714.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:课堂   Flutter

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!