3.Flutter学习之Image组件

2022-02-09 15:55:55 浏览数 (1)

学习自: Dart Flutter教程_Dart Flutter入门实战视频教程-2019年新出. Flutter之path_provider

Image属性

代码语言:javascript复制
void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Image组件的学习',
      home: Scaffold(
        appBar: AppBar(title: Text('Image组件的学习')),
        body: HomeCotent(),
      ),
    );
  }
}

class HomeCotent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        height: 300,
        width: 300,
        decoration: BoxDecoration(color: Colors.cyanAccent),
        child: Image.network(
            'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1428199975,1303736617&fm=26&gp=0.jpg',
          alignment: Alignment.center,    //图片相对于父widget的对齐方式
          color: Colors.blue,             //给图片设置颜色,
          colorBlendMode: BlendMode.screen, //将图片与color相融合

          /*
          * fit:控制图片拉伸和挤压,根据父Widget来的。
          * fill:全图显示,图片会拉伸,充满父容器;
          * contain:全图显示,显示原比例;
          * cover:显示可能拉伸,可能裁切,充满(图片要充满整个容器,还不变形)
          * fitWidth:宽度充满(横向充满),显示可能拉伸,可能裁切
          * fitHeight:高度充满(竖向充满),显示可能拉伸,可能裁切
          *scaleDown:效果与contain类似,此属性不允许显示超过原图片大小,可小不可大
          *  */
          fit: BoxFit.cover,
          repeat:ImageRepeat.repeatX ,   //平铺效果,类似于html的平铺
          ///width height 这两个属性一般结合ClipOval可以看出效果,单个使用无意义。
        ),
      ),
    );
  }
}

这里展示一下Image组件repeat平铺的效果 未使用平铺效果: 代码如下

代码语言:javascript复制
void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Image组件的学习',
      home: Scaffold(
        appBar: AppBar(title: Text('Image组件的学习')),
        body: HomeCotent(),
      ),
    );
  }
}

class HomeCotent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        height: 300,
        width: 300,
        decoration: BoxDecoration(color: Colors.cyanAccent),
        child: Image.network(
            'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1428199975,1303736617&fm=26&gp=0.jpg',
          alignment: Alignment.center,    //图片相对于父widget的对齐方式
        ),
      ),
    );
  }

使用平铺后,效果如图所示:

加载网络图片

代码语言:javascript复制
Image.network(
            'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1428199975,1303736617&fm=26&gp=0.jpg');

加载本地图片

1.创建对应分辨率的文件夹,并且将不同分辨率的图片放入不同分辨率的文件夹下,images默认1.0x
2. 在pubspec.yaml中声明

注意:配置时,注意文件名一定要与图片文件一致。

3.使用Image引用
代码语言:javascript复制
Image.asset('images/video_icon.png')
或者
Image(
    image:AssetImage(‘images/video_icon.png’);
)

注意:如果一切配置正常,我们使用热更新去更新程序,可能会遇到图片加载不出来,这时需要重新运行。

加载本地图片

加载本地完整路径图片
代码语言:javascript复制
Image.file(File('/sdcard/Download/timg.jpg'))
  • 此处并未实现所谓的加载完整路径,log报错``
代码语言:javascript复制
I/flutter ( 4794): The following FileSystemException was thrown resolving an image codec:
I/flutter ( 4794): Cannot open file, path = '/storage/emulated/0/Download/timg.jpg' (OS Error: Permission denied, errno
I/flutter ( 4794): = 13)
I/flutter ( 4794): When the exception was thrown, this was the stack:
I/flutter ( 4794): #0      _File.open.<anonymous closure> (dart:io/file_impl.dart:364:9)
I/flutter ( 4794): (elided 13 frames from package dart:async)
I/flutter ( 4794): ...
I/flutter ( 4794): Path: /storage/emulated/0/Download/timg.jpg
I/flutter ( 4794): 
加载相对路径图片

pubspec.yaml中添加path_provider.依赖

代码语言:javascript复制
/**
 * 1.在pubspec.yaml文件中声明依赖 PathProvider 插件
 *   dependencies:
 *   path_provider: ^0.5.0 1
 * 2.在pubspec.yaml顶部的动作功能区中点击“Packages Get”
 *
 * getExternalStorageDirectory,在iOS上,抛出异常,在Android上,这是getExternalStorageDirectory的返回值
 * getTemporaryDirectory,在iOS上,对应NSTemporaryDirectory()返回的值,在Android上,这是getCacheDir的返回值。
 * getApplicationDocumentsDirectory,在iOS上,这对应NSDocumentsDirectory,在Android上,这是AppData目录
 */
代码语言:javascript复制
body: ListView(
          children: <Widget>[
            MyRowText("获取sd卡的根路径", ()async{
              String sDCardDir = (await getExternalStorageDirectory()).path;
              debugPrint(sDCardDir);
            }),
            MyRowText("获取临时目录的路径", ()async{
              String sTempDir = (await getTemporaryDirectory()).path;
              debugPrint(sTempDir);
            }),
            MyRowText("获取文档目录的路径", ()async{
              String sDocumentDir = (await getApplicationDocumentsDirectory()).path;
              debugPrint(sDocumentDir);
            }),
          ],
        ),

如何设置placeholder(占位图片)?

为了设置PlaceHolder我们需要借助FadeInImage

代码语言:javascript复制
/**
* 	1.在pubspec.yaml文件中声明依赖transparent_image插件
* 	2.在pubspec.yaml顶部的动作功能区中点击“Packages Get”
*/

应用如下:
import 'package:flutter/material.dart';
import 'package:transparent_image/transparent_image.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Image组件'),
        ),
        body: HomeConter(),
      ),
    );
  }

}

class HomeConter extends StatelessWidget{
  String path='http://dl.ppt123.net/pptbj/201603/2016030410190920.jpg';
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Center(
      child: Container(
        child: FadeInImage.memoryNetwork(
            placeholder: kTransparentImage,//指定图片未加载时的默认模板,kTransparentImage是一个空白的Uint8List
            image: path,
        )
      ),
    );
  }
}

如何设置图片缓存

在Flutter中使用图片缓存,需要借助于cached_network_image插件。从网络加载的图片缓存到本地。 添加依赖如上。

代码语言:javascript复制
  child: CachedNetworkImage(
          imageUrl: path, //图片的地址
          placeholder: (context,url)=>CircularProgressIndicator(),  //加载目标[imageUrl]时显示的小部件。即占位图片
          errorWidget: (context,url,error)=>Icon(Icons.error),//加载目标[imageUrl]失败时显示的小部件。
        ),

小技巧之圆形图片

第一种实现方法
代码语言:javascript复制
void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Image组件的学习',
      home: Scaffold(
        appBar: AppBar(title: Text('Image组件的学习')),
        body: HomeCotent(),
      ),
    );
  }
}

class HomeCotent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        height: 300,
        width: 300,
        decoration: BoxDecoration(
            color: Colors.cyanAccent,
          borderRadius: BorderRadius.circular(150),
          //其效果等价于上一章节中的 BorderRadius.all( Radius.circular(150)),圆角设置为宽高的一半则为圆
          image:  DecorationImage(
            fit: BoxFit.cover,
            image: NetworkImage('http://c.hiphotos.baidu.com/zhidaohttps://img.yuanmabao.com/zijie/pic/item/d009b3de9c82d1587e249850820a19d8bd3e42a9.jpg') 
            //使用网络去加载图片,等价于Image.network();
          ),
        ),
      ),
    );
  }
}

效果如下:

第二种实现方法

第二种实现方法时采用,一个ClipOval

代码语言:javascript复制
void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Image组件的学习',
      home: Scaffold(
        appBar: AppBar(title: Text('Image组件的学习')),
        body: HomeCotent(),
      ),
    );
  }
}

class HomeCotent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: ClipOval(
        child: Image.network('http://c.hiphotos.baidu.com/zhidaohttps://img.yuanmabao.com/zijie/pic/item/d009b3de9c82d1587e249850820a19d8bd3e42a9.jpg'),
      ),
    );
  }
}

效果如下:

为什么这里的图片不是圆形而是椭圆形的? 其实这个是我们图片的问题,因为我选择的这个图片时长方形的。所以呈现椭圆。如何你选择的照片正好是正方形,则不需要进行一下操作。

那么我们应该如何修改呢?很简单只要给Image设置宽高一致的数值,以及剪裁方式即可。

代码语言:javascript复制
void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Image组件的学习',
      home: Scaffold(
        appBar: AppBar(title: Text('Image组件的学习')),
        body: HomeCotent(),
      ),
    );
  }
}

class HomeCotent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: ClipOval(
        child: Image.network(
          'http://c.hiphotos.baidu.com/zhidaohttps://img.yuanmabao.com/zijie/pic/item/d009b3de9c82d1587e249850820a19d8bd3e42a9.jpg',
          width: 300,
          height: 300,
          fit: BoxFit.cover,
        ),
      ),
    );
  }
}

效果如图所示:

0 人点赞