鸿蒙开发进阶(HarmonyOS)谈天UI结果与简单AI接口调用
鸿蒙NEXT开发实战往期必看文章:一分钟相识”纯血版!鸿蒙HarmonyOS Next应用开发!
“非常具体的” 鸿蒙HarmonyOS Next应用开发学习门路!(从零基础入门到精通)
HarmonyOS NEXT应用开发案例实践总结合(持续更新......)
HarmonyOS NEXT应用开发性能优化实践总结(持续更新......)
鸿蒙发展的真快呀,半年前还在用api9,现在直接api12了。下载新的模拟机时发现,DevEcoStudio都从3.1下载到了现在的5.0了,这算不算见证了它的发展呢,哈哈。
https://img-blog.csdnimg.cn/img_convert/4f4b28e7ad5a69e00ef51252f9fc3db6.png
想实行简单写一个谈天页面调用模子,实行下语法方面有什么厘革,然后发现很简单的谈天UI,尽然会有这么多坑,害!话不多说开干!
一、滚动谈天区域
想想一个谈天区域无非就是一个滚动列表判断一下然后弹性布局左右对齐,太简单了,使用Scroll这个可滚动的容器组件,将消息列表遍历一下,单独界说消息的左右对齐,完事!
这时出现了第一个不好控制的结果,当对话少无法占满滚动区域大小尽然是默认居中!
https://img-blog.csdnimg.cn/img_convert/826c09a84a839f74f2c958b473c5447f.png
当子组件的布局尺寸高出父组件的尺寸时,内容才可以滚动,翻了会官网文档没找到Scroll内元素向上对齐的方法
只好动用空空的脑袋想一想了:
https://img-blog.csdnimg.cn/img_convert/1e8aabe9a2d5bcc54005763c958106c2.jpeg
[*] 对话少时,子组件的布局尺寸小于父组件的尺寸无法滚动,默认居中对齐
[*] 对话多时高出父组件的尺寸可以滚动,滚动是不是就能上对齐了!
想到就干:设置子组件最小长度为Scroll容器长度
.constraintSize({minHeight:"100%"})
https://img-blog.csdnimg.cn/img_convert/ab001061b67a8ebee5f8c60bbc615933.png
可以!(可以是可以哈,后续一个bug,好像就这样玩出来的 TAT )
// 谈天内容区域Scroll() {Column(){ ForEach(this.messages, (item: message) => { Flex({justifyContent: item.role === 'user' ? FlexAlign.End : FlexAlign.Start}) { if (item.role === 'user') { ItemComponent(item, true) // 自己发送的消息 } else { ItemComponent(item, false)// 对方发送的消息 } } })}.constraintSize({minHeight:"100%"})
// 设置子组件最小长度为Scroll容器长度}.width("100%").height("90%").scrollBar(BarState.Off) 二、消息左右对齐与传输数据格式
1、消息怎样设置左右对齐
是我的消息我就放右边,不是我的就放左边,判断判断
这里可以用if非常好,那就简单了,来个参数告诉我这条消息是不是自己的,然后:
[*] Flex布局容器 里面用三目运算符设置对齐方式,可以吧
[*] 头像左右不好控制用if控制其显示,是不是很方便
最后就是颜色,大小,样式的调整了,没啥美感就这样了,开摆
https://img-blog.csdnimg.cn/img_convert/dfe73649c77e1a0bbc38ce4180e8fd11.jpeg
//渲染消息
@Builder
function ItemComponent(item: message, isSelf: boolean) {
Flex({ justifyContent:isSelf ? FlexAlign.End : FlexAlign.Start}) {
if(!isSelf) {
Image($r("app.media.chatbot"))
.width("50vp")
}
Text(item.content)
.fontSize(16)
.lineHeight(24)
.backgroundColor(isSelf ? '#ffdddd' : '#ddffdd') // 根据发送者设置背景色
.padding({ top: 8, bottom: 8, left: 10, right: 10 })
.borderRadius(10)
.textAlign(TextAlign.Start)
.constraintSize({maxWidth: "240vp"}) // 设置最大宽度
if(isSelf) {
Image($r("app.media.me"))
.width("50vp")
}
}
.margin({ top: 4, bottom: 4 }) // 消息间距
}
2、传输数据格式
[*] 由于要知道是谁发的消息就记录了一下脚色,对比了一下QQ,想到昵称尽然没有,等待后续加工中…
[*] 写到json格式的数据,必要取返回消息的一个值,HarmonyOS next不在支持any了,语法检查有点严酷哈,只好自界说范例了。
必要哪个字段界说哪个好像也行,偷懒不可取哦
[*] 由于接口调用要将全部上下文消息整体发送已往,所以界说了个messages数组,还可以forearch展示用的也是这个数组
// 发送的每条消息类型
class message{
role: string; // 发送角色
content: string; // 发送的消息
// 如有更多需求,如:发消息人物昵称,可进行相应的设计
constructor(role: string,content: string) {
this.role = role
this.content = content
}
}
// 根据ai反回的数据类型定义的接口类型,next不支持any类型
interface userInfo{
id: string,
object: string,
created: string,
result: string
is_truncated: boolean,
need_clear_history: boolean,
finish_reason: string
}
// @State数据与页面双向数据绑定,当消息增加时页面刷新显示
@State messages: Array<message> = [
new message("user","你好"),
new message("assistant", "你好,请问有什么我可以帮助你的吗?无论你有什么问题或需要帮助,我都会尽力回答和协助你。请随时告诉我你的需求。")
];
三、输入框和发送
这里有个bug很难熬,各位大佬,求评论,救救 TAT
https://img-blog.csdnimg.cn/img_convert/3a05e565c441121fad7cfa5c38bd02bc.jpeg
一个输入框,一个按钮发送,用预览器调试挺方便的,然后到了模拟机有个叫 键盘 的东东没考虑到。
这个东西尽然会把,消息给顶上去!消息少时就输入键盘一跳出来就白白了 (看不到消息了)
https://img-blog.csdnimg.cn/img_convert/71e2c1bea1d47308400bf7826ded5da3.gif
研究了一下微信,消息少时输入时消息是顶格的,消息多时输入消息看到的最下放时最新消息,也就滚动到了看的见最下方
实行办理:
[*]一、翻动我’‘可爱’'的官方文档 找到一个叫 Scroller 的可滚动容器组件的控制器,当它按下时,获取当前消息区域滚动条的位置,当它抬起时,让它回到按下时的位置,无效
[*]二、搜索其他语言办理办法:vue谈天页面在进入之后信息滑动到底部位置 然后照旧翻动我’‘可爱’'的官方文档,不知道该怎么搜索,没找到相应的函数
[*]三、求救
// 可滚动的容器组件,当子组件的布局尺寸超过父组件的尺寸时,内容可以滚动。
myScroll: Scroller = new Scroller();
locat: OffsetResult = {xOffset: 0, yOffset: 0};
// 输入框和发送按钮
Row() {
TextInput({ text: this.inputText, placeholder: '输入你想询问的问题' })
.height(40)
.width("70%")
.onChange((val) => {
this.inputText = val
})
.margin({right: 2})
.onClick(() => {
this.locat = this.myScroll.currentOffset();
})
.onEditChange((isEditing) => {
if(isEditing) {
this.myScroll.scrollTo(this.locat);
}
})
Button('发送')
.onClick(() => {
// 发送消息并更新UI
this.messages.push(new message("user", this.inputText))
this.inputText = ''
getTake(this.messages, this.token).then((response: AxiosResponse<userInfo>) =>{
let text = response.data.result
this.messages.push(new message("assistant", text))
})
})
}
.justifyContent(FlexAlign.Center)
.height("10%")
四、AI接口调用
这个我会,我会使用axios,忽然想到新版不知道能不能用,证明结果:axios已经适配鸿蒙HarmonyOS NEXT
OpenHarmony三方库中央仓 axios
import axios, {AxiosResponse} from '@ohos/axios'
这里调用的是文兴一言模子,要调用什么ai可查看其开发文档
const apiKey = "xxxxxx"
const secret = "xxxxxxxxxxx"
// 根据apikey和secret获取token
export function get_access_token(){
return axios.post(`/oauth/2.0/token?grant_type=client_credentials&client_id=${apiKey}&client_secret=${secret}`)
}
// 根据token和所有消息发送一次请求,获取结果
export function getTake(messages: Array<message>, token: string): Promise<AxiosResponse>{
const params =JSON.stringify({
messages: messages
})
return axios.post(`/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/completions_pro?access_token=${token}`, params)
}
同时HarmonyOS next 内置了许多AI服务 哦
如:textToSpeech (文本转语音) import { textToSpeech } from '@kit.CoreSpeechKit'; objectDetection(多目标识别)import { visionBase, objectDetection } from '@kit.CoreVisionKit;等
具体查看官方文档:AI | 华为开发者联盟 (huawei.com)
五、总结
果然手搓UI界面得:一、先计划,二、懂布局
换句话说:创建UI界面时,首要步骤是进行精心的计划,其次则必要深入理解并掌握布局技巧。
HanmonyOS next入门很简单,但最好一个产品很不轻易,欢迎来一起学习
最后附上结果图和源码地点
一、结果图
https://img-blog.csdnimg.cn/img_convert/c094a58952993c0cc55cfc383bf3253f.png
https://img-blog.csdnimg.cn/img_convert/7252b72963710a2898dc897b96399f35.png
二、目录结构
https://img-blog.csdnimg.cn/img_convert/dffe2e5e2b4d34d21f8fc6a55a744909.png
https://i-blog.csdnimg.cn/direct/aecd8e669e8141f7b75be983bfd94925.png
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]