Flutter   发布时间:2022-05-03  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了Flutter实战一Flutter聊天应用(九)大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

在这文章中,我们将允许用户在聊天消息中发送图像,从设备检索图像文件,并将文本和图像数据存储在Google云端存储Bucket中。由于我们使用Firebase云储存,应用程序将变得更加健壮和可扩展。它能够在上传和下载期间处理网络中断,安全地存储数据,并在用户群扩展时保持相同的性能

要将数据(如文本和照片)从移动设备上传到云端,我们需要使用firebase_storage插件。在@H_549_7@main.dart文件中,确保导入相应的包。

@H_404_15@import 'package:firebase_storage/firebase_storage.dart';

要访问存储在移动设备上的数据并在Flutter应用程序中使用它,我们需要Flutter的平台服务API和image_picker插件。在@H_549_7@main.dart文件中,导入image_picker包。另外还要导入dart:mathdart:io库,用于在设备上生成随机文件名和处理文件操作。

@H_404_15@import 'package:image_picker/image_picker.dart';
@H_404_15@import 'dart:math';
@H_404_15@import 'dart:io';

此时,@R_382_9616@程序可以让用户发送和接收消息。现在,我们将在用户界面中添加一个按钮来撰写消息,使用户可以从应用访问设备的相机。然后我们将给UI处理二进制数据的能力。

需要注意的是,如果我们正在iOS设备上进行测试,那么需要添加一个设置,让图像选择器插件访问相机和设备上存储的图像。要启用访问,需要将以下条目添加到应用程序的Info.plist文件的主字典中。

<Dict>
         <key>NSCameraUsageDescription</key>
         <String>Share images with other chat users</String>
         <key>NSPhotoLibraryUsageDescription</key>
         <String>Share images with other chat users</String>
 ...
 </Dict>

<String>元素可以包含任何文本值。我们还可以在xcode中添加这些设置,使用Privacy - Camera Usage DescriptionPrivacy - Photo Library Usage Description属性的新行。

用户需要一种访问存储在设备上的图像的方法,我们将在用于撰写聊天消息的UI旁边创建一个按钮。应用程序UI的这一部分由ChatScreenState中的私有方法_buildTextComposer()定义。添加一个IconButton小部件,用于访问相机和存储的图像到_buildTextComposer方法。输入字段和发送按钮的现有Row控件应该是父级,将IconButton控件包装在新的Container控件中,Container控件让我们能自定义按钮的边距间距,使其在输入字段旁边更好看。

class ChatScreenState extends State<ChatScreen> {
  //@H_404_15@...
  Widget _buildTextComposer() {
    @H_404_15@return new IconTheme(
      data: new IconThemeData(color: Theme.of(context).accentColor),child: new Container(
        margin: const EdgeInsets.symmetric(horizontal: 8.0),child: new Row(
          children: <Widget> [
            new Container(
              margin: new EdgeInsets.symmetric(horizontal: 4.0),child: new IconButton(
                icon: new Icon(Icons.photo_camera),onPressed: (){}
              ),),new Flexible(
              //@H_404_15@...
            ),new Container(
              //@H_404_15@...
            )
          ]
        )
      )
    );
  }
  //@H_404_15@...
}

icon属性中,使用Icons.photo_camera常量创建一个新的Icon实例,此常量可以让控件使用Flutter素材图标库提供的“相机”图标。

Flutter实战一Flutter聊天应用(九)

现在修改相机按钮的onPressed回调。我们需要引用Google云端存储Bucket,并在用户选择之后立即开始上传图像。对于按钮的onPressed属性,我们将调用async函数并将其与几个await表达式组合,以特定顺序执行与图像相关的任务。

class ChatScreenState extends State<ChatScreen> {
  //@H_404_15@...
  Widget _buildTextComposer() {
        //@H_404_15@...
              child: new IconButton(
                icon: new Icon(Icons.photo_camera),onPressed: () async {
                  await _ensureLoggedIn();
                  File imageFile = await ImagePicker.pickImage();
                }
              ),//@H_404_15@...
  }
  //@H_404_15@...
}

在允许用户选择、上传和发送图像之前,确保通过执行私有_ensureLoggedIn()方法登录。然后等待用户选择一个图像,并从pickImage()方法获取一个名为imageFile的新的File对象。此方法由之前导入的Flutter Image Picker插件提供。它不需要参数,并返一个名为pathString值作为图像文件的URL。接下来,修改_sendmessage()添加imageUrl参数。

class ChatScreenState extends State<ChatScreen> {
  //@H_404_15@...
  void _sendmessage({ String text,String imageUrl }) {
    reference.push().set({
      'text': text,'imageUrl': imageUrl,'senderName': googleSignIn.currentUser.displayName,'senderPhotoUrl': googleSignIn.currentUser.photoUrl,});
    analytics.logEvent(name: 'send_message');
  }
  //@H_404_15@...
}

创建一个用于将文件上传到Google Cloud Storage的实例变量,初始化它以获取File对象的引用,并将其传递给put()方法。给每个文件一个唯一的名称,使用image_作为前缀,然后是随机整数

class ChatScreenState extends State<ChatScreen> {
  //@H_404_15@...
  Widget _buildTextComposer() {
        //@H_404_15@...
              child: new IconButton(
                icon: new Icon(Icons.photo_camera),onPressed: () async {
                  await _ensureLoggedIn();
                  File imageFile = await ImagePicker.pickImage();
                  int random = new Random().nexTint(100000);
                  StorageReference ref = FirebaseStorage.instance.ref().child("image_$random.jpg");
                  StorageUploadTask uploadTask = ref.put(imageFilE);
                  Uri downloadUrl = (await uploadTask.futurE).downloadUrl;
                }
              ),//@H_404_15@...
  }
  //@H_404_15@...
}

put()方法由Firebase的Cloud Storage API定义,它需要一个File对象作为参数,并将其上传到Google云端存储Bucket。之前导入的Flutter Firebase Storage插件提供对该API的访问,并定义了StorageUploadTask类。上传完成后,您可以获取图像的downloadURL,现在调用_sendmessage()并传递downloadURL来发送图像。

class ChatScreenState extends State<ChatScreen> {
  //@H_404_15@...
  Widget _buildTextComposer() {
        //@H_404_15@...
              child: new IconButton(
                icon: new Icon(Icons.photo_camera),onPressed: () async {
                  await _ensureLoggedIn();
                  File imageFile = await ImagePicker.pickImage();
                  int random = new Random().nexTint(100000);
                  StorageReference ref = FirebaseStorage.instance.ref().child("image_$random.jpg");
                  StorageUploadTask uploadTask = ref.put(imageFilE);
                  Uri downloadUrl = (await uploadTask.futurE).downloadUrl;
                  _sendmessage(imageUrl: downloadUrl.toString());
                }
              ),//@H_404_15@...
  }
  //@H_404_15@...
}

这个URL用于应用程序UI从Google云端存储下载图像到本地,让发送人在聊天对话中查看他们发送的图像。发送或接收的每个聊天消息都需要能够显示图像和文本。接下来,我们将增强Chatmessage类,以检测用户何时发送图像并使用其URL获取图像。

class Chatmessage extends StatelessWidget {
  //@H_404_15@...
  @override
  Widget build(BuildContext context) {
    @H_404_15@return new SizeTransition(
      //@H_404_15@...
      child: new Container(
        margin: const EdgeInsets.symmetric(vertical: 10.0),child: new Row(
          crossAxisAlignment: CrossAxisAlignment.start,children: <Widget>[
            //@H_404_15@...
            new column(
              crossAxisAlignment: CrossAxisAlignment.start,children: <Widget>[
                new Text(
                  snapshot.value['senderName'],style: Theme.of(context).textTheme.subhead),new Container(
                  margin: const EdgeInsets.only(top: 5.0),child: snapshot.value['imageUrl'] != null ?
                    new Image.network(
                      snapshot.value['imageUrl'],width: 250.0,):
                    new Text(snapshot.value['text']),)
              ]
            )
          ]
        )
      )
    );
  }
}

在上面的代码中,如果数据库行的值字段是imageUrl,那么应用程序将创建一个Image窗口控件,并将其与图像的内容填充。为了一致性,将宽度设置为特定数量的逻辑像素。如果消息不包含图像,则应用程序将在完成此步骤之前创建一个Text窗口控件。

Flutter实战一Flutter聊天应用(九)

因为我们在更改了iOS的Info.plist配置文件,所以我们现在需要重新启动应用程序,而不是重新加载。

大佬总结

以上是大佬教程为你收集整理的Flutter实战一Flutter聊天应用(九)全部内容,希望文章能够帮你解决Flutter实战一Flutter聊天应用(九)所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。