HarmonyOS ArkUI之仿微信朋友圈圖片預(yù)覽
51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)
前言
新世界的大門已打開,關(guān)也關(guān)不住!
《華為開發(fā)者大會(huì)2021》推出了方舟開發(fā)框l架(ArkUI),官方解釋:方舟開發(fā)框架是一種跨設(shè)備的高性能UI開發(fā)框架,支持聲明式編程和跨設(shè)備多態(tài)UI。
本項(xiàng)目就是基于ArkUI中的聲明式編程開發(fā),語言ETS(Extended Type Script),代碼都在ets文件中編寫,這個(gè)文件用于描述 UI 布局、樣式、事件交互和頁面邏輯。
官方文檔地址:基于TS擴(kuò)展的聲明式開發(fā)范式1 基于TS擴(kuò)展的聲明式開發(fā)范式2
本文介紹仿微信朋友圈實(shí)現(xiàn)列表展示,九宮格小圖圖片展示,點(diǎn)擊圖片進(jìn)行圖片預(yù)覽,圖片左右滑動(dòng)切換。
效果演示
項(xiàng)目類說明
主要知識(shí)點(diǎn)
九宮格列表和選擇圖片列表:網(wǎng)格容器組件(Grid)
瀏覽大圖切換頁面:滑動(dòng)容器組件(Swiper)
循環(huán)渲染迭代數(shù)組:渲染組件(ForEach) (目前第二個(gè)參數(shù)中 itemGenerator: (item: any, index?: number) => void index不能使用)
基礎(chǔ)的組件:圖片顯示(Image) 文本顯示(Text) 按鈕(Button)
布局容器組件:沿垂直方向布局的容器(Column),沿水平方向布局容器(Row),堆疊容器(Stack)
代碼解析
1、朋友圈列表展示
列表使用List組件實(shí)現(xiàn)多數(shù)據(jù)列表展示(核心代碼實(shí)例)。
- List({ initialIndex: 0 }) {
- ForEach(this.listItems, item => {
- ListItem() {
- Row() {
- Column() {
- Image(item.bigImg)
- .width(50)
- .height(50)
- .borderRadius(30)
- .margin(5)
- .onClick(() => {
- })
- Blank()
- }.height("100%")
- Column() {
- Text(item.name)
- .fontSize(16)
- .margin({ left: 0})
- .width("100%")
- Row() {
- Text(item.content)
- .fontSize(14)
- .margin({ top: 10 })
- .fontColor(Color.Grey)
- .width("80%")
- .textAlign(TextAlign.Start)
- Blank()
- }
- Column() {
- Grid() {
- ForEach(this.imageDataArray, item => {
- GridItem() {
- Image(item.smallImg).width(50).height(50)
- }.sharedTransition("0", { duration: 100, curve: Curve.Linear })
- .onClick(()=>{
- console.log("item.id==="+item.id)
- router.push({
- uri: 'pages/imageflige',
- params: {
- imageIndex: item.id, // 當(dāng)前圖片位置
- }
- })
- })
- }, item => item.name)
- }
- .width(155)
- .columnsTemplate('1fr 1fr 1fr')
- .rowsGap(2)
- .columnsGap(2)
- }
- .width('100%')
- .height(200)
- .alignItems(HorizontalAlign.Start)
- .margin({ top: 10 })
- }.height("100%")
- }
- .height("100%")
- }
- .height(250)
- .margin({ top: 10 })
- }, item => item.name)
- }
2、九宮格展示
主要是網(wǎng)格容器Grid組件和渲染組件ForEach(核心代碼示例)。
- Column() {
- Grid() {
- ForEach(this.imageDataArray, item => {
- GridItem() {
- Image(item.smallImg).width(50).height(50)
- }.sharedTransition("0", { duration: 100, curve: Curve.Linear })
- .onClick(()=>{
- console.log("item.id==="+item.id)
- router.push({
- uri: 'pages/imageflige',
- params: {
- imageIndex: item.id, // 當(dāng)前圖片位置
- }
- })
- })
- }, item => item.name)
- }
- .width(155)
- .columnsTemplate('1fr 1fr 1fr')
- .rowsGap(2)
- .columnsGap(2)
- }
- .width('100%')
- .height(200)
- .alignItems(HorizontalAlign.Start)
- .margin({ top: 10 })
3、大圖預(yù)覽
使用滑動(dòng)容器組件Swiper,通過傳遞點(diǎn)擊的當(dāng)前下標(biāo)定位到指定位置(核心代碼示例)。
- import router from '@system.router';
- @Entry
- @Component
- struct Imageflige {
- @State private listPicture: Array<Resource> = [
- $r("app.media.food1"), $r("app.media.food2"), $r("app.media.food3"),
- $r("app.media.food4"), $r("app.media.food5"), $r("app.media.food1"),
- $r("app.media.food2"), $r("app.media.food3"), $r("app.media.food4")
- ]
- @State imageIndex: number = 0
- build() {
- Column() {
- Stack({ alignContent: Alignment.Top }) {
- // 切換頁面
- Swiper() {
- ForEach(this.listPicture, item => {
- // 圖片
- Image(item)
- .width('100%')
- .height('100%')
- .objectFit(ImageFit.Contain) //縮放類型
- }, item => item.toString())
- }
- .width('100%')
- .height('100%')
- .index(this.imageIndex) // 設(shè)置當(dāng)前索引
- .indicator(true) // 不顯示指示器
- .loop(true) // 關(guān)閉循環(huán)
- .sharedTransition("0", { duration: 100, curve: Curve.Linear })
- .onChange((index: number) => { // 索引變化監(jiān)聽
- // 更新索引值
- this.imageIndex = index
- })
- Image($r("app.media.back"))
- .width(35)
- .height(35)
- .margin(10)
- .backgroundColor(Color.White)
- .onClick(() => {
- router.back()
- })
- }
- .height("100%")
- .width("100%")
- .alignContent(Alignment.TopStart)
- }
- }
- private aboutToAppear() {
- this.imageIndex = router.getParams().imageIndex
- }
- }
評(píng)論功能有兩部分:評(píng)論列表和評(píng)論發(fā)送輸入框。
51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)