写点什么

Flutter 卡片分享功能实现:将你的内容分享给世界

  • 2023-06-28
    浙江
  • 本文字数:2549 字

    阅读完需:约 8 分钟

Flutter卡片分享功能实现:将你的内容分享给世界

前言


在 app 中,在实现分享功能的时候,通常会有一种以卡片形式展示和分享内容的分享方式。这种功能可以将信息以整洁、易读的方式呈现给用户,使他们能够快速了解内容的关键信息,并将其分享给其他人。那么在这篇文章中,就一起来探索下,如何使用 Flutter 来实现这卡片分享功能吧~


源代码:https://www.aliyundrive.com/s/FH7Xc2vyLvC


实现方案

为了卡片的样式的灵活性和可定制性,本文采用对组件进行截图的方式来实现卡片保存分享的功能,选择这个方案还有一点好处就是充分利用了 flutter 跨平台的优势。当然也会有一定的缺点,例如对于性能的考虑,当对复杂的嵌套卡片组件截图时,渲染和图像转换的计算量是需要考虑的,当然也可以选择忽略不计~

创建弹窗 &卡片布局

在生成分享卡片的同时还会有其他的操作选项,例如保存图片、复制链接、浏览器打开等等,所以通常分享卡片的形式为弹窗形式,中间为分享卡片主体,剩余空间为操作项。



操作项组件封装:


class ImageDialog extends StatelessWidget {  const ImageDialog({    Key? key,    required this.items,    ...  }) : super(key: key);  final List<ItemLittleView> items;  ...
@overrideWidget build(BuildContext context) { return Column( mainAxisAlignment: MainAxisAlignment.end, children: [ Container( ... child: Row( children: items .map((e) => itemLittleView( label: e.label, icon: e.icon, onTap: () { Navigator.pop(context); e.onTap?.call(); })) .toList()), ), ], );}
Widget itemLittleView({ required String label, required String icon, Function()? onTap, }) => InkWell( onTap: onTap, child: Container( margin: EdgeInsets.only(right: 10), child: Column( mainAxisAlignment: MainAxisAlignment.end, children: [ Container( //图标 ), Container( //文字 ), ], ), ), ); }}
class ItemLittleView { final String label; final String icon; final Function()? onTap;
ItemLittleView({required this.label, required this.icon, this.onTap});}
复制代码


需要加入新的操作项时,只需要简单的添加一个ItemLittleView即可。


ImageDialog(  items: [    ItemLittleView(      label: "生成图片 ",      icon: "assets/images/icon/ic_down.png",      onTap: () => doSaveImage(),    ),    ...  ],),
复制代码


卡片的布局则根据业务的需求自定义即可,本文也只是一个简单的例子。

渲染并截取组件截图

在 flutter 中可以使用RepaintBoundary将将组件渲染为图像。


  • 第一步:定义全局的 GlobalKey,用于获取卡片布局组件的引用


var repaintKey = GlobalKey();
RepaintBoundary( key: repaintKey, //分享卡片 child: shareImage(),),
复制代码


  • 第二步:使用 RenderRepaintBoundary 的 toImage 方法将其转换为图像


Future<Uint8List> getImageData() async {  BuildContext buildContext = repaintKey.currentContext!;  //用于存储截取的图片数据  var imageBytes;  //通过 buildContext 获取到 RenderRepaintBoundary 对象,表示要截取的组件边界  RenderRepaintBoundary boundary =      buildContext.findRenderObject() as RenderRepaintBoundary;
//这行代码获取设备的像素密度,用于设置截取图片的像素密度 double dpr = ui.window.devicePixelRatio; //将边界对象 boundary 转换为图像,使用指定的像素密度。 ui.Image image = await boundary.toImage(pixelRatio: dpr); // image.width //将图像转换为ByteData数据,指定了数据格式为 PNG 格式。 ByteData? byteData = await image.toByteData(format: ui.ImageByteFormat.png); //将ByteData数据转换为Uint8List 类型的图片数据。 imageBytes = byteData!.buffer.asUint8List(); return imageBytes;}
复制代码


  • 第三步:获取权限 &保存截图


//获取权限_requestPermission() async {    Map<Permission, PermissionStatus> statuses = await [      Permission.storage,    ].request();
final info = statuses[Permission.storage].toString();}
Future<String> saveImage(Uint8List imageByte) async { //将回调拿到的Uint8List格式的图片转换为File格式 //获取临时目录 var tempDir = await getTemporaryDirectory(); //生成file文件格式 var file = await File('${tempDir.path}/image_${DateTime.now().millisecond}.png') .create(); //转成file文件 file.writeAsBytesSync(imageByte); print("${file.path}"); String path = file.path; return path;}
//最后通过image_gallery_saver来保存图片/// 执行存储图片到本地相册 void doSaveImage() async { await _requestPermission(); Uint8List data = await getImageData(); String path = await saveImage(data); final result = await ImageGallerySaver.saveFile(path); showDialog( context: context, builder: (_) { return AlertDialog( title: Text("保存成功!"), ); }); }
复制代码


到这里,分享卡片的功能就实现啦~

总结

在本文中,我们探索了使用 Flutter 实现卡片分享功能的过程。在开发 app 时,卡片分享功能可以为用户提供更好的交互和共享体验,我猜大家在开发的过程中也会有很大的概率碰上这样的需求。通过设计精美的卡片样式,可以帮助更快速的推广 APP。

关于我

Hello,我是 Taxze,如果您觉得文章对您有价值,希望您能给我的文章点个❤️,有问题需要联系我的话:我在这里 。如果您觉得文章还差了那么点东西,也请通过关注督促我写出更好的文章~万一哪天我进步了呢?😝

发布于: 2023-06-28阅读数: 31
用户头像

他日若遂凌云志 敢笑黄巢不丈夫 2020-10-15 加入

曾许少年凌云志,誓做人间第一流. 一起加入Flutter技术交流群532403442 有好多好多滴学习资料喔~ 小T目前主攻Android与Flutter, 通常会搞搞人工智能、SpringBoot 、Mybatiys等.

评论

发布
暂无评论
Flutter卡片分享功能实现:将你的内容分享给世界_flutter_编程的平行世界_InfoQ写作社区