一、Flutter图片按钮
在Flutter中,图片按钮是一种非常常见的视觉组件。通过使用InkWell或GestureDetector包裹图片,就可以实现点击事件。同时,我们可以通过设置不同的属性来自定义按钮的样式。
GestureDetector( onTap: () { // 点击事件 }, child: Image.asset( 'assets/images/button.png', width: 120, height: 60, fit: BoxFit.cover, alignment: Alignment.center, ), )
二、Flutter图片加载失败显示默认图片
在网络请求或本地图片加载时,如果图片不存在或加载失败,我们可以设置一张默认图片来代替。
Image.network( 'http://www.example.com/404.jpg', width: 200, height: 200, fit: BoxFit.cover, alignment: Alignment.center, errorBuilder: (BuildContext context, Object exception, StackTrace? stackTrace) { return Image.asset('assets/images/default.png'); }, )
三、Flutter图片加载失败
在网络请求的图片加载时,如果网络不稳定或服务器宕机等异常情况,图片可能会加载失败。我们可以通过设置errorBuilder属性来自定义加载失败时的样式。
Image.network( 'http://www.example.com/image.jpg', width: 200, height: 200, fit: BoxFit.cover, alignment: Alignment.center, errorBuilder: (BuildContext context, Object exception, StackTrace? stackTrace) { return Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( Icons.broken_image, size: 60, color: Colors.grey[400], ), SizedBox(height: 10), Text( '图片加载失败', style: TextStyle( color: Colors.grey[400], fontSize: 16, ), ), ], ); }, )
四、Flutter图片无法铺满
在设置图片长宽时,如果图片的长宽比与容器不一致,那么图片可能无法完全铺满容器。我们可以通过调整fit属性来解决这个问题。
Image.network( 'http://www.example.com/image.jpg', width: double.infinity, // 设置宽度为容器宽度 height: 200, fit: BoxFit.fill, // 填充整个容器 alignment: Alignment.center, )
五、Flutter图片拉伸比例
拉伸比例指在填充容器时,图片长宽比是否改变。fit属性中的scaleDown和none值表示不改变比例,而cover和fill值则表示改变比例。
Image.network( 'http://www.example.com/image.jpg', width: 200, height: 200, fit: BoxFit.cover, alignment: Alignment.center, )
六、Flutter图片变圆角
我们可以通过使用ClipRRect组件将图片切成圆角。
ClipRRect( borderRadius: BorderRadius.circular(10), child: Image.network( 'http://www.example.com/image.jpg', width: 200, height: 200, fit: BoxFit.cover, alignment: Alignment.center, ), )
七、Flutter图片列表
在开发中,我们经常需要展示多张图片,这时我们可以使用ListView或GridView等滚动组件来实现图片列表。
GridView.builder( gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 3, crossAxisSpacing: 10, mainAxisSpacing: 10, childAspectRatio: 1, ), itemBuilder: (BuildContext context, int index) { return Image.network( 'http://www.example.com/image_$index.jpg', fit: BoxFit.cover, alignment: Alignment.center, ); }, )
八、Flutter图片上传控件
在Flutter中实现图片上传控件比较简单。我们可以使用Flutter自带的ImagePicker组件来控制相册或相机。
File? _imageFile; Future_getImageFromGallery() async { final pickedFile = await ImagePicker().getImage(source: ImageSource.gallery); setState(() { _imageFile = File(pickedFile!.path); }); } Future _getImageFromCamera() async { final pickedFile = await ImagePicker().getImage(source: ImageSource.camera); setState(() { _imageFile = File(pickedFile!.path); }); } Column( children: [ ElevatedButton( onPressed: _getImageFromGallery, child: Text('从相册选择'), ), ElevatedButton( onPressed: _getImageFromCamera, child: Text('拍照上传'), ), if (_imageFile != null) Image.file(_imageFile!), ], )
九、Flutter图片列表内存溢出
在展示大量图片时,由于内存限制,可能会发生内存溢出的情况。我们可以使用Flutter自带的CachedNetworkImage组件来避免内存溢出问题。
CachedNetworkImage( imageUrl: 'http://www.example.com/image.jpg', fit: BoxFit.cover, alignment: Alignment.center, placeholder: (context, url) => CircularProgressIndicator(), errorWidget: (context, url, error) => Icon(Icons.error), )
十、Flutter图片视频编辑选取
在视频编辑时,我们可以使用Flutter自带的video_player和flutter_ffmpeg组件来选择视频并提取封面。
Future_pickVideoAndThumbnail() async { final pickedFile = await ImagePicker().getVideo(source: ImageSource.gallery); if (pickedFile != null) { final thumbnailPath = await _extractThumbnail(pickedFile.path); setState(() { _videoFile = File(pickedFile.path); _thumbnailFile = File(thumbnailPath); }); } } Future _extractThumbnail(String videoPath) async { final thumbnailPath = '${(await getTemporaryDirectory()).path}/thumbnail.jpg'; await FlutterFFmpeg().execute( '-i $videoPath -ss 00:00:01.000 -vframes 1 $thumbnailPath', ); return thumbnailPath; } Column( children: [ ElevatedButton( onPressed: _pickVideoAndThumbnail, child: Text('选择视频'), ), if (_thumbnailFile != null) Image.file(_thumbnailFile!), if (_videoFile != null) Text(_videoFile!.path), ], )