本案例是用Bmob 鸿蒙SDK开发一个常见的图片列表和回复功能,先直接上最终的效果:
因为整个工程对于新手来说还是有点多内容,这里挑选比较重要的步骤进行讲解,查看源码可直接跳到最后进行下载。
一、导入Bmob SDK
创建鸿蒙项目,选择Stage模型,API9.0,然后在DevEco Studio 开发工具的命令行(Terminal)中执行下面的命令,安装Bmob Harmony SDK:
shell
ohpm install @bmob/bmob
如果一切顺利,你会在当前项目下的oh_modules
目录下看到@bmob/bmob
的包已经成功下载,如下图所示:
二、获取密钥
登录 Bmob后端云 ,创建应用,获取Secret Key和Secret Code,如下图所示:
三、初始化应用
在你创建的鸿蒙应用中,entry/src/main/ets
下面新建一个ArkTS File,名为BmobApp
。代码如下:
arkts
import { Bmob } from '@bmob/bmob';
import AbilityStage from '@ohos.app.ability.AbilityStage';
export default class BmobApp extends AbilityStage {
onCreate() {
super.onCreate();
Bmob.initialize('你的Secret Key', '你的Secret Code')
}
}
四、配置网络权限和设置应用入口
打开 entry/src/main/module.json5
文件,在module
节点下面新增 srcEntry
和 requestPermissions
子节点,配置如下:
arkts
{
"module": {
"name": "entry",
"type": "entry",
"description": "$string:module_desc",
"mainElement": "EntryAbility",
"deviceTypes": [
"phone",
"tablet"
],
"srcEntry": "./ets/BmobApp.ets",
"requestPermissions": [
{
"name": "ohos.permission.INTERNET"
}
],
...省略更多
}
}
五、数据表设计
进入到Bmob后端云控制台,创建一个名为videos
(内容数据表)和replys
(回复数据表)的数据表,并添加数据。
videos
表设计如下:
字段名称 | 注释 | 类型 |
---|---|---|
url | 分享的图片 | string |
avator | 头像地址 | string |
content | 发表的内容 | string |
num | 回复的数量 | number |
name | 发表人 | string |
replys
表设计如下:
字段名称 | 注释 | 类型 |
---|---|---|
videoid | 评论的内容记录对应的objectId信息 | string |
avator | 头像地址 | string |
content | 评论内容 | string |
name | 评论人 | string |
最后的数据表如下:
六、添加内容展示组件
我们仔细观察一下,会发现内容展示的item项和评论回复的item项很相似,差别只有 分享的图片
和 回复的数量
在内容展示页面存在,在评论回复项中不存在,而且这部分的页面布局多个地方重复调用。
我们可以把这部分的功能重复使用起来:
- 在
src\main\ets
文件夹下面新增一个新的文件夹,这里取名为component
,如下图所示:
- 在
component
文件夹下新增MyListItem.ets
文件,代码如下:
scss
@Component
export default struct MyListItem {
@State item: any = null
build() {
Row() {
Image(this.item.avator)
.width(32)
.aspectRatio(1)
.borderRadius(50)
Column({ space: 5 }) {
Text(this.item.name)
.width('100%')
.fontWeight(FontWeight.Bold)
.fontSize(15)
Image(this.item.url)
.width('100%')
.borderRadius(10)
.objectFit(ImageFit.Contain)
Text(this.item.content)
.width('100%')
Row() {
Text(this.item.createdAt)
.fontSize(12)
.fontColor('#c3c4c5')
Row({ space: 4 }) {
Image(this.item.num!=undefined?$r('app.media.ic_public_comments'):'')
.width(14)
.aspectRatio(1)
.fillColor('#c3c4c5')
Text(this.item.num!=undefined?this.item.num.toString():'')
.fontSize(12)
.fontColor('#c3c4c5')
}
}
.width('100%')
.justifyContent(FlexAlign.SpaceBetween)
}
.layoutWeight(1)
.padding({ left: 10 })
}
.padding(15)
.alignItems(VerticalAlign.Top)
}
}
七、完成首页列表功能
1. 获取内容列表
在页面的aboutToAppear
方法中,添加如下的代码,获取videos
表中的内容(按createdAt
字段顺序排列):
javascript
// 获取内容列表
let query = Bmob.Query('videos')
query.orderby('createdAt').find().then((res) => {
this.myitems = res
}).catch((err) => {
Prompt.showToast({ message: err.error })
})
其中,myitems
的定义如下:
css
@State myitems: any = []
2. 展示内容列表
- 首先在
Index
页面的顶部添加组件的引用:
javascript
import MyListItem from '../component/MyListItem'
- 在
Index
布局页面中用Foreach
添加如下的代码:
scss
Scroll() {
Column() {
ForEach(this.myitems, (video) => {
MyListItem({ item: video })
.onClick(() => {
router.pushUrl({ url: 'pages/Reply', params: { 'video': video } })
})
})
Divider()
.strokeWidth(8)
.color('#f5f5f5')
}
.padding({ bottom: 30 })
}
这里需要说明的是,你可以像我这样,用Scroll
组件包裹ForEach
组件进行使用,也可以直接用List
组件(回复页面我将采用List
组件的方式进行展示)。
页面之间的参数传递非常简单,我这里直接传递整个video对象到Reply页面
八、完成回复页面(Detail.ets)的功能
1. 获取上一个页面传递过来的参数
typescript
private detail: any = null
aboutToAppear() {
// 获取上一个页面传递过来的参数
this.detail = router.getParams()['video']}
}
2. 获取所有回复内容
编写如下的代码:
javascript
/**
* 获取回复内容
*/
getReplys() {
let query = Bmob.Query('replys')
query.where({ 'videoid': this.detail.objectId }).orderby('-createdAt').find().then((res) => {
this.replys = res
})
}
并在aboutToAppear
方法中进行调用。
3. 编写提交回复内容的代码
kotlin
/**
* 发送回复内容
*/
sendReply() {
Bmob.User().current().then((res) => {
if(this.content==''){
Prompt.showToast({message:'你还没有发表内容'})
return
}
let username = res.realname
let avator = res.avator
// 发表回复
let query = Bmob.Query('replys')
query.set('videoid', this.detail.objectId)
query.set('content', this.content)
query.set('avator', avator)
query.set('name', username)
query.save().then((res) => {
Prompt.showToast({ message: '评论成功' })
this.getReplys()
this.content = ''
// 增加videos表对应记录的回复计数
Bmob.Query('videos').increment(this.detail.objectId,'num',1)
})
})
}
这里需要注意的是,我们调用了Bmob.User().current()
方法,获取登录的用户信息,从而可以获取这个登录用户的头像和真实姓名。用户的登录操作我们可以在登录页面中进行调用(这里为了展示方便,没有制作登录页面,直接在Index.ets
页面的aboutToAppear
方法中模拟登录),登录方法如下:
javascript
Bmob.User().login('xiaowon', '123456').then((res) => {
Prompt.showToast({ message: '登录成功' })
})
对应_User表中的一个用户信息:
4. 展示回复内容
展示回复内容的布局代码非常简单,如下:
scss
// 显示回复内容
List() {
ForEach(this.replys, (reply) => {
ListItem() {
MyListItem({ item: reply })
}
})
}.margin({ bottom: 50 })
下载源码
源码地址: gitee.com/zhang-ming-...