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

news2024/12/25 23:51:08

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调用的方式,从首页进入不同大模型的对话页面;

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java笔记 --- 一、双列集合

一、双列集合 双列集合的特点 Map 创建Map对象时,要规定键和值的泛型 Map是一个接口,不能直接创建,要创建实例化对象 Map的遍历 通过键找值 先获取到键的对象,并放到一个单列集合中(map.KeySet()方法)…

如何预防服务器IP被劫持,危害有什么?

服务器IP被劫持是一种严重的网络安全问题,攻击者通过篡改服务器的IP地址,将网络流量重定向到恶意服务器或网站,导致用户无法正常访问目标服务器,并可能面临数据泄露、恶意软件感染等安全风险。了解服务器IP被劫持的危害和预防措施…

【数据结构与算法】6.栈

📚博客主页:爱敲代码的小杨. ✨专栏:《Java SE语法》 ❤️感谢大家点赞👍🏻收藏⭐评论✍🏻,您的三连就是我持续更新的动力❤️ 🙏小杨水平有限,欢迎各位大佬指点&…

python 基础知识点(蓝桥杯python科目个人复习计划25)

今日复习内容:基础算法中的进制转换 1.任意进制转十进制 (1) 基数:表示奇数数字符号的个数 10进制:0--9,基数为1016进制:0--9,A--F,基数为16 (2&#xff…

146基于matlab的齿轮非线性动力学

基于matlab的齿轮非线性动力学,绘出系统状态变量随参数变化分岔图,绘图参数对应的系统各周期及混沌状态的时间历程图、相轨迹图、Poincare映射图,程序已调通,可直接运行。 146 matlab 齿轮非线性动力学 相图 (xiaohongshu.com)

第2章-神经网络的数学基础——python深度学习

第2章 神经网络的数学基础 2.1 初识神经网络 我们来看一个具体的神经网络示例,使用 Python 的 Keras 库 来学习手写数字分类。 我们这里要解决的问题是, 将手写数字的灰度图像(28 像素28 像素)划分到 10 个类别 中(0…

Unity读书系列《Unity3D游戏开发》——拓展编辑器(一)

文章目录 前言一、扩展Project视图1、右键扩展菜单(Asset)2、监听事件3、拓展布局 二、扩展Hierarchy视图1、拓展菜单(GameObject)2、拓展布局3、重写菜单 三、扩展Inspector视图1、扩展原生组件2、扩展继承组件 四、扩展Scene视图…

【多线程】ThreadLocal 作为类的私有静态字段实践

ThreadLocal 通常作为类的私有静态字段存在的主要原因是为了确保每个线程都能够拥有自己独立的 ThreadLocal 变量。 以下是一些原因: 线程隔离: ThreadLocal 的设计目的是为了实现线程隔离,即每个线程都可以独立地管理自己的变量&#xff0c…

华为机考入门python3--(3)牛客3-明明的随机数

分类:集合、排序 知识点: 集合添加元素 set.add(element) 集合转列表 list(set) 列表排序 list.sort() 题目来自【牛客】 N int(input().strip()) nums set()for i in range(N):nums.add(int(input().strip()))# 集合转列表 nums_list l…

3 JS类型 值和变量

计算机对value进行操作。 value有不同的类型。每种语言都有其自身的类型集合。编程语言的类型集是该编程语言的基本特性。 value需要保存一个变量中。 变量的工作机制是变成语言的另一个基本特性。 3.1概述和定义 JS类型分为: 原始类型和对象类型。 原始类型&am…

最高20倍!压缩ChatGPT等模型文本提示,极大节省AI算力

最高20倍!压缩ChatGPT等模型文本提示,极大节省AI算力_信息_段落_问题 在长文本场景中,ChatGPT 等大语言模型经常面临更高算力成本、更长的延迟以及更差的性能。为了解决这三大难题,微软开源了 LongLLMLingua。 据悉,L…

如何在docker容器中安装Elasticsearch中的IK分词器

目录 (1)准备IK分词器的压缩包 (2)进入docker容器 (3)移动ik分词器到指定文件夹 (4)解压分词器压缩包 (5)测试IK分词器是否安装成功 (1&#…

【Image captioning】论文阅读八—ClipCap: CLIP Prefix for Image Captioning_2021

中文标题:ClipCap: CLIP前缀用于图像描述(ClipCap: CLIP Prefix for Image Captioning) 文章目录 1. 介绍2. 相关工作3. 方法3.1 综述3.2 语言模型微调3.3 映射网络架构3.4 推理 4. 结果5. 结论 摘要:图像描述是视觉语言理解中的…

C语言——操作符详解2

目录 0.过渡0.1 不创建临时变量,交换两数0.2 求整数转成二进制后1的总数 1.单目表达式2. 逗号表达式3. 下标访问[ ]、函数调用( )3.1 下标访问[ ]3.2 函数调用( ) 4. 结构体成员访问操作符4.1 结构体4.1.1 结构体的申明4.1.2 结构体变量的定义和初始化 4.2 结构体成…

SpringBoot 配置类解析

全局流程解析 配置类解析入口 postProcessBeanDefinitionRegistry逻辑 processConfigBeanDefinitions逻辑 执行逻辑解析 执行入口 ConfigurationClassPostProcessor.processConfigBeanDefinitions()方法中的do while循环体中 循环体逻辑 parse方法调用链 doProcessConfigurat…

【C++中STL】list链表

List链表 基本概念构造函数赋值和交换大小操作插入和删除数据存取反转和排序 基本概念 将数据进行链式存储 链表list是一种物理存储单元上非连续的存储结构,数据元素的逻辑顺序是通过链表中的指针链接实现的,链表是由一系列结点组成,结点的组…

Android studio环境搭建过程异常

异常:Connect timed out 创建新项目时,提示time out 解决方案:修改gradle下载地址,使用国内镜像地址 distributionUrlhttps\://services.gradle.org/distributions/gradle-8.2-bin.zip修改成distributionUrlhttps\://mirrors.c…

fatal error:require():Failed opening required

今天部署网站遇到了个错误 fatal error:require():Failed opening required 这个错误经常遇到 大多是网站 是开启了 open_basedir 但今天这个错误很神奇 先说解决方法 1. 检测一下是不是真的 不存在这个文件 即使100%确定 也建议你再仔细看一下 这个文件存不存在 今天我遇…

日常学习之:如何使用 dockerfile 将 vue 的单独前端项目通过 docker 的方式部署到 heroku上

文章目录 需求描述开始操作准备阶段:准备 server.js 文件并安装依赖,将 vue 项目包装成单独的服务器制作 server.js安装 server.js 需要的依赖 构建 Dockerfileheroku container 链接和部署其他细节 需求描述 你想用 vue 构建前端,用 django…

终端录屏神器Asciinema慎用教程

1.效果 2.安装 centos yum install asciinema ubuntu apt-get install asciinema 3.使用 asciinema rec kali.cast #录制文件 asciinema play kali.cast #播放文件 asciinema upload kali.cast #上传文件 详细说明:只使用 asciinema rec 也是可以的,ctrlD结束录屏 4.…