HarmonyOS Next“说书人”项目 单机版 实践案例

前段时间开发了一个软件,取名为“说书人”,后由于备案暂时没有通过,于是删除了联网功能,重新做了一个单机版,这里对于单机版的开发实践案例进行一个发出,希望能帮助到大家

文章最后给出了AtomGit仓库地址

pages/Data 目录

此目录下存储了项目中会使用到的数据

AppData.ets

此处存储了应用的版本号信息

export interface appAloneDataTem {appName: string,appVersion: string,appLogin: boolean
}export let appAloneData: appAloneDataTem = {appName: '说书人',appVersion: 'V 1.0.0',appLogin: false
}PersistentStorage.persistProp('appData', appAloneData)复制

bookData.ets

此处存储了书本信息

export interface bookDataTemplate{bookID: number,bookName: string,bookBrief: string,// bookHead: string,bookLabel: string[],// 发布状态:真为公有,假为私有releaseState: boolean,createUserID: number,createUserName: string,createUserOpen: boolean,haveRoleID: string[],chapterIndex: string
}export let bookData: bookDataTemplate = {bookID: 0,bookName: '',bookBrief: '简介',// bookHead: "",bookLabel: [],releaseState: false,createUserID: 0,createUserName: '未知用户',createUserOpen: true,haveRoleID: [],chapterIndex: "0",
}export let bookDataList: bookDataTemplate[] = [{bookID: 0,bookName: '开幕',bookBrief: '《说书人》的第一幕',// bookHead: "",bookLabel: [],releaseState: false,createUserID: 0,createUserName: '未知用户',createUserOpen: true,haveRoleID: [],chapterIndex: "0",}
]PersistentStorage.persistProp('bookData', bookData)
PersistentStorage.persistProp('bookDataList', bookDataList)复制

frameData.ets

此处存储了项目所需要使用到的一些设置信息,以及公有的组件

import router from '@ohos.router';// 画面设置
export interface frame{typefaceSize: number,backGround: ResourceColor,
}export let frameDataSet: frame = {typefaceSize: 16,backGround: "#ffffff",
}// 颜色加法
export let ThisPagefontColor: ResourceColor ='#' +setTenSix(frameDataSet.backGround.toString().slice(1,3)) +setTenSix(frameDataSet.backGround.toString().slice(3,5)) +setTenSix(frameDataSet.backGround.toString().slice(5,7))// 十进制转十六进制
function setTenSix(Color: string){let colorData = (255 - parseInt('0x' + Color.toString()))return colorData <= 15 ? '0' + colorData.toString(16) : colorData.toString(16)
}PersistentStorage.persistProp('frame', frameDataSet)PersistentStorage.persistProp('fontColor', ThisPagefontColor)@Component
export struct frameData {@StorageProp('frame')  frameData: frame = frameDataSet@StorageProp('fontColor') ThisColor: ResourceColor = ThisPagefontColorbuild() {Text('Back').fontColor(this.ThisColor).fontSize(this.frameData.typefaceSize + 6).onClick(() => {router.back()})}
}复制
readBookCharpter.ets

此处存储了章节信息

// 章节信息
export interface readBookCharpterTemplate{// 章节IDarticleID: number,// 章节索引chapterIndex: string,// 章节内容dialogueList: string,// 造物者之IDcreateUserID: string,// 归属之书ascriptionBookID: number,
}export let readBookCharpterData: readBookCharpterTemplate = {articleID: 0,chapterIndex: "1-1",dialogueList: "",createUserID: "",ascriptionBookID: 0
}export let readBookCharpterDataList: readBookCharpterTemplate[] = [{articleID: 0,chapterIndex: "1-1",dialogueList: "left|官方001|大家好!,left|官方001|欢迎使用《说书人》APP,它是一款面向角色编写剧本的软件 ,left|官方001|你可以在这款软件中定义角色,为多个角色之间编写剧本,还可以编写角色的关系网,查看角色的时间线等等... ,left|官方001|虽然在“还可以”之后的功能都还没实现就是了 ,left|官方001|截止编写本幕为止,软件只完成了基本功能,还有相当多不完善的地方,都会在为了慢慢解决的 ,left|官方001|十分感谢您对《说书人》的使用,如果使用过程中存在什么意见或建议,可以添加客服QQ提出 ,left|官方001|客服QQ: 1827650871",createUserID: "",ascriptionBookID: 0}
]PersistentStorage.persistProp('readBookCharpterData', readBookCharpterData)
PersistentStorage.persistProp('readBookCharpterDataList', readBookCharpterDataList)复制

roleData.ets

此处存储了角色会使用的数据


export interface roleCustom{name: string,value: string
}export interface roleDataTemplate{roleID: number,roleName: string,roleAge: string,roleGender: string,roleBrief: string,roleHead: string,roleLabel: string[],roleCustom: roleCustom[],// 发布状态:真为公有,假为私有releaseState: boolean,// 创造他的用户createUserID: number,createUserName: string,// 用户是否公开createUserOpen: boolean,// 有关系的角色和出现过的书籍relevantRoleID: string[],relevantBookID: string[]
}export let roleData: roleDataTemplate = {roleID: 0,roleName: '',roleAge: '0',roleGender: '',roleBrief: '简介',roleHead: "",roleLabel: [],roleCustom: [],releaseState: false,createUserID: 0,createUserName: "未知用户",createUserOpen: true,relevantRoleID: [],relevantBookID: []
}export let roleDataList: roleDataTemplate[] = [{roleID: 0,roleName: '官方001',roleAge: '18',roleGender: '男',roleBrief: '一个勤劳的打工人',roleHead: "",roleLabel: [],roleCustom: [],releaseState: false,createUserID: 0,createUserName: "未知用户",createUserOpen: true,relevantRoleID: [],relevantBookID: []},
]PersistentStorage.persistProp('roleData', roleData)
PersistentStorage.persistProp('roleDataList', roleDataList)复制
inspirationTem.ets
export interface inspirationTem {inspirationID: number,inspirationTitle: string,inspirationMain: string
}export let inspirationData: inspirationTem = {inspirationID: 0,inspirationTitle: '标题',inspirationMain: '正文'
}export let inspirationDataList: inspirationTem[] = [{inspirationID: 0,inspirationTitle: '标题',inspirationMain: '正文'}
]PersistentStorage.persistProp('inspirationData', inspirationData)
PersistentStorage.persistProp('inspirationDataList', inspirationDataList)复制

以上,便是整个应用所使用的数据信息,使用持久化存储将数据存储在本地

接下来,便是主要页面

pages/index.ets

import router from '@ohos.router'
import { frame, frameDataSet,ThisPagefontColor } from './Data/frameData'
import { userOwnData, userOwn } from './Data/userData'import promptAction from '@ohos.promptAction';@Entry
@Component
struct Index {@StorageProp('frame') frameData: frame = frameDataSet@StorageProp('fontColor') ThisColor: ResourceColor = ThisPagefontColor@StorageLink('userOwnData') userOwn: userOwnData = userOwn@State indexTime: number = 0onPageShow(): void {promptAction.showToast({message: "欢迎使用说书人"})this.indexTime = setTimeout(() => {router.clear()router.replaceUrl({"url":"pages/Main/userSpace","params": {"goPageIndex" : 0}})promptAction.showToast({message: '登陆成功!'})}, 3000)}build() {Flex({justifyContent: FlexAlign.Center}){}.width('100%').height('100%').backgroundImage($r('app.media.fengmian')).backgroundImageSize(ImageSize.Cover).backgroundColor(this.frameData.backGround).expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM]).onClick(() => {clearTimeout(this.indexTime)router.clear()router.replaceUrl({"url":"pages/Main/userSpace","params": {"goPageIndex" : 0}})promptAction.showToast({message: '登陆成功!'})})}
}复制

pages/loginPOP.ets

import { frame, frameDataSet,ThisPagefontColor, frameData } from './Data/frameData'
import router from '@ohos.router';@CustomDialog
export default struct agreePage {agreePage: CustomDialogControlleronCancel: () => void = () => {}onJUJUE: () => void = () => {}@StorageProp('frame') frameData: frame = frameDataSet@StorageProp('fontColor') ThisColor: ResourceColor = ThisPagefontColorbuild() {/* 用户名和需要修改的参数都由外部传递此处只涉及数据修改任务*/Flex(){Column({space: 16}){Row(){Text('《用户协议》与《隐私政策》提示').fontSize(this.frameData.typefaceSize + 4).fontColor(this.ThisColor)}.width('100%').justifyContent(FlexAlign.Center).padding({top: 24,left: 24})Scroll(){Column({ space: 12 }){Text(`
您需要阅读并同意隐私政策和用户协议后,才能使用《说书人》软件。如果您不同意,很遗憾我们无法为您提供相关服务。`).fontColor(this.ThisColor).fontSize(this.frameData.typefaceSize + 2)Flex({wrap: FlexWrap.Wrap}){Text('您可以点击阅读').fontColor(this.ThisColor).fontSize(this.frameData.typefaceSize + 2)Text(`《用户协议》`).fontColor(`#4a90e2`).fontSize(this.frameData.typefaceSize + 2).onClick(() => {router.pushUrl({url: "pages/agreement/userAgreememt"})this.agreePage.close()})Text(`与`).fontColor(this.ThisColor).fontSize(this.frameData.typefaceSize + 2)Text(`《隐私政策》`).fontColor(`#4a90e2`).fontSize(this.frameData.typefaceSize + 2).onClick(() => {router.pushUrl({url: "pages/agreement/privacyAgreement"})this.agreePage.close()})Text(`了解相关信息。`).fontColor(this.ThisColor).fontSize(this.frameData.typefaceSize + 2)Text(`如您同意,请点击“同意”开始接受我们的服务。`).fontColor(this.ThisColor).fontSize(this.frameData.typefaceSize + 2)}.width('100%')}.padding({left: 24,right: 24})}.edgeEffect(EdgeEffect.Spring)Row(){Button('同意 ').type(ButtonType.Normal).backgroundColor(this.frameData.backGround).fontSize(this.frameData.typefaceSize + 2).fontColor(this.ThisColor).border({width: {left: 1,right: 1,bottom: 1},color: '#f4f6f5'}).width('50%').onClick(() => {this.onCancel()this.agreePage.close()})Button('拒绝').type(ButtonType.Normal).backgroundColor(this.frameData.backGround).fontSize(this.frameData.typefaceSize + 2).fontColor(this.ThisColor).border({width: {left: 1,right: 1,bottom: 1},color: '#f4f6f5'}).width('50%').onClick(() => {this.onJUJUE()this.agreePage.close()})}}}.backgroundColor(this.frameData.backGround)}
}复制

pages/Main

以下是Main目录中的文件,此处存储了主要界面

userSpace.ets

import { frame, frameDataSet, ThisPagefontColor } from '../Data/frameData'import scriptInterface from './mainPage/scriptPage'
import RelationshipPage from './mainPage/relationshipPage'@Entry
@Component
struct UserSpace {@StorageProp('frame') frameData: frame = frameDataSet@StorageProp('fontColor') ThisColor: ResourceColor = ThisPagefontColorbuild() {Flex(){Tabs(){TabContent(){scriptInterface()}.tabBar('首页')TabContent(){RelationshipPage()}.tabBar('灵感')}.barPosition(BarPosition.End)}.backgroundColor(this.frameData.backGround)}
}复制

pages/Main/mainPage/scriptPage.ets

import { frame, frameDataSet,ThisPagefontColor } from '../../Data/frameData'
import { router } from '@kit.ArkUI'
import { roleDataList, roleDataTemplate, } from '../../Data/roleData'import { standardCudeImage } from '../../template/textImgTemplate'
import { bookDataList, bookDataTemplate } from '../../Data/bookData'
import { it } from '@ohos/hypium'@Entry
@Component
export default struct scriptInterface {@StorageProp('frame') frameData: frame = frameDataSet@StorageProp('fontColor') ThisColor: ResourceColor = ThisPagefontColor@StorageProp('roleDataList') roleDataList: roleDataTemplate[]  = roleDataList@StorageProp('bookDataList') bookDataList: bookDataTemplate[] = bookDataList@State openSet: boolean = false@State ThisText: string = ''@State sw:number = 0@State sh:number = 0build() {Flex(){Stack({alignContent: Alignment.Top}){Column(){Row(){TextInput({placeholder: "搜索"}).width('90%').textAlign(TextAlign.Center).onChange(value => {this.ThisText = value})Text('+').fontSize(32).width(50).textAlign(TextAlign.Center)}.width('100%').justifyContent(FlexAlign.SpaceBetween).onClick(() => {this.openSet = !this.openSet})Tabs(){// 角色TabContent(){Scroll(){Column({ space: 16 }){ForEach(this.roleDataList, (item: roleDataTemplate, index) => {if (item.roleName.includes(this.ThisText) || item.roleID.toString().includes(this.ThisText)) {// 角色模板Row({space: 16}){Text(`${item.roleName}`).fontSize(16).width(90).height(120).borderRadius(16).backgroundColor(this.frameData.backGround).border({width: 1}).borderRadius(16).textOverflow({overflow: TextOverflow.Ellipsis}).padding(16).textAlign(TextAlign.Center)Column({ space: 6 }){Row(){Text(`${item.roleName}`).fontSize(this.frameData.typefaceSize + 4).fontColor(this.ThisColor).fontWeight(600)}Row(){Text(`${item.roleBrief}`).fontSize(this.frameData.typefaceSize - 2).fontColor(this.ThisColor).maxLines(2).textOverflow({overflow: TextOverflow.Ellipsis})}.width('70%')Row(){ForEach(item.roleLabel, (item: string) => {Text(`/ ${item} /`).fontSize(this.frameData.typefaceSize - 4).fontColor(this.ThisColor).fontWeight(200)})}}.width('100%').alignItems(HorizontalAlign.Start)}.onClick(() => {router.pushUrl({"url": "pages/userSystem/userDetailed","params": {"roleID": item.roleID}})})}})}}.height('100%').align(Alignment.Top).edgeEffect(EdgeEffect.Spring).padding({top: 12,bottom: 64})}.tabBar('角色')// 剧本TabContent(){Scroll(){// 剧本列表Column({ space: 16 }){ForEach(this.bookDataList, (item: bookDataTemplate, index) => {if (item.bookName.includes(this.ThisText) || item.bookID.toString().includes(this.ThisText)) {// 剧本模板Row({space: 16}){Column({ space: 6 }){Row(){Text(item.bookName).fontSize(this.frameData.typefaceSize + 4).fontColor(this.ThisColor).fontWeight(600)}.width('70%').justifyContent(FlexAlign.End)Row(){Text(item.bookBrief).fontSize(this.frameData.typefaceSize - 2).fontColor(this.ThisColor).maxLines(2).textOverflow({overflow: TextOverflow.Ellipsis}).textAlign(TextAlign.End)}.width('70%').justifyContent(FlexAlign.End)Row(){/* 感觉很酷的一串代码 */ForEach(item.bookLabel, (item: string) => {Text(`/ ${item} /`).fontSize(this.frameData.typefaceSize - 4).fontColor(this.ThisColor).fontWeight(200).textAlign(TextAlign.End)})}.width('70%').justifyContent(FlexAlign.End)}.alignItems(HorizontalAlign.Start)standardCudeImage(`${item.bookName}`, this.frameData.backGround, this.ThisColor)}.onClick(() => {router.pushUrl({url: "pages/scriptSystem/scriptDetailed",params: {"bookID": item.bookID,"collection": false}})})}})}}.height('100%').align(Alignment.Top).edgeEffect(EdgeEffect.Spring).padding({top: 12,bottom: 64})}.tabBar('剧本')}.barPosition(BarPosition.Start)}.padding({left: 24,right: 24,}).align(Alignment.Top).alignItems(HorizontalAlign.Start)// 阴影Column(){}.width('100%').height('100%').backgroundColor(Color.Black).opacity(.6).visibility(this.openSet ? Visibility.Visible : Visibility.None).onClick(() => {this.openSet = false})// 角色剧本动态Column(){Row(){Text('角色').fontSize(this.frameData.typefaceSize + 2).fontColor(this.ThisColor)}.width(160).justifyContent(FlexAlign.Center).padding({left: 24,right: 24,top: 16,bottom: 16}).border({width: {bottom: 1}}).onClick(() => {router.pushUrl({"url": "pages/CreatePage/userCreate"})this.openSet = false})Row(){Text('剧本').fontSize(this.frameData.typefaceSize + 2).fontColor(this.ThisColor)}.width(160).justifyContent(FlexAlign.Center).padding({left: 24,right: 24,top: 16,bottom: 16}).border({width: {bottom: 1}}).onClick(() => {router.pushUrl({"url": "pages/CreatePage/scriptCreate"})this.openSet = false})}.border({ width: 1 }).borderRadius(2).position({x: this.sw / 2 - 16,y: 36}).backgroundColor(Color.White).visibility(this.openSet ? Visibility.Visible : Visibility.None)}}.backgroundColor(this.frameData.backGround).onAreaChange((oldValue: Area, newValue: Area) => {this.sw = new Number(newValue.width).valueOf();this.sh = new Number(newValue.height).valueOf();});}
}复制

pages/Main/mainPage/relationshipPage

import { frame, frameDataSet,ThisPagefontColor } from '../../Data/frameData'
import { inspirationTem, inspirationData, inspirationDataList } from '../../Data/inspirationData'
import { promptAction } from '@kit.ArkUI'@Entry
@Component
export default struct RelationshipPage {@StorageProp('frame') frameData: frame = frameDataSet@StorageProp('fontColor') ThisColor: ResourceColor = ThisPagefontColor@StorageLink('inspirationData') inspirationData: inspirationTem = inspirationData@StorageLink('inspirationDataList') inspirationDataList: inspirationTem[] = inspirationDataList@State index: number = 0build() {Flex({justifyContent: FlexAlign.Center,wrap: FlexWrap.Wrap}){Column(){// 标题Row(){Text('灵感图谱').fontSize(this.frameData.typefaceSize + 6).fontColor(this.ThisColor).letterSpacing(6)}.padding({top: 12, bottom: 12}).width('100%').justifyContent(FlexAlign.Center).border({width: {bottom: 2}})// 正文Column(){Row(){TextInput({ placeholder: "标题", text: this.inspirationDataList[this.index].inspirationTitle }).fontWeight(600).fontSize(this.frameData.typefaceSize + 14).placeholderFont({size: this.frameData.typefaceSize + 14}).fontColor(this.ThisColor).maxLength(16).showUnderline(true).onChange(value => {this.inspirationDataList[this.index].inspirationTitle = value})}.padding(24)Scroll(){Column(){TextArea({placeholder: '在此输入内容', text: this.inspirationDataList[this.index].inspirationMain}).backgroundColor(this.frameData.backGround).borderRadius(12).height('100%').maxLength(600).border({width: 1}).fontSize(this.frameData.typefaceSize + 2).onChange(value => {this.inspirationDataList[this.index].inspirationMain = value})}.padding({left: 24, right: 24})}.edgeEffect(EdgeEffect.Spring).height('70%').width('100%').align(Alignment.Top)}.width('100%').alignItems(HorizontalAlign.Start)// 按钮Row(){Button('上一篇').fontSize(this.frameData.typefaceSize + 6).fontColor(this.ThisColor).backgroundColor(this.frameData.backGround).layoutWeight(1).onClick(() => {if (this.index != 0) {this.index -= 1} else {promptAction.showToast({message: "已到达第一篇"})}})Button('下一篇').fontSize(this.frameData.typefaceSize + 6).fontColor(this.ThisColor).backgroundColor(this.frameData.backGround).layoutWeight(1).onClick(() => {if (this.index == this.inspirationDataList.length - 1) {if (this.inspirationDataList[this.index].inspirationTitle != '标题' ||this.inspirationDataList[this.index].inspirationMain != '正文') {this.inspirationDataList.push({inspirationID: this.index,inspirationTitle: '标题',inspirationMain: '正文'})this.index ++} else {promptAction.showToast({message: "已到达最后一篇"})}} else {this.index ++}})}.height('10%').width('100%').justifyContent(FlexAlign.SpaceBetween)}}}
}复制

pages/userSystem/

以下是pages/userSystem/中的内容,存储了角色系统

userDetailed.ets

import { frame, frameDataSet,ThisPagefontColor, frameData } from '../Data/frameData'
import { roleDataTemplate, roleData, roleDataList } from '../Data/roleData'
import { promptAction, router } from '@kit.ArkUI'
import { standardCudeImage } from '../template/textImgTemplate'@Extend(Text) function textCare(size: number){.fontColor('#3c3f41').backgroundColor('#e0dcda').fontSize(size).fontWeight(300).padding({left: 8,right: 8,top: 5,bottom: 5}).borderRadius(12).opacity(.8)
}@Entry
@Component
struct UserDetailed {aboutToAppear(): void {let params = router.getParams() as Record<string, number>let roleID = params['roleID']for (let item of this.roleDataList) {if (item.roleID == roleID) {this.roleData = itembreak}}}@StorageProp('frame') frameData: frame = frameDataSet@StorageProp('fontColor') ThisColor: ResourceColor = ThisPagefontColor@StorageProp('roleDataList') roleDataList: roleDataTemplate[] = roleDataList@State roleData: roleDataTemplate = roleData@State openText: boolean = falsebuild() {Flex({wrap: FlexWrap.Wrap}){Column({ space: 24 }){// 标题Row(){Row(){Text('Back').fontColor(this.ThisColor).fontSize(this.frameData.typefaceSize + 6).onClick(() => {router.back()}).width(100)}Text(this.roleData.roleName).fontSize(this.frameData.typefaceSize + 8).fontColor(this.ThisColor)Text('').width(100).textAlign(TextAlign.End)}.width('100%').justifyContent(FlexAlign.SpaceBetween)Scroll(){Column({ space: 24 }){Row({space: 16}){Text(this.roleData.roleName).fontSize(24).width(120).height(120).borderRadius(60).backgroundColor(this.frameData.backGround).border({width: 1}).textOverflow({overflow: TextOverflow.Ellipsis}).padding(2).textAlign(TextAlign.Center).letterSpacing(3)Column({ space: 9 }){// 书名Row(){Text(this.roleData.roleName).fontSize(this.frameData.typefaceSize + 6).fontColor(this.ThisColor).fontWeight(600)}// IDRow(){Text(String(this.roleData.roleID)).fontSize(this.frameData.typefaceSize - 4).fontColor(Color.Gray).fontWeight(400)}// 标签Row({ space: 6 }){ForEach(this.roleData.roleLabel, (item: string) => {Text(item).textCare(this.frameData.typefaceSize - 3)})}}.width('100%').alignItems(HorizontalAlign.Start).height(120)}// 简介Column({ space: 12 }){Text('简介').fontSize(this.frameData.typefaceSize + 4).fontColor(this.ThisColor).fontWeight(600)Row(){Text(this.roleData.roleBrief).maxLines(this.openText ? 999 : 4).textOverflow({overflow: this.openText ? TextOverflow.None : TextOverflow.Ellipsis }).fontSize(this.frameData.typefaceSize).fontColor(this.ThisColor)}.width('100%')Row(){Text(this.openText ? '收起' : '展开').fontSize(this.frameData.typefaceSize - 2).fontColor(this.ThisColor).fontWeight(300).onClick(() => {this.openText = !this.openText})}.width('100%')}.width('100%').alignItems(HorizontalAlign.Start)}.alignItems(HorizontalAlign.Start).height('100%')}.edgeEffect(EdgeEffect.Spring).height('87%')// 目录开始阅读收藏Row(){Text('').width(50)Text('解锁详细档案').fontSize(this.frameData.typefaceSize + 2).fontColor(this.ThisColor).onClick(() => {router.pushUrl({"url": "pages/userSystem/userPages/userArchives","params": {"roleID": this.roleData.roleID}})})Text('').width(50)}.width('100%').justifyContent(FlexAlign.SpaceBetween).alignItems(VerticalAlign.Center).border({width: {top: 2}}).padding({top: 16})}.padding({top: 16,left: 24,right: 24,bottom: 16})}.height('100%')}
}复制

pages/userSystem/userPages

import { frame, frameDataSet,ThisPagefontColor, frameData } from '../../Data/frameData'
import { roleDataTemplate, roleData, roleDataList, roleCustom } from '../../Data/roleData'
import { standardCudeImage } from '../../template/textImgTemplate'
import router from '@ohos.router';@Entry
@Component
struct UserArchives {aboutToAppear(): void {let params = router.getParams() as Record<string, number>let roleID = params['roleID']for (let item of this.roleDataList) {if (item.roleID == roleID) {this.roleData = itembreak}}}@StorageProp('frame') frameData: frame = frameDataSet@StorageProp('fontColor') ThisColor: ResourceColor = ThisPagefontColor@StorageProp('roleDataList') roleDataList: roleDataTemplate[] = roleDataList@State roleData: roleDataTemplate = roleData@State sw: number = 0@State sh: number = 0build() {Flex(){Scroll(){Column({ space: 12 }){// 标题Row(){frameData().width(50)Text(this.roleData.roleName).fontSize(this.frameData.typefaceSize + 8).fontColor(this.ThisColor)Text('详细档案').width(50).fontSize(this.frameData.typefaceSize + 6).fontColor(this.ThisColor)}.width('100%').justifyContent(FlexAlign.SpaceBetween).border({width: {bottom: 2}}).padding({top: 16,left: 24,right: 24,bottom: 16})Column({ space: 24 }){Stack(){Column({ space: 12 }){Row(){Text('姓名:').fontSize(this.frameData.typefaceSize + 2).fontColor(this.ThisColor)Text(this.roleData.roleName).fontSize(this.frameData.typefaceSize + 2).fontColor(this.ThisColor)}.width('100%').justifyContent(FlexAlign.SpaceBetween).margin({top: 42}).padding({left: 16,right: 16,top: 16,bottom: 6}).border({width: {bottom: 1}})Row(){Text('性别:').fontSize(this.frameData.typefaceSize + 2).fontColor(this.ThisColor)Text(this.roleData.roleGender).fontSize(this.frameData.typefaceSize + 2).fontColor(this.ThisColor)}.width('100%').justifyContent(FlexAlign.SpaceBetween).padding({left: 16,right: 16,top: 16,bottom: 6}).border({width: {bottom: 1}})Row(){Text('年龄:').fontSize(this.frameData.typefaceSize + 2).fontColor(this.ThisColor)Text(this.roleData.roleAge).fontSize(this.frameData.typefaceSize + 2).fontColor(this.ThisColor)}.width('100%').justifyContent(FlexAlign.SpaceBetween).padding({left: 16,right: 16,top: 16,bottom: 6}).border({width: {bottom: 1}})ForEach(this.roleData.roleCustom, (item: roleCustom, index) => {Row(){Text(`${item.name}: `).fontSize(this.frameData.typefaceSize + 2).fontColor(this.ThisColor)Text(`${item.value}`).fontSize(this.frameData.typefaceSize + 2).fontColor(this.ThisColor)}.width('100%').justifyContent(FlexAlign.SpaceBetween).padding({left: 16,right: 16,top: 16,bottom: 6}).border({width: {bottom: 1}})})Row(){Text('简介:').fontSize(this.frameData.typefaceSize + 2).fontColor(this.ThisColor)Text(`${this.roleData.roleBrief}`).fontSize(this.frameData.typefaceSize - 2).fontColor(this.ThisColor).width('70%').textAlign(TextAlign.End)}.width('100%').justifyContent(FlexAlign.SpaceBetween).padding({left: 16,right: 16,top: 16,bottom: 6}).border({width: {bottom: 1}})}.border({width: 1}).borderRadius(16).padding(16)Text(this.roleData.roleName).fontSize(18).width(90).height(90).borderRadius(45).backgroundColor(this.frameData.backGround).border({width: 1}).textOverflow({overflow: TextOverflow.Ellipsis}).padding(2).textAlign(TextAlign.Center).letterSpacing(3).position({x: this.sw / 2 - 64,y: -46})}.margin({top: 46})}.alignItems(HorizontalAlign.Center).padding({left: 24,right: 24,top: 10,bottom: 10})}}.edgeEffect(EdgeEffect.Spring)}.onAreaChange((oldValue: Area, newValue: Area) => {this.sw = new Number(newValue.width).valueOf();this.sh = new Number(newValue.height).valueOf();});}
}复制

pages/scriptSystem/

以下是pages/scriptSystem/中的内容,存储了剧本系统

import { frame, frameDataSet,ThisPagefontColor, frameData } from '../Data/frameData'
import router from '@ohos.router'
import { bookDataTemplate, bookData, bookDataList } from '../Data/bookData'
import { standardCudeImage } from '../template/textImgTemplate'@Extend(Text) function textCare(size: number){.fontColor('#3c3f41').backgroundColor('#e0dcda').fontSize(size).fontWeight(300).padding({left: 8,right: 8,top: 5,bottom: 5}).borderRadius(12).opacity(.8)
}@Entry
@Component
struct ScriptDetailed {aboutToAppear(): void {let params = router.getParams() as Record<string, number>let bookID = params['bookID']for (let i = 0; i < this.bookDataList.length; i++) {if (this.bookDataList[i].bookID == bookID) {this.bookData = this.bookDataList[i]break}}}@StorageProp('frame') frameData: frame = frameDataSet@StorageProp('fontColor') ThisColor: ResourceColor = ThisPagefontColor@StorageProp('bookDataList') bookDataList: bookDataTemplate[] = bookDataList@State bookData: bookDataTemplate = bookData@State openText: boolean = falsebuild() {Flex({wrap: FlexWrap.Wrap}){Column({ space: 24 }){// 标题Row(){Row(){frameData()}.width(50)Text(this.bookData.bookName).fontSize(this.frameData.typefaceSize + 8).fontColor(this.ThisColor).maxLines(1)Row(){Text('')}.width(50).justifyContent(FlexAlign.Start)}.width('100%').justifyContent(FlexAlign.SpaceBetween)Scroll(){Column({ space: 24 }){// 封面标题作者标签IDRow({space: 16}){standardCudeImage(this.bookData.bookName, this.frameData.backGround, this.ThisColor)Column({ space: 9 }){// 书名Row(){Text(this.bookData.bookName).fontSize(this.frameData.typefaceSize + 6).fontColor(this.ThisColor).fontWeight(600)}// IDRow(){Text(this.bookData.bookID.toString()).fontSize(this.frameData.typefaceSize - 4).fontColor(Color.Gray).fontWeight(400)}// 标签Row({ space: 6 }){ForEach(this.bookData.bookLabel, (item: string) => {Text(item).textCare(this.frameData.typefaceSize - 3)})}}.width('100%').alignItems(HorizontalAlign.Start).height(120)}// 简介Column({ space: 12 }){Text('简介').fontSize(this.frameData.typefaceSize + 4).fontColor(this.ThisColor).fontWeight(600)Row(){Text(this.bookData.bookBrief).maxLines(this.openText ? 999 : 4).textOverflow({overflow: this.openText ? TextOverflow.None : TextOverflow.Ellipsis }).fontSize(this.frameData.typefaceSize).fontColor(this.ThisColor)}.width('100%')Row(){Text(this.openText ? '收起' : '展开').fontSize(this.frameData.typefaceSize - 2).fontColor(this.ThisColor).fontWeight(300).onClick(() => {this.openText = !this.openText})}.width('100%')}.width('100%').alignItems(HorizontalAlign.Start)}.alignItems(HorizontalAlign.Start).height('100%')}.edgeEffect(EdgeEffect.Spring).height('87%')// 目录开始阅读收藏Row(){Text('').fontSize(this.frameData.typefaceSize + 2).fontColor(this.ThisColor).width(100)Text('开始阅读').fontSize(this.frameData.typefaceSize + 2).fontColor(this.ThisColor).onClick(() => {router.pushUrl({"url": "pages/scriptSystem/scriptPages/scriptRead","params": {"bookID": this.bookData.bookID,"chapterIndex": 1,}})})Text('').fontSize(this.frameData.typefaceSize + 2).fontColor(this.ThisColor).width(100)}.width('100%').justifyContent(FlexAlign.SpaceBetween).alignItems(VerticalAlign.Center).border({width: {top: 2}}).padding({top: 16})}.padding({top: 16,left: 24,right: 24,bottom: 16})}.height('100%')}
}复制

pages/scriptSystem/scriptPages/scriptRead.ets

import { frame, frameDataSet,ThisPagefontColor, frameData } from '../../Data/frameData'
import { readBookCharpterTemplate, readBookCharpterDataList, readBookCharpterData } from '../../Data/readBookChapterData'
import { smallImage } from '../../template/textImgTemplate'
import { delPage } from './popUp/del'
import { editTextPage } from './popUp/editText'import router from '@ohos.router';
import promptAction from '@ohos.promptAction'
import { roleDataTemplate } from '../../Data/roleData'@Extend(Text) function textCare(size: number){.padding({left: 12,right: 12,top: 16,bottom: 12}).fontSize(size).fontColor(Color.Black)
}@Entry
@Component
struct ScriptRead {// 删除文字delPageOpen: CustomDialogController = new CustomDialogController({builder: delPage({onCancel: (value: boolean) => {if (value) {this.dialogueListNew.splice(this.delIndex, 1)this.displayList[this.displayIndex] = false}}})})// 添加文字editTextPageOpen: CustomDialogController = new CustomDialogController({builder: editTextPage({onCancel: (careValue: number ,text: string ,returnRole: roleDataTemplate, newData: boolean) => {let textValue: string = ''for (let i = 0; i < text.length; i++) {if (text[i] == ','){textValue += ','} else if (text[i] == '|') {textValue += '/'} else {textValue += text[i]}}let dialogue: string[] = []/* 如果是旁白,就不需要角色昵称 */if (careValue != 2){if (careValue == 1) {dialogue[0] = 'left'} else if(careValue == 3) {dialogue[0] = 'right'}dialogue[1] = returnRole.roleName} else {dialogue[0] = 'pb'dialogue[1] = 'pb'}dialogue[2] = textValuethis.dialogueListNew.push(dialogue)this.displayList.push(true)this.scorllData.scrollBy(0, 10000)}}),})scorllData: Scroller = new Scroller()@StorageProp('frame') frameData: frame = frameDataSet@StorageProp('fontColor') ThisColor: ResourceColor = ThisPagefontColor@StorageLink('readBookCharpterDataList') readBookList: readBookCharpterTemplate[] = []@State index: number = 1@State bookLength: number = 0@State dialogueList: string[] = []@State dialogueListNew: string[][] = []@State displayList: boolean[] = []@State displayIndex: number = 1@State delIndex: number = 0@State readBook: readBookCharpterTemplate = readBookCharpterData@Builder leftUser(roleName: string, roleText: string){// 左侧角色Column({ space: 4 }){Row({ space: 12 }){smallImage(roleName, this.frameData.backGround, this.ThisColor)Text(`${roleName}`).fontColor(this.ThisColor).fontSize(this.frameData.typefaceSize)}Row(){Text(`${roleText}`).fontColor(this.ThisColor).fontSize(this.frameData.typefaceSize - 2)}.border({width: 1}).borderRadius({topRight: 12,bottomLeft: 12,bottomRight: 12}).backgroundColor(this.frameData.backGround).padding({top: 8,bottom: 8,left: 12,right: 12}).margin({left: '12%'})}.width('70%').alignItems(HorizontalAlign.Start)}@Builder rightUser(roleName: string, roleText: string){// 右侧角色Column({ space: 4 }){Row({ space: 12 }){Text(`${roleName}`).fontColor(this.ThisColor).fontSize(this.frameData.typefaceSize)smallImage(roleName, this.frameData.backGround, this.ThisColor)}.width('100%').justifyContent(FlexAlign.End)Row(){Row(){Text(`${roleText}`).fontColor(this.ThisColor).fontSize(this.frameData.typefaceSize - 2)}.border({width: 1}).borderRadius({topLeft: 12,bottomLeft: 12,bottomRight: 12}).backgroundColor(this.frameData.backGround).padding({top: 8,bottom: 8,left: 12,right: 12}).margin({right: '12%'})}.width('80%').justifyContent(FlexAlign.End)}.width('100%').alignItems(HorizontalAlign.End)}@Builder narratorUser(roleText: string){// 旁白Column({ space: 4 }){Row(){Text(`${roleText}`).fontColor(this.ThisColor).fontSize(this.frameData.typefaceSize - 2).textAlign(TextAlign.Center)}.border({width: 1}).borderRadius(12).padding(12).margin({top: 8,}).justifyContent(FlexAlign.Center)}.padding({left: 24,right: 24}).width('100%')}aboutToAppear(): void {let params = router.getParams() as Record<string, number>let bookID = params['bookID']let readIndex = params['chapterIndex']for (let index = 0; index < this.readBookList.length; index++) {if (this.readBookList[index].ascriptionBookID == bookID) {this.readBook = this.readBookList[index]break}}this.dialogueList = this.readBook.dialogueList.split(',')for (let item of this.dialogueList) {let read = item.split('|')this.dialogueListNew.push([read[0], read[1], read[2]])}}onPageHide(): void {this.saveData()}saveData() {let readList: string[] = []this.readBook.dialogueList = ''for (let item of this.dialogueListNew) {readList.push(item.join('|'))}for (let item of readList) {this.readBook.dialogueList += item + ','}for (let index = 0; index < this.readBookList.length; index ++) {if (this.readBookList[index].articleID == this.readBook.articleID) {this.readBookList[index] = this.readBook}}promptAction.showToast({message: "保存成功!"})}build() {Flex(){Column(){// 标题Row(){frameData().width(50)Text(`第${this.index}幕`).fontSize(this.frameData.typefaceSize + 8).fontColor(this.ThisColor)Text('').textAlign(TextAlign.End).width(50)}.width('100%').justifyContent(FlexAlign.SpaceBetween).border({width: {bottom: 2}}).padding({top: 16,left: 24,right: 24,bottom: 16})Scroll(this.scorllData){Column({ space: 12 }){ForEach(this.dialogueListNew, (item: string[], index) => {Row(){if (item[0] == 'left') {this.leftUser(item[1], item[2])} else if (item[0] == 'right') {this.rightUser(item[1], item[2])} else if (item[0] == 'pb') {this.narratorUser(item[2])}}.onClick(() => {this.delIndex = indexthis.delPageOpen.open()})})}.alignItems(HorizontalAlign.Start).padding({left: 24,right: 24,top: 16,bottom: 16}).width('100%').alignItems(HorizontalAlign.Start)}.align(Alignment.Top).edgeEffect(EdgeEffect.Spring).height('86%').onClick(() => {this.displayList[this.displayIndex++] = true})Row(){Text('').textCare(this.frameData.typefaceSize + 2).width(100)Text('编辑文本').textCare(this.frameData.typefaceSize + 2).onClick(() => {this.editTextPageOpen.open()})Text('保存').textCare(this.frameData.typefaceSize + 2).onClick(() => {this.saveData()}).width(100).textAlign(TextAlign.End)}.width('100%').justifyContent(FlexAlign.SpaceBetween).border({width: {top: 2}})}.height('100%')}}
}复制

以上便是"说书人"项目中部分重要代码的分享,由于字数限制,不能全部上传,完整代码已经上传AtomGit,大家可以进行下载

master · 说书人_单机版 · AtomGit

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

WebP Vs. PNG:哪种图像格式适合您的网站?

图像对任何网站都至关重要,可以增强视觉吸引力和用户体验。但是,图像也会显着影响网站的加载时间,因此必须针对 Web 使用对其进行优化。一种方法是使用正确的图像格式。

【Git】—— 代码版本控制工具git的安装及基本使用

目录 一、Git的核心作用 二、安装Git 三、本地仓库命令 1、初始化 2、查看文件状态 3、将文件添加到暂存区 4、将文件提交到本地仓库 5、查看提交日志 6、将暂存区文件取消暂存 7、回溯到指定版本 四、忽略文件 一、Git的核心作用 远程备份&#xff1a;将代码备份到…

sentinel-请求限流、线程隔离、本地回调、熔断

请求限流&#xff1a;控制QPS来达到限流的目的 线程隔离&#xff1a;控制线程数量来达到限流的目录 本地回调&#xff1a;当线程被限流、隔离、熔断之后、就不会发起远程调用、而是使用本地已经准备好的回调去提醒用户 熔断&#xff1a;熔断也叫断路器&#xff0c;当失败、或者…

阿里云人工智能ACA(七)——计算机视觉基础

一、自然语言处理基本介绍 1. 自然语言处理的定义 1-1 自然语言 人类使用的在社会生活中自然形成的语言 1-2 自然语言处理 目标是让计算机能够理解、解析、生成和处理人类的自然语言 包含自然语言理解和自然语言生成两部分组成 2. 自然语言处理的发展趋势 3.自然语言处理…

细说STM32F407单片机通过IIC读写EEPROM 24C02

目录 一、操作说明 二、工程配置 1、时钟、DEBUG、GPIO、USART6、NVIC、Code Generator 2、 IIC2 &#xff08;1&#xff09;Master Features组&#xff0c;主设备参数 &#xff08;2&#xff09;Slave Features组&#xff0c;从设备参数 三、软件设计 1、KELED 2、E…

redis开发与运维-redis04-redis客户端Jedis与连接池及客户端异常模拟

文章目录 【README】【1】redis客户端通信协议【2】java客户端Jedis连接redis集群【2.1】Jedis基本用法【2.2】Jedis操作5种数据类型代码实践【2.3】Jedis使用序列化api操作【2.3.1】操作Jedis字节数组api代码实践 【3】Jedis连接池【3.1】Jedis连接池JedisPool代码实践【3.1.1…

KaiOS 4.0 | DataCall and setupData implemention

相关文档 1、KaiOS 3.1 系统介绍 KaiOS 系统框架和应用结构(APP界面逻辑)文章浏览阅读842次,点赞17次,收藏5次。对于Java开发者而言,理解JS的逻辑调用是有点困难的。而KaiOS webapp开发又不同于现代的web开发,更像chrome浏览器内嵌模式。在这里梳理一下kaios平台web应用…

正则化强度的倒数C——让模型学习更准确

引言 嘿&#xff0c;小朋友们&#xff0c;今天我们要学习一个叫做正则化强度倒数C的概念。这听起来可能有点复杂&#xff0c;但它其实是一种帮助计算机学习的方法。想象一下&#xff0c;我们教计算机识别动物&#xff0c;我们希望它既能识别出猫&#xff0c;也能识别出狗&…

飞牛NAS登录Fn Connect教程实测|远程访问教程

前言 有很多小伙伴已经用上飞牛NAS系统很久了&#xff0c;但大部分都是在局域网下使用&#xff0c;如果外出办公或者在办公室&#xff0c;就没办法连接到家里的NAS。 于是咱们今天先出一条关于远程连接到飞牛NAS的教程。 关于飞牛NAS的教程会一步步发布&#xff0c;请耐心等…

Python编程快速上手:让繁琐工作自动化(第2版)下载

适读人群 &#xff1a;本书适合任何想要通过Python学习编程的读者&#xff0c;尤其适合缺乏编程基础的初学者。通过阅读本书&#xff0c;读者将能利用非常强大的编程语言和工具&#xff0c;并且体会到用Python编程的快乐。 Python编程从入门到实践姊妹篇&#xff0c;零基础自学…

短视频矩阵账号管理技术源码搭建详解,支持OEM

一、引言 在短视频矩阵系统中&#xff0c;账号管理是至关重要的一环&#xff0c;它涉及到多平台账号的接入、用户信息的安全存储与高效管理、权限的精准控制以及账号数据的同步与更新等关键功能。一个健壮、灵活且安全的账号管理技术架构&#xff0c;能够为整个短视频矩阵系统的…

精读DeepSeek v3技术文档的心得感悟

最近宋大宝同学读完了DeepSeekv3的文档&#xff0c;心中颇多感慨&#xff0c;忍不住想在这里记录一下对这款“业界有望启示未来低精度训练走向”的开源大模型的观察与思考。DeepSeek v3的亮点绝不仅仅是“Float8”或“超长上下文”这么简单&#xff0c;而是贯穿了从数值精度、注…

43243242342

&#x1f4e2;博客主页&#xff1a;https://blog.csdn.net/2301_779549673 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01; &#x1f4e2;本文由 JohnKi 原创&#xff0c;首发于 CSDN&#x1f649; &#x1f4e2;未来很长&#…

Spring Boot教程之四十:使用 Jasypt 加密 Spring Boot 项目中的密码

如何使用 Jasypt 加密 Spring Boot 项目中的密码 在本文中&#xff0c;我们将学习如何加密 Spring Boot 应用程序配置文件&#xff08;如 application.properties 或 application.yml&#xff09;中的数据。在这些文件中&#xff0c;我们可以加密用户名、密码等。 您经常会遇到…

2011-2019年各省总抚养比数据

2011-2019年各省总抚养比数据 1、时间&#xff1a;2011-2019年 2、来源&#xff1a;国家统计局 3、指标&#xff1a;行政区划代码、地区、年份、总抚养比(人口抽样调查)(%) 4、范围&#xff1a;31省 5、指标解释&#xff1a;总抚养比也称总负担系数。指人口总体中非劳动年…

Java基于SpringBoot的社区团购系统的设计与实现,附源码

博主介绍&#xff1a;✌Java老徐、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&…

libreoffice在Windows和Linux环境的安装和结合Springboot使用教程

前言&#xff1a; 在公司做开发时&#xff0c;遇到一个需求&#xff0c;要求上传的文件有图片&#xff0c;也有word和pdf。预览信息时&#xff0c;既要求能水印展示出来&#xff0c;又要求能大图水印预览。思索许久&#xff0c;我决定采取全部打水印然后转成图片Base64&#x…

Linux实验报告7-文件管理

目录 一&#xff1a;实验目的 二&#xff1a;实验内容 (1)查看/etc/inittab文件的权限属性&#xff0c;并指出该文件的所有者以及文件所属组群。 (2)新建文件test&#xff0c;设置文件权限为r--r-----。 (3)新建文件test2&#xff0c;设系统中有用户study和用户组studygr…

07 基于OpenAMP的核间通信方案

引言 ZYNQ7020有两个CPU核心&#xff0c;这两个核心可以采用SMP或AMP方式进行调度&#xff0c;当采用AMP方式进行调度时核0和核1可以运行不同的操作系统&#xff0c;如核0运行Linux系统&#xff0c;提供有些复杂的用户交互工作&#xff0c;核1运行实时操作系统&#xff0c;对设…

Huggingface数据集采样之后得到的arrow文件无法用Dataset.load_from_disk加载解决方法

问题起源 我现在有数据集 我想要采样1/10构成一个新的数据集。起初我只是简单的使用save_to_disk保存&#xff0c;如下代码&#xff1a; from datasets import Dataset import os# 原数据集路径 source_dataset_path "~/.cache/huggingface/datasets/allenai___tulu-3-…