HarmonyOS Next 入门实战 - 根底组件、页面完成
根底组件
常用组件
- Text:显现文本内容
- Image:显现图片
- Button:显现一个按钮
- Column: 纵向布局
- Row:横向布局
- List:列表
各组件的用法
Text("文本组件")
.fontColor(Theme.Color.textPrimary)
.fontWeight(FontWeight.Medium)
.fontSize(20)
Image($r('app.media.banner'))
.objectFit(ImageFit.Fill)
.width('100%')
.height(100)
.opacity(191)
Button("按钮").onClick((event) => {
//按钮点击事情
})
Column() {
Text("文本1")
.fontColor(Theme.Color.textPrimary)
.fontWeight(FontWeight.Medium)
.fontSize(20)
Text("文本2")
.fontColor(Theme.Color.textPrimary)
.fontWeight(FontWeight.Medium)
.fontSize(20)
Text("文本3")
.fontColor(Theme.Color.textPrimary)
.fontWeight(FontWeight.Medium)
.fontSize(20)
}.width('100%')
Row() {
Text("文本1")
.fontColor(Theme.Color.textPrimary)
.fontWeight(FontWeight.Medium)
.fontSize(20)
Text("文本2")
.fontColor(Theme.Color.textPrimary)
.fontWeight(FontWeight.Medium)
.fontSize(20)
Text("文本3")
.fontColor(Theme.Color.textPrimary)
.fontWeight(FontWeight.Medium)
.fontSize(20)
}.width('100%')
List() {
ForEach(this.items, (item: string, index) => {
ListItem(){
Text(item).padding(10).width('100%')
}
})
}
Grid
用于展现网格列表
Grid(){
GridItem(){
Text("item1").padding(10)
}
GridItem(){
Text("item2").padding(10)
}
GridItem(){
Text("item12").padding(10)
}
}.columnsTemplate("1f 1f 1f") //列散布规矩
.rowsTemplate("1f 1f 1f") //行散布规矩
Grid的夸行/列设置
在创立Grid时能够传入GridLayoutOptions来完成网格所占行/列数
- regularSize,类型为[number,number],用来界说一般规矩的Item所占的行/列数
- irregularIndexes,类型为number[],用来指定不遵从一般规矩的Item索引。
- onGetIrregularSizeByIndex,类型(index: number) => [number, number]的回调函数,irregularIndexes中装备的索引会回调到此函数,回来成果表明该Item所占用的行/列数,[所占行数,所占列数]
@Preview
@Component
struct GridList {
item: Array<number> = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
layoutOption: GridLayoutOptions = {
regularSize: [1, 1], //一般规矩的item占用1行1列
irregularIndexes: [0, 5], //非一般规矩item的索引
onGetIrregularSizeByIndex: (index: number) => {
if (index == 0) {
return [1, 2] //0索引处的item占用1行2列
} else {
return [2, 1] //5索引处的item占用2行1列
}
}
}
build() {
Grid(null, this.layoutOption) {
ForEach(this.item, (item: number, index) => {
GridItem() {
Stack() {
Text(item + "").textAlign(TextAlign.Center)
}.width('100%').height(index == 5 ? 105 : 50)
}.backgroundColor(Color.Pink)
}, (item: number, index) => {
return item + ""
})
}
.columnsTemplate('1fr 1fr')
.rowsGap(5)
.columnsGap(5)
.width('100%')
.height('100%')
}
}
WaterFlow
瀑布流
WaterFlow() {
FlowItem() {
Text("item1").padding(10)
}
FlowItem() {
Text("item2").padding(10)
}
}
瀑布流夸行/列设置
运用瀑布流的分组信息(WaterFlowSections)能够设置item不同列数的混合布局。
WaterFlowSections 中能够设置多个分组信息,每个分组信息包含如下内容:
● itemsCount 分组中的item数量
● crossCount 瀑布流的行/列数
● columnsGap/rowsGap:列/行距离
● margin 分组的外边距
@Preview
@Component
struct WaterFlowListView {
items: Array<number> = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
@State sections: WaterFlowSections = new WaterFlowSections()
aboutToAppear(): void {
this.sections.push({
itemsCount: 1, //分组中的item数量
crossCount: 1, //分组中的列数
columnsGap: 8, //列距离
rowsGap: 8, //行距离
})
this.sections.push({
itemsCount: 8,
crossCount: 2,
columnsGap: 8,
rowsGap: 8,
margin:{
top: 8
}
})
this.sections.push({
itemsCount: 1,
crossCount: 1,
columnsGap: 8,
rowsGap: 8,
margin:{
top: 8
}
})
}
build() {
WaterFlow({ sections: this.sections }) {
ForEach(this.items, (item: number, index) => {
FlowItem() {
Stack() {
Text(item + "").textAlign(TextAlign.Center)
}.height(index*10 + 30)
}.backgroundColor(Color.Pink).width('100%')
}, (item: number, index) => {
return item + ""
})
}
.width('100%')
.height('100%')
}
}
页面完成
预备数据
首要需求预备数据,包含诗词内容,小常识,作者。
json文件内容如下:
[
{
"title": "满江红·写怀",
"dynasty": "南宋",
"author": "岳飞",
"introduction": "此词上片写作者悲愤华夏重陷敌手,怜惜前功尽弃的局势,也表达自己持续尽力,争夺壮年建功的期望。\n此词下片工作笔端,表达词人关于民族敌人的血海深仇,统一祖国的深切期望,忠于朝廷即忠于祖国的热诚之心。",
"text": "勃然大怒,凭阑处、潇潇雨歇。\n抬望眼,仰天长啸,壮怀激烈。\n三十功名尘与土,八千里路云和月。\n莫等闲、白了少年初,空悲切。\n靖康耻,犹未雪。\n臣子恨,何时灭。\n驾长车,踏破贺兰山缺。\n壮志饥餐胡虏肉,笑谈渴饮匈奴血。\n待从头、拾掇旧山河,朝天阙。",
"textAlign": "center",
"translation": "气得头发竖起,以至于将帽子顶起,登高倚栏杆,一场潇潇细雨刚刚停歇。\n\n昂首望眼四望宽广一片,仰天长声啸叹,一片报国之心充溢心胸。\n\n三十多年来虽已树立一些功名,但好像尘土微乎其微,南北转战八千里,经过多少风云人生。\n\n不要虚度年华,斑白了少年黑发,只要单独懊悔悲悲切切。\n\n靖康年的奇耻,没有湔雪。\n\n臣子愤怒,何时才干消灭。\n\n我要驾着战车向贺兰山进攻,连贺兰山也要踏为平地。\n\n我满怀壮志,交兵饿了就吃敌人的肉,谈笑渴了就喝敌人的鲜血。\n\n我要从头再来,克复旧日河山,朝拜故都京阙。",
"searchKey": "manjianghong|mjh|mjhxh|song|yuefei|yf"
},
{
"title": "水调歌头·明月何时有",
"dynasty": "北宋",
"author": "苏轼",
"introduction": "词前的小序交待了写词的进程:“丙辰中秋,欢饮达旦,酣醉。作此篇,兼怀子由。”苏轼由于与当权的变法者王安石等人政见不同,自求外放,曲折在各地为官。他从前要求调任到离苏辙较近的当地为官,以求兄弟多多集会。公元1074年(熙宁七年)苏轼差知密州。到密州后,这一期望仍无法完成。公元1076年的中秋,皓月当空,银辉遍地,词人与胞弟苏辙别离之后,已七年未得聚会。此时,词人面临一轮明月,心潮起伏,所以乘酒兴正酣,挥笔写下了这首名篇。",
"text": "丙辰中秋,欢饮达旦,酣醉,作此篇,兼怀子由。\n\n明月何时有?把酒问彼苍。不知天上宫阙,今夕是何年。我欲乘风归去,又恐琼楼玉宇,高处不堪寒。起舞弄清影,何似在人世。\n\n转朱阁,低绮户,照无眠。不应有恨,何事长向别时圆?人有悲欢离合,月有阴晴圆缺,此事古难全。但愿人长久,千里共婵娟。",
"textAlign": "left",
"translation": "丙辰年的中秋节,快乐地喝酒直到第二天早晨,喝到酣醉,写了这首词,一起怀念弟弟苏辙。\n\n明月从什么时候才开端呈现的?我端起酒杯遥问苍天。不知道在天上的宫廷,何年何月。我想要乘御清风回到天上,又恐怕在美玉砌成的楼宇,受不住挺拔九霄的冰冷。翩然起舞玩赏着月下清影,哪像是在人世。\n\n月儿转过朱红色的楼阁,低低地挂在雕花的窗户上,照着没有睡意的自己。明月不应对人们有什么仇恨吧,为什么偏在人们离别时才圆呢?人有悲欢离合的变迁,月有阴晴圆缺的转化,这种事自古来难以周全。只期望这世上所有人的亲人能安全健康,即使相隔千里,也能同享这夸姣的月光。",
"rectify": {
"高触不堪寒": "高触不堪寒"
},
"searchKey": "shuidiaogetou|mingyuejishiyou|sdgt|myjsy|song|sushi|ss"
},
{
"title": "登高",
"dynasty": "唐",
"author": "杜甫",
"introduction": "此诗作于公元767年(唐代宗大历二年)秋天,杜甫时在夔州。这是他在五十六岁时写下的。一天他单独登上夔州白帝郊外的高台,登高临眺,萧条的秋江风光,引发了他身世漂荡的慨叹,渗入了他老病孤愁的悲痛。所以,就有了这首被誉为“七律之冠”的《登高》。",
"text": "风急天高猿萧哀,渚清沙白鸟飞回;\n无边落木萧萧下,不尽长江滚滚来。\n万里悲秋常作客,百年多病独登台;\n困难苦恨繁霜鬓,失意新停浊酒杯。",
"textAlign": "center",
"translation": "风急天高猿猴啼叫显得非常悲痛,水清沙白的河洲上有鸟儿在回旋扭转。\n一望无垠的树木萧萧地飘下落叶,长江滚滚涌来飞跃不息。\n悲对秋景慨叹万里流浪终年为客,终身傍边疾病缠身今天独上高台。\n历尽了困难苦恨青丝长满了双鬓,衰颓满心偏又暂停了浇愁的酒杯。",
"searchKey": "denggao|dg|tang|dufu|dg"
},
……
]
[
{
"title": "唐宋八咱们",
"text": "唐宋八咱们,又称为“唐宋散文八咱们”,是唐代和宋代八位散文家的合称,别离为唐代韩愈、柳宗元和宋代欧阳修、苏洵、苏轼、苏辙、王安石、曾巩八位。\n其间韩愈、柳宗元是唐代古文运动的首领,欧阳修、三苏(苏轼、苏辙、苏洵)等四人是宋代古文运动的核心人物,王安石、曾巩是临川文学的代表人物。他们先后掀起的古文改造浪潮,使诗文开展的陈腐相貌面目一新。\n八咱们中苏家父子兄弟有三人,人称“三苏”,别离为苏洵、苏轼、苏辙,又有“一门三学士”之誉。故可用“韩柳欧王曾三苏”归纳。"
},
{
"title": "醉八仙",
"text": "醉八仙,指唐朝嗜酒的八位学者名人,亦称酒中八仙、饮中八仙。《新唐书·李白传》载,李白、贺知章、李适之、汝阳王李琎、崔宗之、苏晋、张旭、焦遂为“酒中八仙人”。杜甫有《饮中八仙歌》。瓷器画面绘饮中八仙,每每于人物之上书以人名,以清朝为多见。\n一仙贺知章:知章骑马似搭船,目炫落井水底眠。\n二仙汝阳王:汝阳三斗始朝天,道逢麴车口流涎,恨不移封向酒泉。\n三仙李适之:左相日兴费万钱,饮如长鲸吸百川,衔杯乐圣称避贤。\n四仙崔宗之:宗之洒脱美少年,举觞白眼望彼苍,皎如玉树临风前。\n五仙苏晋:苏晋长斋绣佛前,醉中往往爱逃禅。\n六仙李白:李白一斗诗百篇,长安市上酒家眠。皇帝呼来不上船,自称臣是酒中仙。\n七仙张旭:张旭三杯草圣传,脱帽露顶王公前,挥毫落纸如云烟。\n八仙焦遂:焦遂五斗方卓著,高谈雄辩惊四筵。"
},
……
]
[
{
"name": "苏轼",
"dynasty": "北宋",
"introduction": "苏轼(1037年—1101年),字子瞻,又字和仲,号铁冠道人、东坡居士,世称苏东坡、苏仙、坡仙。眉州眉山(今四川省眉山市)人,北宋文学家,书法家、画家,前史治水名人。与父苏洵、弟苏辙三人并称“三苏”。\n嘉祐二年(1057年),参加殿试中乙科,赐进士及第(一说赐进士身世)。嘉祐六年(1061年),参加制科考试,授大理评事、签书凤翔府判官。宋神宗时,曾在杭州、密州、徐州、湖州等地任职。元丰三年(1080年),因“乌台诗案”,被贬为黄州团练副使。宋哲宗即位后,出任兵部尚书、礼部尚书等职,外放管理杭州、颍州、扬州、定州等地。跟着新党执政,又被贬惠州、儋州。宋徽宗时,获赦北还,病逝于常州。南宋时期,追赠太师,谥号“文忠”。\n苏轼是北宋中期文坛首领,在诗、词、文、书、画等方面获得很高成果。其诗体裁宽广,新鲜豪健,善用夸大比方,独具风格,与黄庭坚并称“苏黄”;其词开豪宕一派,与辛弃疾同是豪宕派代表,并称“苏辛”;其文著作宏富,纵横恣肆,豪宕自若,与欧阳修并称“欧苏”,与韩愈、柳宗元、欧阳修、苏洵、苏辙、王安石、曾巩合称“唐宋八咱们”;善书法,与黄庭坚、米芾、蔡襄合称“宋四家”;拿手文人画,尤擅墨竹、怪石、枯木等。著作有《东坡七集》《东坡易传》《东坡乐府》《寒食帖》《潇湘竹石图》《枯木怪石图》等。"
},
{
"name": "杜甫",
"dynasty": "唐",
"introduction": "杜甫(712年2月12日—770年),字子美,自号少陵野老,本籍襄阳(今属湖北),自其曾祖时迁居巩县(今河南巩义西南)。唐代闻名现实主义诗人。与李白合称“李杜”“大李杜”,也常被称为“老杜”。\n杜甫自幼好学,常识广博,颇有政治志向。唐玄宗开元后期,举进士不第,周游各地。后居住长安近十年,未能有所发挥,日子贫穷,逐步对其时的社会情况有较深的知道。后靠献赋才得授小官。安史之乱迸发、长安沦陷后,他曾被困城中半年,后逃至凤翔,被唐肃宗拜为左拾遗,世称“杜拾遗”。长安克复后,随肃宗还京,又被外放为华州司功参军。期间创作了《登高》《春望》《北征》以及“三吏”“三别”等名作。后弃官移家至成都,一度在剑南节度使严武幕中任顾问,被表授为检校工部员外郎,故世称“杜工部”。晚年携家出蜀,于大历五年(770年)冬在曲折途中去世,享年五十九岁。\n杜甫善于运用各种诗篇方式,尤善于律诗,风格多样,而以沉郁为主;言语精练,具有高度的表达能力。承继和开展《诗经》以来注重反映社会现实的优秀文学传统,成为中国古代诗篇艺术开展的又一顶峰,被后人公认为诗篇史上的“集大成者”。他的品质,也被认为是中华民族文人品质的榜样。自晚唐两宋后,杜甫逐步声名远播,对中国文学和日本文学都产生了深远的影响。后世敬称他为“诗圣”,称其诗为“诗史” 。其传世著作大多集于《杜工部集》。"
},
{
"name": "岳飞",
"dynasty": "南宋",
"introduction": "岳飞(1103年3月24日—1142年1月27日),字鹏举,宋朝相州汤阴(今河南汤阴)人,本籍东昌(今山东聊城),南宋时期抗金名将、军事家、战略家、民族英雄、书法家、诗人,位列南宋“中兴四将”之首。\n岳飞从二十岁起,曾先后四次参军。自建炎二年(1128年)遇宗泽至绍兴十一年(1141年)止,先后参加、指挥巨细战役数百次。金军攻击江南时,别出心裁,力主抗金,克复建康。绍兴四年(1134年),克复襄阳六郡。绍兴六年(1136年),率师北伐,顺畅攻取商州、虢州等地。绍兴十年(1140年),完颜宗弼毁盟攻宋,岳飞挥师北伐,两河公民奔走相告,各地义师纷繁呼应,夹攻金军。岳家军先后克复郑州、洛阳等地,在郾城、颍昌大北金军,进军朱仙镇。宋高宗赵构和宰相秦桧却一意求和,以十二道“金字牌”催令出师。在宋金议和进程中,岳飞遭受秦桧、张俊等人诬害入狱。1142年1月,以莫须有的罪名,与长子岳云、部将张宪一起遇害。宋孝宗时,平反昭雪,改葬于西湖畔栖霞岭,追谥武穆,后又追谥忠武,封鄂王。 \n岳飞是南宋出色的统帅,他注重公民抗金力气,缔造了“连接河朔”之谋,建议黄河以北的民间抗金义师和宋军互相配合,以克复失地;治军赏罚分明,纪律严整,又能体恤部下,一马当先,带领的“岳家军”声称“冻死不拆屋,饿死不掳掠”。金军有“撼山易,撼岳家军难”的评语,以示对岳家军的由衷敬佩。\n岳飞的文才相同杰出,其代表词作《满江红·勃然大怒》是千古传诵的爱国名篇,后人辑有文集传世。"
},
……
}
将json文件放置在资源目录 resources/rawfile/ 下载
运用时经过 import 导入
import poetryList from 'resources/rawfile/poetry.json';
import tips from 'resources/rawfile/tips.json';
依据json数据格式界说数据实体类
export interface Poetry {
uuid?: string
title: string
dynasty: string
author: string
introduction: string
text: string
textAlign: string
translation: string
rectify?: object
searchKey: string
}
export class Tip {
uuid: string
title: string
text: string
}
主页完成
主页完成作用
主页内容包含一个随机的小常识和诗词列表,因而咱们能够运用List,Grid,WaterFlow组件来完成列表展现,这儿咱们以WaterFlow为例。
小常识布局
@Component
export struct TipView {
@Prop tip: Tip
viewHeight: number = 152
textFontSize: number = 19
textController: TextController = new TextController();
applyTextStyle() {
let style = TextStyleUtils.buildParagraphIndentStyle(this.tip.text, this.textFontSize * 2)
this.textController.setStyledString(style)
}
build() {
Stack({
alignContent: Alignment.TopStart
}) {
Image($r('app.media.tip_banner'))
.objectFit(ImageFit.Fill)
.width('100%')
.height(this.viewHeight)
.opacity(191)
Column() {
Text(this.tip.title)
.fontSize(20)
.fontWeight(FontWeight.Medium)
Text(undefined, { controller: this.textController })
.fontSize(this.textFontSize)
.lineHeight(26)
.maxLines(4)
.textOverflow({
overflow: TextOverflow.Ellipsis
})
.margin({ top: 5 })
.width("100%")
.onAppear(() => {
this.applyTextStyle()
})
}
.alignItems(HorizontalAlign.Start)
.padding({
top: 10,
bottom: 10,
left: 12,
right: 12
})
.width('100%')
.constraintSize({ maxHeight: this.viewHeight })
.backgroundColor(Theme.Color.tipShade)
}
.clip(true)
.borderRadius(10)
}
}
小常识内容触及多个阶段,为了阅览便利,阶段开端需求缩进2个汉字,HarmonyOS供给了 ParagraphStyle 类设置阶段款式。
export class TextStyleUtils {
static buildParagraphIndentStyle(text: string, offset: number): MutableStyledString {
let paragraphStyle: ParagraphStyle = new ParagraphStyle({ textIndent: LengthMetrics.vp(offset) });
let regArray = text.matchAll(/\n/g)
let styleArray: Array<StyleOptions> = []
styleArray.push({
start: 0,
length: 3,
styledKey: StyledStringKey.PARAGRAPH_STYLE,
styledValue: paragraphStyle
})
for (let match of regArray) {
styleArray.push({
start: match.index,
length: 3,
styledKey: StyledStringKey.PARAGRAPH_STYLE,
styledValue: paragraphStyle
})
}
return new MutableStyledString(text, styleArray)
}
}
诗词列表项布局
@Component
struct DataItemView {
@Prop item: Poetry
build() {
Column() {
Text(this.item.title)
.fontColor(Theme.Color.textPrimary)
.fontWeight(FontWeight.Medium)
.fontSize(20)
Text(`[${this.item.dynasty}]${this.item.author}`)
.fontColor(Theme.Color.textSecondary)
.fontSize(16)
.margin({ top: 2 })
Text(this.item.introduction)
.fontColor(Theme.Color.textSecondary)
.fontSize(16)
.margin({ top: 5 })
.maxLines(3)
.textOverflow({
overflow: TextOverflow.Ellipsis
})
}
.alignItems(HorizontalAlign.Start)
.padding(10)
}
}
瀑布流列表
列表第一项是小常识布局,需求夸2列显现,因而列表项分组如下:
- 小常识布局,数量为1,展现1列
- 诗词项布局,数量为诗词列表数量,展现2列
- 底部留白,数量为1,展现1列
@Component
struct WaterFlowView {
@Prop tip: Tip
@Prop poetryList: LazyDataSource<Poetry>
@State sections: WaterFlowSections = new WaterFlowSections()
aboutToAppear(): void {
this.sections.push({
itemsCount: 1,
crossCount: 1,
})
this.sections.push({
itemsCount: this.poetryList.totalCount(),
crossCount: 2,
columnsGap: 8,
rowsGap: 8,
})
this.sections.push({
itemsCount: 1,
crossCount: 1,
})
}
build() {
WaterFlow({ sections: this.sections, layoutMode: WaterFlowLayoutMode.SLIDING_WINDOW }) {
FlowItem() {
TipView({
tip: this.tip,
})
}
.padding({ top: 8, bottom: 8 })
.onClick(() => {
})
LazyForEach(this.poetryList,
(item: Poetry, index) => {
FlowItem() {
DataItemView({
item: item
})
}
.width('100%')
.borderRadius(10)
.backgroundColor(Theme.Color.inputEditTextBackground)
.onClick(() => {
})
},
(item: Poetry, index) => {
return item.uuid
}
)
FlowItem() {
Text().height(8).width('100%')
}
}
.width('100%')
.height('100%')
.padding({ left: 8, right: 8 })
}
详情页完成
详情页完成作用
诗词正文部分能够依据内容居中或居左展现,【介绍】部分也是需求阶段缩进(参阅小常识布局)。详情页布局比较简单,不在胪陈。
本文的技术设计和完成都是根据作者工作中的经验总结,如有过错,请留言纠正,谢谢。