前段时间开发了一个软件,取名为“说书人”,后由于备案暂时没有通过,于是删除了联网功能,重新做了一个单机版,这里对于单机版的开发实践案例进行一个发出,希望能帮助到大家
文章最后给出了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 = ThisPagefontColor
build() {
Text('Back')
.fontColor(this.ThisColor)
.fontSize(this.frameData.typefaceSize + 6)
.onClick(() => {
router.back()
})
}
}
复制
readBookCharpter.ets
此处存储了章节信息
// 章节信息
export interface readBookCharpterTemplate{
// 章节ID
articleID: number,
// 章节索引
chapterIndex: string,
// 章节内容
dialogueList: string,
// 造物者之ID
createUserID: 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 = 0
onPageShow(): 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: CustomDialogController
onCancel: () => void = () => {}
onJUJUE: () => void = () => {}
@StorageProp('frame') frameData: frame = frameDataSet
@StorageProp('fontColor') ThisColor: ResourceColor = ThisPagefontColor
build() {
/* 用户名和需要修改的参数都由外部传递
此处只涉及数据修改任务*/
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 = ThisPagefontColor
build() {
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 = 0
build() {
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 = 0
build() {
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 = item
break
}
}
}
@StorageProp('frame') frameData: frame = frameDataSet
@StorageProp('fontColor') ThisColor: ResourceColor = ThisPagefontColor
@StorageProp('roleDataList') roleDataList: roleDataTemplate[] = roleDataList
@State roleData: roleDataTemplate = roleData
@State openText: boolean = false
build() {
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)
}
// ID
Row(){
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 = item
break
}
}
}
@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 = 0
build() {
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 = false
build() {
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 }){
// 封面标题作者标签ID
Row({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)
}
// ID
Row(){
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] = textValue
this.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 = index
this.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