【鸿蒙】大模型对话应用(二):对话界面设计与实现

Demo介绍

本demo对接阿里云和百度的大模型API,实现一个简单的对话应用。

DecEco Studio版本:DevEco Studio 3.1.1 Release

HarmonyOS SDK版本:API9

关键点:ArkTS、ArkUI、UIAbility、网络http请求、列表布局、层叠布局

对话页面设计

参照各种聊天类软件设计,一个简单的对话页面大致可分为三部分:对话框头,对话框,输入框

在src/main/ets/pages目录下新建页面,完成对话页面UI实现;

注意:一定是新建page;新建ets文件或复制已有的page,都会导致页面的路由文件src/main/resources/base/profile/main_pages.json中 无法生成新页面的路由。

@Entry
@Component
struct ChatPage {
  build() {
    Row() {
      Column() {
        // 1 对话框头
        headerText("Hello 文心一言")
        // 2 对话框
        chatList()
        // 3 输入框
        inputBox()
      }
      .width('100%')
    }
    .height('100%')
  }
}
@Builder function headerText(title: string) {
  
}

@Builder function chatList() {

}

@Builder function inputBox() {

}

对话框头设计实现

使用 @Builder 注解自定义UI结构 headerText

其中仅一个文本组件,文本字体最小20,最大40,文本限制占一行;是为了适配手机竖屏时,字体大小固定可能导致错行或展示异常;

对话框头高度占全屏比为10%

@Builder function headerText(title: string) {
  Text(title)
    .minFontSize(20).maxFontSize(40).maxLines(1)
    .fontWeight(FontWeight.Bold)
    .height('10%')
}

预览效果:

对话框设计实现

对话框中,每条消息又由:①对话消息、②对话头像,两部分实现

先定义消息体类结构:

  • role,消息发起角色;分为我方(MessageRoleEnum.Mine)和对方(MessageRoleEnum.Other)
  • message,消息文本
export class MessageVO {
  role: MessageRoleEnum
  message: string

  constructor(role: MessageRoleEnum, message: string) {
    this.role = role
    this.message = message
  }
}

export enum MessageRoleEnum {
  // 我方
  Mine,
  // 对方
  Other
}

定义测试数据

import { MessageRoleEnum, MessageVO } from '../model/MessageVO'
class TextTest {
  static readonly Text: MessageVO[] = [
    {
      role: MessageRoleEnum.Mine,
      message: '请介绍一下你自己'
    },
    {
      role: MessageRoleEnum.Other,
      message: "我是百度公司开发的人工智能语言模型,我的中文名是文心一言,英文名是ERNIE-Bot," +
      "可以协助您完成范围广泛的任务并提供有关各种主题的信息,比如回答问题,提供定义和解释及建议。如果您有任何问题,请随时向我提问。"
    },
    {
      role: MessageRoleEnum.Mine,
      message: '我在上海,周末可以去哪里玩?'
    },
    {
      role: MessageRoleEnum.Other,
      message: '上海是一个充满活力和文化氛围的城市,有很多适合周末游玩的地方。以下是几个值得推荐的地方:\n\n1. 上海科技馆:上海科技馆是中国大陆最大的科技馆之一'
    }
  ]
}

使用列表组件(List)完成布局构建

说明:ArkUI提供了一种轻量的UI元素复用机制@Builder,@Builder所装饰的函数遵循build()函数语法规则,开发者可以将重复使用的UI元素抽象成一个方法,在build方法里调用。

下面代码中chatList 为对话框的UI布局结构;

chatLine_mine chatLine_other 分别为:消息源是自己 和 消息源是对方(大模型)时的UI结构,唯一不同的就是图像在左(对方)还是在右(我方);

chatLine_image_style 修饰对话框中头像样式;

chatLine_text_style 修饰对话框中消息文本的样式。

@Builder function chatList() {
  List({space: 15, scroller: this.scroller}) {
    ForEach(TextTest.Text, (item: MessageVO) => {
      if (item.role === MessageRoleEnum.Mine) {
        chatLine_mine(item.message)
      } else {
        chatLine_other(item.message)
      }
    })
  }
  .alignListItem(ListItemAlign.Center)
  .height('80%')
}

@Builder function chatLine_mine(msg:string) {
  Row({space: 5}) {
    Text(msg).chatLine_text_style()
    Image($r("app.media.icon")).chatLine_image_style()
  }
  .alignItems(VerticalAlign.Top)
}
@Builder function chatLine_other(msg:string) {
  Row({space: 5}) {
    Image($r("app.media.icon")).chatLine_image_style()
    Text(msg).chatLine_text_style()
  }
  .alignItems(VerticalAlign.Top)
}

@Extend(Image) function chatLine_image_style() {
  .width(50)
  .aspectRatio(1)
}
@Extend(Text) function chatLine_text_style() {
  .fontSize(20)
  .fontColor(Color.White)
  .width('70%')
  .lineHeight(25)
  .backgroundColor('rgb(64,64,64)')
  .padding(12)
  .border({radius: 10})
}

预览效果:

输入框设计实现

使用层叠布局(Stack)完成一个简单的输入框;

其中【发送】按钮图标,是一个png格式图片,放在src/main/resources/base/media 目录下;

API9中,输入框组件(TextInput)API不支持原生的 [ 清除输入框文本按钮 ] ,可以使用层叠布局配合TextInput 组件的 text 属性实现。

@Builder function inputBox() {
  Row() {
    Stack() {
      TextInput({placeholder: '有问题尽管问我~'})
        .height(50)
        .enterKeyType(EnterKeyType.Send)
      Image($r('app.media.ic_public_send'))
        .margin({right:10})
        .height(35)
    }
    .alignContent(Alignment.End)
    .height('10%')
  }
  .width('90%')
}

预览效果:

头像图标为项目创建默认生成的src/main/resources/base/media/icon.png,可自己更换

发送图标可在华为官网图标库获取:HarmonyOS 主题图标库 | icon素材免费下载 | 华为开发者联盟

至此,对话的UI页面就构建完成了;

使用相同的步骤,可以构建出相同的两个页面,一个用于和阿里云大模型对话,一个用于和百度云大模型对话。

下一步,可以通过页面跳转或跨Ability调用的方式,从首页进入不同大模型的对话页面;

之后可以通过请求大模型接口,更新页面数据,驱动页面渲染,实现与大模型的对话效果。

参考文档(鸿蒙官方开发指南):文档中心

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/359703.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Mac下手动源码编译安装Swig

使用Homebrew安装 这个方式最简单,但是一般都是安装的最新版: brew install swig如果按照特定版本,需要看一个当前支持的列表: brew search swig brew install swig3源码编译安装 swig依赖pcre库,需要先安装pcre …

一文掌握SpringBoot注解之@Component 知识文集(8)

🏆作者简介,普修罗双战士,一直追求不断学习和成长,在技术的道路上持续探索和实践。 🏆多年互联网行业从业经验,历任核心研发工程师,项目技术负责人。 🎉欢迎 👍点赞✍评论…

Nginx 本地部署vue项目

1、 下载 Nginx 稳定版本 2、下载安装后,打开 nginx.conf配置文件 3、找到打包好的文件,并配置运行文件 文件的位置 root C:/server/build location /{root C:/server/build;index index.html index.htm;#解决刷新后nginx报404问题try_files $uri …

redis复习笔记05(小滴课堂)

案例实战之注册登录-图形验证码谷歌开源Kaptcha引入 验证码配置工具类。 验证码存储Redis逻辑编码实战 工具类用于获取本机ip和md5加密,直接使用就行,我们这里主要是学习redis不是学习这个。 获取验证码并存到redis中的接口: 运行测试&…

聚焦AI新动能,九州未来与燧弘华创签约!

1月24日,厦门市电子信息与人工智能产业高质量发展大会成功举办。来自电子信息产业、人工智能领域的企业家、专家等近300位嘉宾齐聚一堂,共谋智能基础,共话产业合作,共享发展商机。 会上,九州未来与燧弘华创签署算力租…

【Tomcat与网络4】Tomcat的连接器设计

目录 1 如何设计一个灵活可靠的连接器 2 主要组件介绍 在上一篇,我们介绍了Tomcat提供服务的整体结构,本文我们一起来看一下Tomcat的连接器的设计。 在前面我们提到Tomcat主要完成两个功能: 处理 Socket 连接,负责网络字节流与…

详解SpringCloud微服务技术栈:深入ElasticSearch(1)——数据聚合

👨‍🎓作者简介:一位大四、研0学生,正在努力准备大四暑假的实习 🌌上期文章:详解SpringCloud微服务技术栈:ElasticSearch实战(旅游类项目) 📚订阅专栏&#x…

Docker容器引擎镜像创建

目录 一、镜像的创建 (一)基于现有镜像创建 1.启动一个镜像,在容器里做修改 2.将修改后的容器提交为新的镜像 (二)基于本地模板创建 (三)基于Dockerfile 创建 1.联合文件系统&#xff08…

【DB2 流浪之旅】 第一讲 Linux 环境安装 db2 数据库

DB2数据库是IBM开发的一种大型关系型数据库平台。它支持多用户或应用程序在同一条SQL 语句中查询不同database甚至不同DBMS中的数据。一般DB2是搭配IBM Power系列小机使用的,兼容性好、性能高。当然DB2也有Linux版本的,相对性能会差一些,主要…

大创项目推荐 题目:基于深度学习卷积神经网络的花卉识别 - 深度学习 机器视觉

文章目录 0 前言1 项目背景2 花卉识别的基本原理3 算法实现3.1 预处理3.2 特征提取和选择3.3 分类器设计和决策3.4 卷积神经网络基本原理 4 算法实现4.1 花卉图像数据4.2 模块组成 5 项目执行结果6 最后 0 前言 🔥 优质竞赛项目系列,今天要分享的是 基…

前端基础-事件循环(消息循环)

这里写自定义目录标题 1. 浏览器进程主要的进程(了解) 2. 渲染主线程是如何工作的?3. 面试题:如何理解 JS 的异步?3. JS为何会阻碍渲染?4. 任务有优先级吗?5. 面试题:阐述一下 JS 的…

React-Native跟Android交互--简单示例记录

/** * 使用命令 npx react-nativelatest init DemoRN创建项目 * * "react": "18.2.0", * "react-native": "0.73.2" * * 官网有详细教程:https://reactnative.dev/docs/native-modules-android */ 一、RN invoke androi…

Docker 镜像的创建

创建镜像有三种方法,分别为基于已有镜像创建、基于本地模板创建以及基于Dockerfile创建。 一、基于现有镜像创建 创建nginx镜像: 1、首先启动一个容器,在容器里做修改 2、然后将修改后的容器提交为新的镜像,需要使用该容器的 I…

Compose | UI组件(十二) | Lazy Layout - 列表

文章目录 前言LazyListScope作用域 用来干什么?LazyColumn组件含义?LazyColumn的基本使用LazyColumn Padding设置边距LazyColumn 设置边距 (contentPadding)LazyColumn 为每个子项设置边距 (Arrangement.spacedBy())LazyColumn 根据 rememberLazyListSta…

使用visual studio写一个简单的c语言程序

官网下载visual studio,社区版免费的 https://visualstudio.microsoft.com/zh-hans/ 下载好以后选择自己的需求进行安装,我选择了两个,剩下的是默认。 创建文件:

android学习笔记----ListView和各种适配器简介

打气筒(LayoutInflater对象)介绍: MainActivity.java import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import an…

15.Golang中的反射机制及应用

目录 概述实践基本应用复杂应用 结束 概述 Golang中的反射用法还是比较简单的 reflect.TypeOf(arg)reflect.ValueOf(arg) 实践 基本应用 package mainimport ("fmt""reflect" )func reflectNum(arg interface{}) {fmt.Println("type ", re…

Vue中嵌入原生HTML页面

Vue中嵌入html页面并相互通信 需求&#xff1a;b2b支付需要从后获取到数据放到form表单提交跳转&#xff0c;如下&#xff1a; 但是vue目前暂时没找到有类似功能相关文档&#xff0c;所以我采用iframe嵌套的方式 1. Vue中嵌入Html <iframe src"/static/gateway.htm…

Unity 设置鼠标

前言 本章主要对鼠标图标样式还有鼠标显隐进行设置 图标样式的设置 代码控制 有时候需要有改变鼠标样式的需求可以使用如下代码 Cursor.SetCursor(this.mouseTexture, Vector2.zero, CursorMode.Auto); 传入的要替换的图标偏移量允许您在支持的平台上使用硬件光标&#xff0…

Blender教程(基础)-内插面、分离、环切、倒角-08

一、内插面 菜单位置如下图位置。 单击需要处理的面&#xff0c;出现一个黄色的圈。 1、菜单选中内插 鼠标悬停在黄色圈内单击左键可以来回实现内插&#xff0c;但是发现并不好操作。 2、快捷键内插 在选中需要操作的面之后&#xff0c;鼠标移动到外面&#xff0c;键盘在英…