#端云一体化开发# #HarmonyOS Next#《说书人》鸿蒙原生基于角色的对话式文 ...

打印 上一主题 下一主题

主题 1052|帖子 1052|积分 3156

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
1、写在前面

过去的一百年里,在“编程”的这个行业诞生之初,人们接纳面向过程的方式举行开发,但是,伴随着步伐规模的日益增大,步伐的复杂度也随之增加,利用结构化编程方法来管理复杂的步伐逻辑变得越来越困难。因此,开发者们引入了“面向对象”的概念,接纳将数据和操纵封装在“对象”中的方式,令步伐设计更加条理。

而现如今,市场上的文本类软件越来越多,创作者的门槛越来越低,无数笔墨作品争相涌现,长篇小说的字数也不断突破记录,但是,对于一个经验不敷丰富的创作者而言,常常会发生文章内容跑偏,角色性格无法把握的问题,特别是在小说笔墨长度越来越长时,如许的问题便愈发严肃。而在如许的情况下,我决定仿照“面向对象”的方式,开发一款基于“角色”定义,举行剧本编写的软件,帮助笔墨创作者们能够基于“角色”来编写文章,进步创作的服从与质量。

在选择开发平台时,我们注意到鸿蒙平台上还没有基于对话式的文本类APP,这使得我在实现根本功能的同时,还可以在这方面添补市场的空缺。此外,我也希望能够加入鸿蒙生态建设,助力国产科技企业发展,成为openHarmony漫天星光中的一员。

综上,我们决定开发一个鸿蒙原生的,基于角色定义的对话式文本编写软件,以达到办理市场空缺,办理用户需求的目的。

本文就是分享《说书人》的一部分鸿蒙技术实践过程,接待各位阅读


2、路由展示

2.1、页面展示

《说书人》的界面非常轻便,主要的界面包括:角色/剧本列表,用户空间,动态空间,以及阅读界面等,如下图所示







2.2、路由展示

(1)Tabs组件简介

Tabs组件的页面组成包罗两个部分,分别是TabContent和TabBar。TabContent是内容页,TabBar是导航页签栏,页面结构如下图所示,根据不同的导航类型,布局会有区别,可以分为底部导航、顶部导航、侧边导航,其导航栏分别位于底部、顶部和侧边。
Tabs组件的实践
《说书人》的角色/书籍列表,动态空间,个人页面,主要分为UserSpacePage,scriptInterface和DynamicPage三个组件,团结Tabs组件,举行页面布局,如下列代码所示:
  1. import { frame, frameDataSet, ThisPagefontColor } from '../Data/frameData'
  2. import { userOwnData, userOwn, userTheyData, userTheyTemplate } from '../Data/userData'
  3. import UserSpacePage from './mainPage/userSpacePage'
  4. import scriptInterface from './mainPage/scriptPage'
  5. import DynamicPage from './mainPage/dynamicPage'
  6. import router from '@ohos.router'
  7. @Entry
  8. @Component
  9. struct UserSpace {
  10.   aboutToAppear(): void {
  11.     let params = router.getParams() as Record<string, number>
  12.     this.pageIndex = params['goPageIndex']
  13.   }
  14.   @StorageProp('frame') frameData: frame = frameDataSet
  15.   @StorageProp('fontColor') ThisColor: ResourceColor = ThisPagefontColor
  16.   @StorageProp('userOwnData') userOwn: userOwnData = userOwn
  17.   @StorageProp('userTheyData') userTheyData: userTheyTemplate = userTheyData
  18.   @State pageIndex: number = 0
  19.   build() {
  20.     Flex(){
  21.       Tabs({
  22.         index: this.pageIndex == undefined ? 0 : this.pageIndex,
  23.       }){
  24.         TabContent(){
  25.           scriptInterface()
  26.         }.tabBar('推荐')
  27.         TabContent(){
  28.           DynamicPage()
  29.         }.tabBar('动态')
  30.         TabContent(){
  31.           UserSpacePage()
  32.         }.tabBar('空间')
  33.       }
  34.       .barPosition(BarPosition.End)
  35.     }
  36.     .backgroundColor(this.frameData.backGround)
  37.   }
  38. }复制
复制代码
3、端云一体化的实践应用

在本项目中,接入了华为云提供的认证服务与数据库服务,将AGC的serverless云和HarmonyOS的端举行团结开发,以下是开发示例
1、登录AppGallery Connect


2、在全部服务中,选择“认证服务”,启动手机号码认证





3、我的项目中,添加项目,再选择添加应用,随后根据实际情况填写即可





4、在“项目设置”中,下载SDK配置,并放在自己项目的如图所示的目录中







5、修改oh-package.json5文件,添加以下内容

  1. "dependencies": { "@hw-agconnect/hmcore": "^1.0.1", "@hw-agconnect/cloud": "^1.0.1" }复制复制复制
复制代码
6、修改EntryAbility.ets文件,在onCreate中添加以下内容



  1. async onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) {
  2.   let input = await this.context.resourceManager.getRawFileContent('agconnect-services.json')
  3.   let jsonString  = util.TextDecoder.create('utf-8', {
  4.     ignoreBOM: true
  5.   }).decodeWithStream(input, {
  6.     stream: false
  7.   });
  8.   initialize(this.context, JSON.parse(jsonString));
  9. }复制复制复制
复制代码
7、打开需要利用验证码的界面,导入代码

  1. // 导入
  2. import cloud from '@hw-agconnect/cloud';
  3. import { Auth, VerifyCodeAction } from '@hw-agconnect/cloud';
  4. import { promptAction } from '@kit.ArkUI';
  5. // 申请验证码
  6. function requestVerifyCode(phoneNumber: string){
  7.   cloud.auth().requestVerifyCode({
  8.     action: VerifyCodeAction.REGISTER_LOGIN,
  9.     lang: 'zh_CN',
  10.     sendInterval: 60,
  11.     verifyCodeType: {
  12.       phoneNumber: phoneNumber,
  13.       countryCode: '86',
  14.       kind: "phone"
  15.     }
  16.   }).then(verifyCodeResult => {
  17.     //验证码申请成功
  18.     promptAction.showToast({
  19.       message: '申请成功'
  20.     })
  21.   }).catch(() => {
  22.     //验证码申请失败
  23.     promptAction.showToast({
  24.       message: "申请失败 "
  25.     })
  26.   });
  27. }
  28. // 注册用户
  29. function createUser(phoneNumber: string, phoneCode: string){
  30.   cloud.auth().createUser({
  31.     kind: 'phone',
  32.     countryCode: '86',
  33.     phoneNumber: phoneNumber,
  34.     password: '123456789',//可以给用户设置初始密码,后续可以用密码来登录
  35.     verifyCode: phoneCode
  36.   }).then(result => {
  37.     // 创建用户成功
  38.     promptAction.showToast({
  39.       message: '创建成功'
  40.     })
  41.   }).catch(() => {
  42.     // 创建用户失败
  43.     promptAction.showToast({
  44.       message: '创建失败'
  45.     })
  46.   })
  47. }复制
复制代码
 以上是手机号部分的开发流程,数据库部分也与其相似,可以在AGC官网查看文档举行开发
4、角色/剧本创建部分

对于角色/剧本的创建,总是会遇见需要“多维数组”等云数据库默认无法实现的情况,这种情况下,就接纳分隔符来对数据举行处理,以字符串类型存储在云端,再在本地读取时举行反处理
角色创建部分如下:
  1. import { frame, frameDataSet,ThisPagefontColor, frameData } from '../../Data/frameData'
  2. import { userOwnData, userOwn } from '../../Data/userData'
  3. import { roleDataTemplate, roleData, roleCustom } from '../../Data/roleData'
  4. import router from '@ohos.router';
  5. import EntryPage from '../popUp/EntryPage'
  6. import CarePage from '../popUp/CarePage'
  7. import DelCarePage from '../popUp/DelCarePage'
  8. import closePage from '../popUp/closePage'
  9. import promptAction from '@ohos.promptAction';
  10. @Extend(Text) function textCare(size: number){
  11.   .fontColor('#3c3f41')
  12.   .backgroundColor('#e0dcda')
  13.   .fontSize(size)
  14.   .fontWeight(300)
  15.   .padding({
  16.     left: 8,
  17.     right: 8,
  18.     top: 5,
  19.     bottom: 5
  20.   })
  21.   .borderRadius(12)
  22.   .opacity(.8)
  23. }
  24. @Entry
  25. @Component
  26. struct UserCreate {
  27.   entryPageOpen: CustomDialogController = new CustomDialogController({
  28.     builder: EntryPage({
  29.       onCancel: (Name: string, Value: string) => {
  30.         this.roleCustom.push({
  31.           name: Name,
  32.           value: Value
  33.         })
  34.       }
  35.     })
  36.   })
  37.   carePageOpen: CustomDialogController = new CustomDialogController({
  38.     builder: CarePage({
  39.       onCancel: (Value: string) => {
  40.         this.roleLabel.push(Value)
  41.       }
  42.     })
  43.   })
  44.   delcarePageOpen: CustomDialogController = new CustomDialogController({
  45.     builder: DelCarePage({
  46.       onCancel: (Value: boolean) => {
  47.         if (Value) {
  48.           this.roleLabel.splice(this.delRoleIndex, 1)
  49.         }
  50.       },
  51.     })
  52.   })
  53.   closeOpen: CustomDialogController = new CustomDialogController({
  54.     builder: closePage({
  55.       onCancel: () => {
  56.         this.roleData = roleData
  57.         this.newRoleData = this.roleData
  58.         this.roleData.createUserID = this.userOwn.userID
  59.         this.roleData.createUserName = this.userOwn.userName
  60.         router.pushUrl({
  61.           "url": "pages/Main/userSpace",
  62.           "params": {
  63.             "goPageIndex" : 0
  64.           }
  65.         })
  66.       },
  67.     })
  68.   })
  69.   @StorageProp('frame') frameData: frame = frameDataSet
  70.   @StorageProp('fontColor') ThisColor: ResourceColor = ThisPagefontColor
  71.   @StorageProp('userOwnData') userOwn: userOwnData = userOwn
  72.   @StorageLink('roleData') roleData: roleDataTemplate = roleData
  73.   @State newRoleData: roleDataTemplate = this.roleData
  74.   @State openText: boolean = false
  75.   @State roleCustom: roleCustom[] = []
  76.   @State roleLabel: string[] = this.newRoleData.roleLabel
  77.   @State delRoleIndex: number = 0
  78.   loadRoleData(){
  79.     this.roleData = this.newRoleData
  80.     this.roleData.roleLabel = this.roleLabel
  81.     this.roleData.createUserID = this.userOwn.userID
  82.     this.roleData.createUserName = this.userOwn.userName
  83.     for (let index = 0; index < this.roleCustom.length; index++) {
  84.       this.roleData.roleCustomName.push(this.roleCustom[index].name)
  85.       this.roleData.roleCustomValue.push(this.roleCustom[index].value)
  86.     }
  87.     router.pushUrl({
  88.       "url": "pages/dynamicSystem/previewPage/userPreviewPage"
  89.     })
  90.   }
  91.   build() {
  92.     Flex({
  93.       wrap: FlexWrap.Wrap
  94.     }){
  95.       Column({ space: 24 }){
  96.         // 标题
  97.         Row(){
  98.           frameData()
  99.             .width(50)
  100.           Text('角色')
  101.             .fontSize(this.frameData.typefaceSize + 8)
  102.             .fontColor(this.ThisColor)
  103.           Text('')
  104.             .width(50)
  105.         }.width('100%')
  106.         .justifyContent(FlexAlign.SpaceBetween)
  107.         Scroll(){
  108.           Column({ space: 24 }){
  109.             // 封面标题作者标签ID
  110.             Row({space: 16}){
  111.               Text(String(this.newRoleData.roleName == '' ? '角色名称' : this.newRoleData.roleName).slice(String(this.newRoleData.roleName == '' ? '角色名称' : this.newRoleData.roleName).length - 2, String(this.newRoleData.roleName == '' ? '角色名称' : this.newRoleData.roleName).length))
  112.                 .fontSize(18)
  113.                 .width(120)
  114.                 .height(120)
  115.                 .borderRadius(60)
  116.                 .backgroundColor(this.frameData.backGround)
  117.                 .border({
  118.                   width: 1
  119.                 })
  120.                 .textOverflow({overflow: TextOverflow.Ellipsis})
  121.                 .padding(2)
  122.                 .textAlign(TextAlign.Center)
  123.                 .letterSpacing(3)
  124.               Column({ space: 9 }){
  125.                 // 角色昵称
  126.                 Row(){
  127.                   Text(this.newRoleData.roleName == '' ? '角色名称' : this.newRoleData.roleName)
  128.                     .fontSize(this.frameData.typefaceSize + 6)
  129.                     .fontColor(this.ThisColor)
  130.                     .fontWeight(600)
  131.                 }
  132.                 // ID
  133.                 Row(){
  134.                   Text(this.newRoleData.roleAge.toString())
  135.                     .fontSize(this.frameData.typefaceSize - 4)
  136.                     .fontColor(Color.Gray)
  137.                     .fontWeight(400)
  138.                 }
  139.                 // 作者
  140.                 Row({ space: 6 }){
  141.                   Text(String(this.userOwn.userName).slice(String(this.userOwn.userName).length - 2, String(this.userOwn.userName).length))
  142.                     .fontSize(8)
  143.                     .width(28)
  144.                     .height(28)
  145.                     .borderRadius(14)
  146.                     .backgroundColor(this.frameData.backGround)
  147.                     .border({
  148.                       width: 1
  149.                     })
  150.                     .textOverflow({overflow: TextOverflow.Ellipsis})
  151.                     .padding(2)
  152.                     .textAlign(TextAlign.Center)
  153.                   Text(this.userOwn.userName)
  154.                     .fontSize(this.frameData.typefaceSize - 2)
  155.                     .fontColor(Color.Gray)
  156.                 }
  157.                 // 标签
  158.                 Flex({
  159.                   wrap: FlexWrap.Wrap,
  160.                   justifyContent: FlexAlign.Start
  161.                 }){
  162.                   ForEach(this.roleLabel, (item: string) => {
  163.                     Text(item)
  164.                       .textCare(this.frameData.typefaceSize - 3)
  165.                       .margin({
  166.                         right: 2,
  167.                         bottom: 2
  168.                       })
  169.                   })
  170.                 }
  171.               }.width('100%')
  172.               .alignItems(HorizontalAlign.Start)
  173.               .height(120)
  174.             }
  175.             // 简介
  176.             Column({ space: 12 }){
  177.               Text('简介')
  178.                 .fontSize(this.frameData.typefaceSize + 4)
  179.                 .fontColor(this.ThisColor)
  180.                 .fontWeight(600)
  181.               Row(){
  182.                 Text(`${this.newRoleData.roleBrief}`)
  183.                   .maxLines(this.openText ? 999 : 4)
  184.                   .textOverflow({overflow: this.openText ? TextOverflow.None : TextOverflow.Ellipsis })
  185.                   .fontSize(this.frameData.typefaceSize)
  186.                   .fontColor(this.ThisColor)
  187.               }.width('100%')
  188.               Row(){
  189.                 Text(this.openText ? '收起' : '展开')
  190.                   .fontSize(this.frameData.typefaceSize - 2)
  191.                   .fontColor(this.ThisColor)
  192.                   .fontWeight(300)
  193.                   .onClick(() => {
  194.                     this.openText = !this.openText
  195.                   })
  196.               }.width('100%')
  197.             }.width('100%')
  198.             .alignItems(HorizontalAlign.Start)
  199.             // 详细档案
  200.             Column(){
  201.               Row(){
  202.                 Text('详细档案')
  203.                   .fontSize(this.frameData.typefaceSize + 4)
  204.                   .fontColor(this.ThisColor)
  205.                   .fontWeight(600)
  206.               }.width('100%')
  207.               .justifyContent(FlexAlign.SpaceBetween)
  208.               .border({
  209.                 width: {
  210.                   bottom: 2
  211.                 }
  212.               })
  213.               .padding({
  214.                 bottom: 6
  215.               })
  216.               // 详细档案中的档案
  217.               Column(){
  218.                 // 词条
  219.                 Column(){
  220.                   // 姓名
  221.                   Row(){
  222.                     Text('姓名:')
  223.                       .fontSize(this.frameData.typefaceSize + 2)
  224.                       .fontColor(this.ThisColor)
  225.                       .fontWeight(500)
  226.                     TextInput({ placeholder: this.newRoleData.roleName == '' ? '请输入角色姓名' : this.newRoleData.roleName })
  227.                       .width('100%')
  228.                       .backgroundColor(this.frameData.backGround)
  229.                       .borderRadius(0)
  230.                       .border({
  231.                         width:{
  232.                           bottom: 1
  233.                         },
  234.                         color: this.ThisColor
  235.                       })
  236.                       .fontColor(this.ThisColor)
  237.                       .placeholderColor(this.ThisColor)
  238.                       .fontSize(this.frameData.typefaceSize + 2)
  239.                       .maxLength(16)
  240.                       .onChange(value => {
  241.                         this.newRoleData.roleName = value
  242.                       })
  243.                   }.width('100%')
  244.                   .justifyContent(FlexAlign.SpaceBetween)
  245.                   .padding({
  246.                     left: 12,
  247.                     right: 12,
  248.                     top: 12,
  249.                     bottom: 12
  250.                   })
  251.                   // 年龄
  252.                   Row(){
  253.                     Text('年龄:')
  254.                       .fontSize(this.frameData.typefaceSize + 2)
  255.                       .fontColor(this.ThisColor)
  256.                       .fontWeight(500)
  257.                     TextInput({ placeholder: this.newRoleData.roleAge == '0' ? '请输入角色年龄' : this.newRoleData.roleAge.toString()})
  258.                       .width('100%')
  259.                       .backgroundColor(this.frameData.backGround)
  260.                       .borderRadius(0)
  261.                       .border({
  262.                         width:{
  263.                           bottom: 1
  264.                         },
  265.                         color: this.ThisColor
  266.                       })
  267.                       .fontColor(this.ThisColor)
  268.                       .placeholderColor(this.ThisColor)
  269.                       .fontSize(this.frameData.typefaceSize + 2)
  270.                       .maxLength(8)
  271.                       .type(InputType.Number)
  272.                       .onChange(value => {
  273.                         this.newRoleData.roleAge = value
  274.                       })
  275.                   }.width('100%')
  276.                   .justifyContent(FlexAlign.SpaceBetween)
  277.                   .padding({
  278.                     left: 12,
  279.                     right: 12,
  280.                     top: 12,
  281.                     bottom: 12
  282.                   })
  283.                   // 性别
  284.                   Row(){
  285.                     Text('性别:')
  286.                       .fontSize(this.frameData.typefaceSize + 2)
  287.                       .fontColor(this.ThisColor)
  288.                       .fontWeight(500)
  289.                     TextInput({ placeholder: this.newRoleData.roleGender == '' ? '请输入角色性别' : this.newRoleData.roleGender })
  290.                       .width('100%')
  291.                       .backgroundColor(this.frameData.backGround)
  292.                       .borderRadius(0)
  293.                       .border({
  294.                         width:{
  295.                           bottom: 1
  296.                         },
  297.                         color: this.ThisColor
  298.                       })
  299.                       .fontColor(this.ThisColor)
  300.                       .placeholderColor(this.ThisColor)
  301.                       .fontSize(this.frameData.typefaceSize + 2)
  302.                       .maxLength(6)
  303.                       .onChange(value => {
  304.                         this.newRoleData.roleGender = value
  305.                       })
  306.                   }.width('100%')
  307.                   .justifyContent(FlexAlign.SpaceBetween)
  308.                   .padding({
  309.                     left: 12,
  310.                     right: 12,
  311.                     top: 12,
  312.                     bottom: 12
  313.                   })
  314.                   ForEach(this.roleCustom, (item: roleCustom, index: number) => {
  315.                     // 姓名
  316.                     Row(){
  317.                       Text(item.name + ':')
  318.                         .fontSize(this.frameData.typefaceSize + 2)
  319.                         .fontColor(this.ThisColor)
  320.                         .fontWeight(500)
  321.                         .textAlign(TextAlign.End)
  322.                         .width('17%')
  323.                       Row(){
  324.                         TextInput({ placeholder: '请输入角色姓名', text: item.value })
  325.                           .width('71%')
  326.                           .backgroundColor(this.frameData.backGround)
  327.                           .borderRadius(0)
  328.                           .border({
  329.                             width:{
  330.                               bottom: 1
  331.                             },
  332.                             color: this.ThisColor
  333.                           })
  334.                           .fontColor(this.ThisColor)
  335.                           .placeholderColor(this.ThisColor)
  336.                           .fontSize(this.frameData.typefaceSize + 2)
  337.                           .maxLength(16)
  338.                         Text('删除')
  339.                           .onClick(() => {
  340.                             this.roleCustom.splice(index, 1)
  341.                           })
  342.                           .textAlign(TextAlign.End)
  343.                           .width(50)
  344.                       }
  345.                     }.width('100%')
  346.                     .justifyContent(FlexAlign.SpaceBetween)
  347.                     .padding({
  348.                       left: 12,
  349.                       right: 12,
  350.                       top: 12,
  351.                       bottom: 12
  352.                     })
  353.                   })
  354.                   Row(){
  355.                     Button('添加自定义词条')
  356.                       .border({
  357.                         width: 1
  358.                       })
  359.                       .backgroundColor(this.frameData.backGround)
  360.                       .fontColor(this.ThisColor)
  361.                       .width('100%')
  362.                       .onClick(() => {
  363.                         this.entryPageOpen.open()
  364.                       })
  365.                   }.width('100%')
  366.                   .padding({
  367.                     left: 12,
  368.                     right: 12,
  369.                     top: 12,
  370.                     bottom: 12
  371.                   })
  372.                 }
  373.                 // 标签
  374.                 Flex({
  375.                   wrap: FlexWrap.Wrap,
  376.                   justifyContent: FlexAlign.SpaceAround
  377.                 }){
  378.                   ForEach(this.roleLabel, (item: string, index) => {
  379.                     Row(){
  380.                       Button(item)
  381.                         .border({
  382.                           width: 1
  383.                         })
  384.                         .backgroundColor(this.frameData.backGround)
  385.                         .fontColor(this.ThisColor)
  386.                         .width('45%')
  387.                         .onClick(() => {
  388.                           this.delRoleIndex = index
  389.                           this.delcarePageOpen.open()
  390.                         })
  391.                     }.padding({
  392.                       left: 12,
  393.                       right: 12,
  394.                       top: 12,
  395.                       bottom: 12
  396.                     })
  397.                   })
  398.                   Row(){
  399.                     Button('添加角色标签')
  400.                       .border({
  401.                         width: 1
  402.                       })
  403.                       .backgroundColor(this.frameData.backGround)
  404.                       .fontColor(this.ThisColor)
  405.                       .width('45%')
  406.                       .onClick(() => {
  407.                         this.carePageOpen.open()
  408.                       })
  409.                   }.padding({
  410.                     left: 12,
  411.                     right: 12,
  412.                     top: 12,
  413.                     bottom: 12
  414.                   })
  415.                 }.width('100%')
  416.                 // 剧本
  417.                 Column({ space: 6 }){
  418.                   Row(){
  419.                     Text('角色简介:')
  420.                       .fontSize(this.frameData.typefaceSize + 4)
  421.                       .fontColor(this.ThisColor)
  422.                       .fontWeight(600)
  423.                   }.width('100%')
  424.                   .padding({
  425.                     bottom: 6
  426.                   })
  427.                   // 简介
  428.                   Row(){
  429.                     TextArea({ placeholder: '请输入角色简介'})
  430.                       .width('100%')
  431.                       .height(120)
  432.                       .padding(16)
  433.                       .fontSize(this.frameData.typefaceSize + 2)
  434.                       .fontColor(this.ThisColor)
  435.                       .fontWeight(500)
  436.                       .onChange(value => {
  437.                         this.newRoleData.roleBrief = value
  438.                       })
  439.                       .maxLength(200)
  440.                   }.width('100%')
  441.                 }
  442.               }
  443.             }.width('100%')
  444.             .alignItems(HorizontalAlign.Center)
  445.           }
  446.           .alignItems(HorizontalAlign.Start)
  447.         }.edgeEffect(EdgeEffect.Spring)
  448.         .scrollBar(BarState.Off)
  449.         .height('85%')
  450.         Row(){
  451.           Button('预览')
  452.             .fontSize(this.frameData.typefaceSize + 2)
  453.             .fontColor(this.ThisColor)
  454.             .backgroundColor(this.frameData.backGround)
  455.             .width('50%')
  456.             .padding({
  457.               top: 16,
  458.               bottom: 16
  459.             })
  460.             .onClick(() => {
  461.               this.loadRoleData()
  462.             })
  463.           Button('取消')
  464.             .fontSize(this.frameData.typefaceSize + 2)
  465.             .fontColor(this.ThisColor)
  466.             .backgroundColor(this.frameData.backGround)
  467.             .width('50%')
  468.             .padding({
  469.               top: 16,
  470.               bottom: 16
  471.             })
  472.             .onClick(() => {
  473.               this.closeOpen.open()
  474.             })
  475.         }
  476.         .width('100%')
  477.         .justifyContent(FlexAlign.SpaceAround)
  478.         .alignItems(VerticalAlign.Center)
  479.         .border({
  480.           width: {
  481.             top: 2
  482.           }
  483.         })
  484.       }
  485.       .padding({
  486.         top: 16,
  487.         left: 24,
  488.         right: 24,
  489.         bottom: 16
  490.       })
  491.       .height('100%')
  492.     }
  493.   }
  494. }复制
复制代码
5、总结

说书人APP是一款基于鸿蒙平台开发的原生应用,旨在通过角色定义的方式进步笔墨创作的服从与质量。
不仅弥补了市场上对话式文本类APP的空缺,而且通过华为端云一体化开发,接入了短信认证服务和云数据库,确保了应用的高兼容性、稳固性、低功耗和高性能。
项目配景与目标:随着市场上文本创作软件的增多,创作者面临的挑战也随之增加,尤其是对于经验不足的创作者而言,怎样有效管理角色和剧情成为一大难题。说书人APP应运而生,目的是帮助这些创作者通过“面向对象”的方式编写剧本,从而进步创作服从和作品质量。
技术实现:应用接纳了华为的端云一体化开发模式,利用DevEco Studio举行编译运行,并支持API version 9版本SDK,确保了应用的技术先进性和安全性。
功能特色:包括注册登录系统、文章创建与编辑、章节管理、角色创建与自定义、以及用户个性化设置等,全面满意笔墨创作者的需求。特别是其基于角色的对话式编写功能,为创作者提供了全新的创作体验。
上风方面
技术创新:作为鸿蒙平台上的原生应用,说书人APP在技术上具有天然的上风,包括更好的系统兼容性和性能优化。 用户体验:通过角色定义的创作方式,简化了复杂的剧情管理,使得创作者可以更加专注于内容的创作。
生态贡献:加入鸿蒙生态建设,不仅丰富了应用市场的多样性,也为国产科技企业的发展贡献了一份气力。
需要改进的地方
用户引导:对于新用户来说,应用的功能大概较为复杂,需要更加直观的用户引导和教程来帮助用户快速上手。
社交互动:虽然应用提供了丰富的创作工具,但在社交互动方面似乎有所欠缺。增加创作者之间的交流和合作功能,大概会进一步提升用户的活泼度和粘性。
持续优化:任何应用都需要根据用户反馈举行持续优化。说书人APP也不例外,需要不断网络用户意见,对功能、界面和性能举行迭代升级。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

北冰洋以北

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表