| ---------------------------------------------------------------------------------------- |# 概述
OpenHarmony ArkUI框架提供了豐富的動(dòng)畫組件和接口,開發(fā)者可以根據(jù)實(shí)際場(chǎng)景和開發(fā)需求,選用豐富的動(dòng)畫組件和接口來實(shí)現(xiàn)不同的動(dòng)畫效果。
本Codelab中,我們會(huì)構(gòu)建一個(gè)簡(jiǎn)易的購物應(yīng)用。應(yīng)用包含兩級(jí)頁面,分別是主頁(“商品瀏覽”頁簽、“購物車”頁簽、“我的”頁簽)和商品詳情頁面。效果如下圖所示:
代碼結(jié)構(gòu)解讀
本篇Codelab只對(duì)核心代碼進(jìn)行講解,首先來介紹下整個(gè)工程的代碼結(jié)構(gòu):
- model:存放封裝好的數(shù)據(jù)實(shí)體。
- pages:存放頁面。
- resources :存放工程使用到的資源文件。
- resources/base/media:存放工程中使用的圖片資源。
- config.json:配置文件。
- 鴻蒙開發(fā)指導(dǎo)文檔:[
gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md
]
搭建OpenHarmony環(huán)境
完成本篇Codelab我們首先要完成開發(fā)環(huán)境的搭建,本示例以Hi3516DV300開發(fā)板為例,參照以下步驟進(jìn)行:
- [獲取OpenHarmony系統(tǒng)版本]:標(biāo)準(zhǔn)系統(tǒng)解決方案(二進(jìn)制)
以3.0版本為例: - 搭建燒錄環(huán)境
- [完成DevEco Device Tool的安裝]
- [完成Hi3516開發(fā)板的燒錄]
- 搭建開發(fā)環(huán)境
- 開始前請(qǐng)參考[工具準(zhǔn)備],完成DevEco Studio的安裝和開發(fā)環(huán)境配置。
- 開發(fā)環(huán)境配置完成后,請(qǐng)參考[使用工程向?qū)創(chuàng)建工程(模板選擇“Empty Ability”),選擇JS或者eTS語言開發(fā)。
- 工程創(chuàng)建完成后,選擇使用[真機(jī)進(jìn)行調(diào)測(cè)]。
HarmonyOS與OpenHarmony鴻蒙文檔籽料:mau123789是v直接拿
構(gòu)建商品列表頁簽
在本節(jié)中,我們將完成商品列表頁簽的設(shè)計(jì),效果圖如下:
從效果圖可以看出,商品列表頁簽主要由三個(gè)部分組成:
- 頂部的Tabs組件。
- 中間TabContent組件內(nèi)包含List組件。其中List組件的item是一個(gè)水平布局,由一個(gè)垂直布局和一個(gè)Image組件組成;item中的垂直布局由3個(gè)Text組件組成。
- 底部的導(dǎo)航頁簽navigation組件。
實(shí)現(xiàn)步驟如下:
- 在pages目錄下面新建一個(gè)ETS Page,命名為HomePage.ets,在config.json文件的pages屬性中會(huì)自動(dòng)添加“pages/HomePage”頁面路由。
說明:
- 頁面文件名不能使用組件名稱,比如:Text.ets、Button.ets等。
- 每個(gè)頁面文件中必須包含入口組件。
新建與pages文件夾同級(jí)的model文件夾,并在model目錄下新建ArsData.ets、GoodsData.ets、Menu.ets和GoodsDataModels.ets文件,其中ArsData.ets、GoodsData.ets、Menu.ets是數(shù)據(jù)實(shí)體類,GoodsDataModels.ets是存放這三種實(shí)體數(shù)據(jù)集合,并定義了獲取各種數(shù)據(jù)集合的方法。數(shù)據(jù)實(shí)體包含實(shí)體的屬性和構(gòu)造方法,可通過new ArsData(string,string) 來獲取ArsData對(duì)象,ArsData.ets內(nèi)容如下:
let NextId = 0; export class ArsData { id: string; title: string; content: string; constructor(title: string, content: string) { this.id = `${NextId++}`; this.title = title; this.content = content; } }
GoodsData.ets代碼如下:
let NextId = 0; export class GoodsData { id: string; title: string; content: string; price: number; imgSrc: Resource; constructor(title: string, content: string, price: number, imgSrc: Resource) { this.id = `${NextId++}`; this.title = title; this.content = content; this.price = price; this.imgSrc = imgSrc; } }
一個(gè)文件中可以包含多個(gè)class ,Menu.ets中就包含了Menu類和ImageItem類,Menu.ets代碼如下
let NextId = 0; export class Menu { id: string; title: string; num: number; constructor(title: string, num: number) { this.id = `${NextId++}`; this.title = title; this.num = num; } } export class ImageItem { id: string; title: string; imageSrc: Resource; constructor(title: string, imageSrc: Resource) { this.id = `${NextId++}`; this.title = title; this.imageSrc = imageSrc; } }
GoodsDataModels.ets代碼如下:
import {GoodsData} from './GoodsData' import {Menu, ImageItem} from './Menu' import {ArsData} from './ArsData' //獲取商品列表數(shù)據(jù) export function initializeOnStartup(): Array< GoodsData > { let GoodsDataArray: Array< GoodsData > = [] GoodsComposition.forEach(item = > { console.log(item.title); GoodsDataArray.push(new GoodsData(item.title, item.content, item.price, item.imgSrc)); }) return GoodsDataArray; } //獲取底部默認(rèn)圖片列表數(shù)據(jù) export function getIconPath(): Array< string > { let IconPath: Array< string > = ['nav/icon-buy.png','nav/icon-shopping-cart.png','nav/icon-my.png'] return IconPath; } //獲取選中后圖片列表數(shù)據(jù) export function getIconPathSelect(): Array< string > { let IconPathSelect: Array< string > = ['nav/icon-home.png','nav/icon-shopping-cart-select.png','nav/icon-my-select.png'] return IconPathSelect; } //獲取商品詳情頁圖片詳情列表 export function getDetailImages(): Array< string > { let detailImages: Array< string > = ['computer/computer1.png','computer/computer2.png','computer/computer3.png','computer/computer4.png','computer/computer5.png','computer/computer6.png'] return detailImages; } //獲取菜單數(shù)據(jù)列表 export function getMenu(): Array< Menu > { let MenuArray: Array< Menu > = [] MyMenu.forEach(item = > { MenuArray.push(new Menu(item.title,item.num)); }) return MenuArray; } //獲取MyTrans數(shù)據(jù)列表 export function getTrans(): Array< ImageItem > { let ImageItemArray: Array< ImageItem > = [] MyTrans.forEach(item = > { ImageItemArray.push(new ImageItem(item.title,item.imageSrc)); }) return ImageItemArray; } //獲取More數(shù)據(jù)列表 export function getMore(): Array< ImageItem > { let ImageItemArray: Array< ImageItem > = [] MyMore.forEach(item = > { ImageItemArray.push(new ImageItem(item.title,item.imageSrc)); }) return ImageItemArray; } //獲取參數(shù)列表 export function getArs(): Array< ArsData > { let ArsItemArray: Array< ArsData > = [] ArsList.forEach(item = > { ArsItemArray.push(new ArsData(item.title,item.content)); }) return ArsItemArray; } //數(shù)據(jù)集合部分 ...
在HomePage.ets文件中創(chuàng)建商品列表頁簽相關(guān)的組件,其中GoodsHome效果圖如下:
代碼如下:@Component @Component struct GoodsHome { private goodsItems: GoodsData[] build() { Column() { Tabs() { TabContent() { GoodsList({ goodsItems: this.goodsItems }); } .tabBar("Top Sellers") .backgroundColor(Color.White) TabContent() { GoodsList({ goodsItems: this.goodsItems }); } .tabBar("Recommended") .backgroundColor(Color.White) TabContent() { GoodsList({ goodsItems: this.goodsItems }); } .tabBar("Lifestyle") .backgroundColor(Color.White) TabContent() { GoodsList({ goodsItems: this.goodsItems }); } .tabBar("Deals") .backgroundColor(Color.White) } .barWidth(540) .barHeight(50) .scrollable(true) .barMode(BarMode.Scrollable) .backgroundColor('#007DFF') .height('100%') } .alignItems(HorizontalAlign.Start) } }
在GoodsHome中使用Tabs組件,在Tabs組件中設(shè)置4個(gè)TabContent,給每個(gè)TabContent設(shè)置tabBar屬性,并設(shè)置TabContent容器中的內(nèi)容GoodsList組件,GoodsList組件效果圖如下:
代碼如下:
@Component struct GoodsList { private goodsItems: GoodsData[] build() { Column() { List() { ForEach(this.goodsItems, item = > { ListItem() { GoodsListItem({ goodsItem: item }) } }, item = > item.id.toString()) } .height('100%') .width('100%') .align(Alignment.Top) .margin({top: 5}) } } }
在GoodsList組件中遍歷商品數(shù)據(jù)集合,ListItem組件中設(shè)置組件內(nèi)容,并使用Navigator組件給每個(gè)Item設(shè)置頂級(jí)跳轉(zhuǎn)路由,GoodsListItem組件效果圖如下:
代碼如下:
@Component struct GoodsListItem { private goodsItem: GoodsData build() { Navigator({ target: 'pages/ShoppingDetail' }) { Row() { Column() { Text(this.goodsItem.title) .fontSize(18) Text(this.goodsItem.content) .fontSize(14) Text('¥' + this.goodsItem.price) .fontSize(18) .fontColor(Color.Red) } .height(130) .width('60%') .margin({ left: 20 }) .alignItems(HorizontalAlign.Start) Image(this.goodsItem.imgSrc) .objectFit(ImageFit.ScaleDown) .height(130) .width('30%') .renderMode(ImageRenderMode.Original) .margin({ right: 10, left: 10 }) } .backgroundColor(Color.White) } .params({ goodsData: this.goodsItem }) .margin({ right: 5 }) } }
在HomePage.ets中創(chuàng)建文件入口組件(Index)以及底部頁簽導(dǎo)航組件(Navigation),導(dǎo)入需要使用到的數(shù)據(jù)實(shí)體類以及需要使用的方法和組件,每個(gè)page文件都必須包含一個(gè)入口組件,使用@Entry修飾,HomePage文件中的入口組件(Index)代碼如下:
import { GoodsData, IconImage } from '../model/GoodsData' import { initializeOnStartup, getIconPath, getIconPathSelect } from '../model/GoodsDataModels' import { ShoppingCart } from './ShoppingCartPage.ets' import { MyInfo } from './MyPage.ets' import router from '@system.router'; @Entry @Component struct Index { @Provide currentPage: number = 1 private goodsItems: GoodsData[] = initializeOnStartup() @State Build: Array< Object > = [ { icon: $r('app.media.icon_home'), icon_after: $r('app.media.icon_buy1'), text: '首頁', num: 0 }, { icon: $r('app.media.icon_shopping_cart'), icon_after: $r('app.media.icon_shopping_cart_select'), text: '購物車', num: 1 }, { icon: $r('app.media.icon_my'), icon_after: $r('app.media.icon_my_select'), text: '我的', num: 2 } ] @Builder NavigationToolbar() { Flex({direction:FlexDirection.Row,wrap:FlexWrap.NoWrap,justifyContent:FlexAlign.SpaceAround}) { ForEach(this.Build, item = > { Column() { Image(this.currentPage == item.num ? item.icon_after : item.icon) .width(25) .height(25) Text(item.text) .fontColor(this.currentPage == item.num ? "#ff7500" : "#000000") } .onClick(() = > { this.currentPage = item.num }) }) } } build() { Column() { Navigation() { Flex() { if (this.currentPage == 0) { GoodsHome({ goodsItems: this.goodsItems }) } if (this.currentPage == 1) { ShoppingCart() //購物車列表 } if (this.currentPage == 2) { MyInfo() //我的 } } .width('100%') .height('100%') } .toolBar(this.NavigationToolbar) .title("購物車") .hideTitleBar(this.currentPage == 1 ? false : true) .hideBackButton(true) } } }
從入口組件的代碼中可以看出,我們定義了一個(gè)全局變量currentPage ,當(dāng)currentPage發(fā)生變化的時(shí)候,會(huì)顯示不同的頁簽。在入口組件中,通initializeOnStartup獲取商品列表數(shù)據(jù)(goodsItems)并傳入GoodsHome組件中。效果圖如下:
構(gòu)建購物車頁簽
從上面效果圖可以看出,主界面購物車頁簽主要由下面三部分組成:
- 頂部的title,由Navigation組件title屬性設(shè)置。
- 中間的List組件,其中List組件的item是一個(gè)水平的布局內(nèi)包含一個(gè)toggle組件,一個(gè)Image組件和一個(gè)垂直布局,其item中的垂直布局是由2個(gè)Text組件組成。
- 底部一個(gè)水平布局包含兩個(gè)Text組件。
在本任務(wù)中我們主要是構(gòu)建一個(gè)購物車頁簽,給商品列表的每個(gè)商品設(shè)置一個(gè)單選框,可以選中與取消選中,底部Total值也會(huì)隨之增加或減少,點(diǎn)擊Check Out時(shí)會(huì)觸發(fā)彈窗。下面我們來完成ShoppingCart頁簽。
在pages目錄下面新建一個(gè)ETS Page ,命名為ShoppingCart.ets,config.json文件pages屬性中也會(huì)自動(dòng)添加“pages/ShoppingCart”頁面路由。
在ShoppingCartPage.ets文件中添加入口組件(ShoppingCart),并導(dǎo)入需要使用到的數(shù)據(jù)實(shí)體類、方法和組件。ShoppingCart組件代碼如下:
import {GoodsData} from '../model/GoodsData' import {initializeOnStartup} from '../model/GoodsDataModels' import prompt from '@system.prompt'; @Entry @Component export struct ShoppingCart { @Provide totalPrice: number = 0 private goodsItems: GoodsData[] = initializeOnStartup() build() { Column() { ShopCartList({ goodsItems: this.goodsItems }); ShopCartBottom() } .height('100%') .width('100%') .alignItems(HorizontalAlign.Start) } }
新建ShopCartList組件用于存放購物車商品列表,ShopCartList組件效果圖如下:
代碼如下:@Component struct ShopCartList { private goodsItems: GoodsData[] build() { Column() { List() { ForEach(this.goodsItems, item = > { ListItem() { ShopCartListItem({ goodsItem: item }) } }, item = > item.id.toString()) } .height('100%') .width('100%') .align(Alignment.Top) .margin({ top: 5 }) } .height('90%') } }
在ShopCartListItem中使用Toggle的單選框類型來實(shí)現(xiàn)每個(gè)item的選擇和取消選擇,在Toggle的onChage事件中來改變totalPrice的數(shù)值。ShopCartListItem組件效果圖如下:
代碼如下:
@Component struct ShopCartListItem { @Consume totalPrice: number private goodsItem: GoodsData build() { Row() { Toggle({ type: ToggleType.Checkbox }) .width(13) .height(13) .onChange((isOn: boolean) = > { if (isOn) { this.totalPrice += parseInt(this.goodsItem.price + '', 0) } else { this.totalPrice -= parseInt(this.goodsItem.price + '', 0) } }) Image(this.goodsItem.imgSrc) .objectFit(ImageFit.ScaleDown) .height(130) .width(100) .renderMode(ImageRenderMode.Original) Column() { Text(this.goodsItem.title) .fontSize(18) Text('¥' + this.goodsItem.price) .fontSize(18) .fontColor(Color.Red) } .margin({left:40}) } .height(100) .width('100%') .margin({ left: 20 }) .alignItems(VerticalAlign.Center) .backgroundColor(Color.White) } }
新建ShopCartBottom組件,ShopCartBottom組件效果圖如下:
代碼如下:@Component struct ShopCartBottom { @Consume totalPrice: number build() { Row() { Text('Total: ¥' + this.totalPrice) .fontColor(Color.Red) .fontSize(18) .margin({ left: 20 }) .width(150) Text('Check Out') .fontColor(Color.Black) .fontSize(18) .margin({ right: 20, left: 180 }) .onClick(() = > { prompt.showToast({ message: 'Checking Out', duration: 10, bottom: 100 }) }) } .height(30) .width('100%') .backgroundColor('#FF7FFFD4') .alignItems(VerticalAlign.Bottom) } }
構(gòu)建我的頁簽
從上面效果圖可以看出,主界面我的頁簽主要由下面四部分組成:
- 頂部的水平布局。
- 頂部下面的文本加數(shù)字的水平List。
- My Transactio模塊,圖片加文本的水平List。
- More模塊,圖片加文本的Grid。
在本任務(wù)中,我們構(gòu)建主頁我的頁簽,主要可以劃分成下面幾步:
在pages目錄下面新建一個(gè)ETS Page 命名為MyPage.ets,在config.json文件pages屬性中也會(huì)自動(dòng)添加“pages/MyPage”頁面路由。
在MyPage.ets文件中添加入口組件(MyInfo),組件內(nèi)容如下:
import {getMenu,getTrans,getMore} from '../model/GoodsDataModels' import {Menu, ImageItem} from '../model/Menu' @Entry @Component export struct MyInfo { build() { Column() { Row() { Image($r('app.media.icon_user')) .objectFit(ImageFit.Contain) .height(50) .width(50) .margin({left:10}) .renderMode(ImageRenderMode.Original) Column() { Text('John Doe') .fontSize(15) Text('Member Name : John Doe >') .fontSize(15) } .height(60) .margin({ left: 20, top: 10 }) .alignItems(HorizontalAlign.Start) } TopList() MyTransList() MoreGrid() } .alignItems(HorizontalAlign.Start) .width('100%') .height('100%') .flexGrow(1) } }
入口組件中還包含TopList,MyTransList和MoreGrid三個(gè)子組件。
在MyPage.ets文件中新建TopList組件,效果圖如下:
代碼如下:@Component struct TopList { private menus: Menu1[] = getMenu() build() { Row() { List() { ForEach(this.menus, item = > { ListItem() { MenuItem({ menu: item }) } }, item = > item.id.toString()) } .height('100%') .width('100%') .margin({ top: 5,left: 10}) .edgeEffect(EdgeEffect.None) .listDirection(Axis.Horizontal) } .width('100%') .height(50) } }
getMenu()方法在上文中已有定義,是獲取菜單列表的方法,TopList的子組件MenuItem內(nèi)容如下:
@Component struct MenuItem { private menu: Menu1 build() { Column() { Text(this.menu.title) .fontSize(15) Text(this.menu.num + '') .fontSize(13) } .height(50) .width(100) .margin({ left: 8, right: 8 }) .alignItems(HorizontalAlign.Start) .backgroundColor(Color.White) } }
在MyPage.ets文件中新建MyTransList組件和MoreGrid組件,MyTransList組件效果如如下:
代碼如下:@Component struct MyTransList { private imageItems: ImageItem[] = getTrans() build() { Column() { Text('My Transaction') .fontSize(20) .margin({ left: 10 }) .width('100%') .height(30) Row() { List() { ForEach(this.imageItems, item = > { ListItem() { DataItem({ imageItem: item }) } }, item = > item.id.toString()) } .height(70) .width('100%') .edgeEffect(EdgeEffect.None) .margin({ top: 5 }) .padding({ left: 16, right: 16 }) .listDirection(Axis.Horizontal) } } .height(120) } }
MoreGrid組件效果圖如下:
代碼如下:
@Component struct MoreGrid { private gridRowTemplate: string = '' private imageItems: ImageItem[] = getMore() private heightValue: number aboutToAppear() { var rows = Math.round(this.imageItems.length / 3); this.gridRowTemplate = '1fr '.repeat(rows); this.heightValue = rows * 75; } build() { Column() { Text('More') .fontSize(20) .margin({ left: 10 }) .width('100%') .height(30) Scroll() { Grid() { ForEach(this.imageItems, (item: ImageItem) = > { GridItem() { DataItem({ imageItem: item }) } }, (item: ImageItem) = > item.id.toString()) } .rowsTemplate(this.gridRowTemplate) .columnsTemplate('1fr 1fr 1fr') .columnsGap(8) .rowsGap(8) .height(this.heightValue) } .padding({ left: 16, right: 16 }) } .height(400) } }
在MyTransList和MoreGrid組件中都包含子組件DataItem,為避免的重復(fù)代碼,可以把多次要用到的結(jié)構(gòu)體組件化,這里的結(jié)構(gòu)體就是圖片加上文本的上下結(jié)構(gòu)體,DataItem組件內(nèi)容如下:
@Component struct DataItem { private imageItem: ImageItem build() { Column() { Image(this.imageItem.imageSrc) .objectFit(ImageFit.Contain) .height(50) .width(50) .renderMode(ImageRenderMode.Original) Text(this.imageItem.title) .fontSize(15) } .height(70) .width(150) .margin({ left: 10, right: 10 }) .backgroundColor(Color.White) } }
構(gòu)建商品詳情頁面
從上面效果圖可以看出,商品詳情頁面主要由下面五部分組成:
- 頂部的返回欄。
- Swiper組件。
- 中間多個(gè)Text組件組成的布局。
- 參數(shù)列表。
- 底部的Buy。
在本任務(wù)中,把上面每一部分都封裝成一個(gè)組件,然后再放到入口組件內(nèi),當(dāng)點(diǎn)擊頂部返回圖標(biāo)時(shí)返回到主頁面的商品列表頁簽,點(diǎn)擊底部Buy時(shí),會(huì)觸發(fā)進(jìn)度條彈窗
在pages目錄下面新建一個(gè)ETS Page, 命名為ShoppingDetail.ets,config.json文件pages屬性中也會(huì)自動(dòng)添加“pages/ShoppingDetail”頁面路由。
在ShoppingDetail.ets文件中創(chuàng)建入口組件,組件內(nèi)容如下:
@Entry @Component struct ShoppingDetail { private arsItems: ArsData[] = getArs() build() { Column() { DetailTop() Scroll() { Column() { SwiperTop() DetailText() DetailArsList({ arsItems: this.arsItems }) Image($r('app.media.computer1')) .height(220) .width('100%') .margin({ top: 30 }) Image($r('app.media.computer2')) .height(220) .width('100%') .margin({ top: 30 }) Image($r('app.media.computer3')) .height(220) .width('100%') .margin({ top: 30 }) Image($r('app.media.computer4')) .height(220) .width('100%') .margin({ top: 30 }) Image($r('app.media.computer5')) .height(220) .width('100%') .margin({ top: 30 }) Image($r('app.media.computer6')) .height(220) .width('100%') .margin({ top: 30 }) } .width('100%') .flexGrow(1) } .scrollable(ScrollDirection.Vertical) DetailBottom() } .height('90%') .width('100%') } }
其中頂部DetailTop組件效果圖如下:
代碼如下:
@Component struct DetailTop { build() { Column() { Row() { Image($r('app.media.icon_return')) .height(40) .width(40) .margin({left: 20}) .onClick(() = > { router.push({ uri: "pages/HomePage" }) }) } .width('100%') .height(35) .backgroundColor('#FF87CEEB') } .width('100%') .height(40) } }
SwiperTop組件效果圖如下:
代碼如下:@Component struct SwiperTop { build() { Column() { Swiper() { Image($r('app.media.computer1')) .height(220) .width('100%') Image($r('app.media.computer2')) .height(220) .width('100%') Image($r('app.media.computer3')) .height(220) .width('100%') Image($r('app.media.computer4')) .height(220) .width('100%') Image($r('app.media.computer5')) .height(220) .width('100%') Image($r('app.media.computer6')) .height(220) .width('100%') } .index(0) .autoPlay(true) .interval(3000) .indicator(true) .loop(true) .height(250) .width('100%') } .height(250) .width('100%') } }
DetailText組件效果圖如下:
代碼如下:@Component struct DetailText { build() { Column() { Row() { Image($r('app.media.icon_promotion')) .objectFit(ImageFit.Contain) .height(30) .width(30) .margin({ left: 10 }) Text('Special Offer: ¥9999') .fontColor(Color.White) .fontSize(20) .margin({ left: 10 }) } .width('100%') .height(35) .backgroundColor(Color.Red) Column() { Text('New Arrival: HUAWEI MateBook X Pro 2021') .fontSize(18) .margin({ left: 10 }) .alignSelf(ItemAlign.Start) Text('13.9-Inch, 11th Gen Intel? Core? i7, 16 GB of Memory, 512 GB of Storage, Ultra-slim Business Laptop, 3K FullView Display, Multi-screen Collaboration, Emerald Green') .fontSize(14) .margin({ left: 10 }) Row() { Image($r('app.media.icon_buy')) .objectFit(ImageFit.Contain) .height(30) .width(30) .margin({ left: 10 }) Text('Limited offer') .fontSize(15) .fontColor(Color.Red) .margin({ left: 100 }) } .backgroundColor(Color.Pink) .width('100%') .height(45) .margin({ top: 10 }) Text(' Shipment: 2-day shipping') .fontSize(13) .fontColor(Color.Red) .margin({ left: 10, top: 5 }) .alignSelf(ItemAlign.Start) Text(' Ship To: Hubei,Wuhan,China') .fontSize(13) .fontColor(Color.Red) .margin({ left: 10, top: 5 }) .alignSelf(ItemAlign.Start) .onClick(() = > { prompt.showDialog({ title: 'select address', }) }) Text('Guarantee: Genuine guaranteed') .fontSize(13) .margin({ left: 10, top: 5 }) .alignSelf(ItemAlign.Start) } .height(170) .width('100%') } .height(180) .width('100%') } }
DetailArsList組件效果圖如下:
代碼如下:
@Component struct DetailArsList{ private arsItems: ArsData[] build() { Scroll() { Column() { List() { ForEach(this.arsItems, item = > { ListItem() { ArsListItem({ arsItem: item }) } }, item = > item.id.toString()) } .height('100%') .width('100%') .margin({ top: 5 }) .listDirection(Axis.Vertical) } .height(200) } } }
ArsListItem組件代碼如下:
@Component struct ArsListItem { private arsItem: ArsData build() { Row() { Text(this.arsItem.title + " :") .fontSize(11) .margin({ left: 20 }) .flexGrow(1) Text(this.arsItem.content) .fontSize(11) .margin({ right: 20 }) } .height(14) .width('100%') .backgroundColor(Color.White) } }
DetailBottom組件效果圖如下:
代碼如下:@Component struct DetailBottom { @Provide private value: number= 1 dialogController: CustomDialogController = new CustomDialogController({ builder: DialogExample({ action: this.onAccept }), cancel: this.existApp, autoCancel: true }); onAccept() { } existApp() { } build() { Column() { Text('Buy') .width(40) .height(25) .fontSize(20) .fontColor(Color.White) .onClick(() = > { this.value = 1 this.dialogController.open() }) } .alignItems(HorizontalAlign.Center) .backgroundColor(Color.Red) .width('100%') .height('10%') } }
DialogExample自定義彈窗組件效果圖如下:
代碼如下:
@CustomDialog struct DialogExample { @Consume private value: number controller: CustomDialogController; action: () = > void; build() { Column() { Progress({ value: this.value++ >= 100 ? 100 : this.value, total: 100, style: ProgressStyle.Capsule }) .height(50) .width(100) .margin({ top: 5 }) } .height(60) .width(100) } }
審核編輯 黃宇
-
鴻蒙
+關(guān)注
關(guān)注
57文章
2302瀏覽量
42689 -
HarmonyOS
+關(guān)注
關(guān)注
79文章
1966瀏覽量
29962
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論