鴻蒙HarmonyOS中的ArkUI組件庫特性與常用組件實(shí)例演示
本文介紹了HarmonyOS的ArkUI組件庫及其核心特性,詳細(xì)講解了15個(gè)常用組件的使用方法,并通過創(chuàng)建一個(gè)電商首頁組件展示了組件的布局和交互效果優(yōu)化,文章還提供了項(xiàng)目運(yùn)行步驟和效果驗(yàn)證,幫助讀者掌握組件的開發(fā)和優(yōu)化技巧。
學(xué)習(xí)目標(biāo):
- 理解ArkUI組件的分類與核心特性;
- 掌握15個(gè)常用ArkUI組件的用法(布局容器、文本、按鈕、輸入框、列表、網(wǎng)格等);
- 實(shí)現(xiàn)一個(gè)電商首頁組件(包含輪播圖、分類導(dǎo)航、商品列表、底部導(dǎo)航欄);
- 優(yōu)化組件交互效果(懸停、點(diǎn)擊、滑動(dòng)動(dòng)畫)。
學(xué)習(xí)重點(diǎn):
- 彈性布局(Flex)與網(wǎng)格布局(Grid)的深度應(yīng)用;
- 自定義組件與系統(tǒng)組件的結(jié)合使用;
- 響應(yīng)式布局的實(shí)現(xiàn)(適配不同設(shè)備尺寸)。

一、 ArkUI組件庫概述 ??
1.1 組件分類
HarmonyOS Next的ArkUI組件庫分為基礎(chǔ)組件和高級組件:
| 分類 | 組件示例 |
|---|---|
| 基礎(chǔ)組件 | Text、Image、Button、Input、TextArea、Checkbox、Radio、Slider、Switch |
| 容器組件 | Column、Row、Flex、Grid、GridItem、List、ListItem、Stack |
| 高級組件 | Swiper(輪播圖)、TabContent(標(biāo)簽頁)、Carousel(卡片輪播)、WaterFlow(瀑布流) |
1.2 核心特性
- 聲明式UI:通過代碼描述UI結(jié)構(gòu),編譯器自動(dòng)渲染;
- 數(shù)據(jù)驅(qū)動(dòng):組件屬性與狀態(tài)數(shù)據(jù)綁定,數(shù)據(jù)變化自動(dòng)更新UI;
- 響應(yīng)式布局:自動(dòng)適配不同設(shè)備尺寸;
- 組件復(fù)用:支持自定義組件,提高代碼復(fù)用率;
- 高性能渲染:采用方舟編譯器編譯,渲染效率比傳統(tǒng)Web開發(fā)高10-20倍。
二、 常用組件實(shí)戰(zhàn) ???
2.1 實(shí)戰(zhàn)目標(biāo)
基于第1篇的「MyFirstHarmonyApp」項(xiàng)目架構(gòu),創(chuàng)建一個(gè)電商首頁組件,包含以下功能:
- 輪播圖(Swiper):展示促銷活動(dòng);
- 分類導(dǎo)航(Grid):顯示商品分類;
- 商品列表(List):展示熱門商品;
- 底部導(dǎo)航欄(TabBar):實(shí)現(xiàn)頁面切換。
2.2 ?? 項(xiàng)目結(jié)構(gòu)調(diào)整
在「entry/src/main/ets」目錄下創(chuàng)建以下文件夾:
components:存放自定義組件;models:存放數(shù)據(jù)模型;utils:存放工具函數(shù)。
2.3 ?? 數(shù)據(jù)模型與工具函數(shù)
1. 數(shù)據(jù)模型
?? entry/src/main/ets/models/HomeModel.ets
// 輪播圖數(shù)據(jù)模型
export interface BannerModel {
id: number;
imageUrl: string;
linkUrl: string;
}
// 分類導(dǎo)航數(shù)據(jù)模型
export interface CategoryModel {
id: number;
name: string;
iconUrl: string;
}
// 商品數(shù)據(jù)模型
export interface GoodsModel {
id: number;
name: string;
imageUrl: string;
price: number;
originalPrice: number;
sales: number;
}
// 底部導(dǎo)航欄數(shù)據(jù)模型
export interface TabBarModel {
id: number;
name: string;
iconUrl: string;
selectedIconUrl: string;
pageUrl: string;
}
2. 工具函數(shù)
?? entry/src/main/ets/utils/ImageUtils.ets
// 圖片加載工具函數(shù)
export function getImageUrl(imagePath: string): string {
return `$r('app.media.${imagePath}')`;
}
3. 模擬數(shù)據(jù)
?? entry/src/main/ets/models/HomeData.ets
import { BannerModel, CategoryModel, GoodsModel, TabBarModel } from './HomeModel';
import { getImageUrl } from '../utils/ImageUtils';
// 輪播圖模擬數(shù)據(jù)
export const bannerData: Array<BannerModel> = [
{ id: 1, imageUrl: getImageUrl('banner1'), linkUrl: 'pages/ProductDetailPage' },
{ id: 2, imageUrl: getImageUrl('banner2'), linkUrl: 'pages/ProductDetailPage' },
{ id: 3, imageUrl: getImageUrl('banner3'), linkUrl: 'pages/ProductDetailPage' }
];
// 分類導(dǎo)航模擬數(shù)據(jù)
export const categoryData: Array<CategoryModel> = [
{ id: 1, name: '手機(jī)', iconUrl: getImageUrl('category1') },
{ id: 2, name: '平板', iconUrl: getImageUrl('category2') },
{ id: 3, name: '筆記本', iconUrl: getImageUrl('category3') },
{ id: 4, name: '智能穿戴', iconUrl: getImageUrl('category4') },
{ id: 5, name: '家居', iconUrl: getImageUrl('category5') },
{ id: 6, name: '出行', iconUrl: getImageUrl('category6') }
];
// 商品模擬數(shù)據(jù)
export const goodsData: Array<GoodsModel> = [
{ id: 1, name: '華為Mate 60 Pro', imageUrl: getImageUrl('goods1'), price: 6999, originalPrice: 7999, sales: 12345 },
{ id: 2, name: '華為P60 Pro', imageUrl: getImageUrl('goods2'), price: 5999, originalPrice: 6999, sales: 8765 },
{ id: 3, name: '華為nova 12 Pro', imageUrl: getImageUrl('goods3'), price: 3999, originalPrice: 4999, sales: 6543 },
{ id: 4, name: '華為MateBook X Pro', imageUrl: getImageUrl('goods4'), price: 8999, originalPrice: 9999, sales: 4321 },
{ id: 5, name: '華為Watch GT 4', imageUrl: getImageUrl('goods5'), price: 1499, originalPrice: 1699, sales: 2109 }
];
// 底部導(dǎo)航欄模擬數(shù)據(jù)
export const tabBarData: Array<TabBarModel> = [
{ id: 1, name: '首頁', iconUrl: getImageUrl('tab1'), selectedIconUrl: getImageUrl('tab1_selected'), pageUrl: 'pages/Index' },
{ id: 2, name: '分類', iconUrl: getImageUrl('tab2'), selectedIconUrl: getImageUrl('tab2_selected'), pageUrl: 'pages/CategoryPage' },
{ id: 3, name: '購物車', iconUrl: getImageUrl('tab3'), selectedIconUrl: getImageUrl('tab3_selected'), pageUrl: 'pages/CartPage' },
{ id: 4, name: '我的', iconUrl: getImageUrl('tab4'), selectedIconUrl: getImageUrl('tab4_selected'), pageUrl: 'pages/MyPage' }
];
2.4 ?? 自定義組件實(shí)現(xiàn)
1. 輪播圖組件
?? entry/src/main/ets/components/BannerComponent.ets
import { BannerModel } from '../models/HomeModel';
import router from '@ohos.router';
@Component
export struct BannerComponent {
@Prop data: Array<BannerModel> = [];
build() {
Swiper() {
ForEach(this.data, (item: BannerModel) => {
Image(item.imageUrl)
.width('100%')
.height(200)
.objectFit(ImageFit.Cover)
.borderRadius(12)
.onClick(() => {
router.pushUrl({ url: item.linkUrl });
});
}, (item: BannerModel) => item.id.toString());
}
.width('100%')
.height(200)
.autoPlay(true)
.indicator({
style: IndicatorStyle.Number,
isShow: true,
size: 12
})
.loop(true)
.duration(3000);
}
}
2. 分類導(dǎo)航組件
?? entry/src/main/ets/components/CategoryComponent.ets
import { CategoryModel } from '../models/HomeModel';
import router from '@ohos.router';
@Component
export struct CategoryComponent {
@Prop data: Array<CategoryModel> = [];
build() {
Grid() {
ForEach(this.data, (item: CategoryModel) => {
GridItem() {
Column({ space: 8 }) {
Image(item.iconUrl)
.width(50)
.height(50)
.objectFit(ImageFit.Contain);
Text(item.name)
.fontSize(14)
.textColor('#666666');
}
.width('100%')
.height('100%')
.onClick(() => {
router.pushUrl({ url: 'pages/CategoryPage' });
});
}
.width('33.33%')
.height('auto');
}, (item: CategoryModel) => item.id.toString());
}
.width('100%')
.height('auto')
.columnsTemplate('1fr 1fr 1fr')
.rowsTemplate('1fr 1fr')
.columnsGap(20)
.rowsGap(20);
}
}
3. 商品列表組件
?? entry/src/main/ets/components/GoodsListComponent.ets
import { GoodsModel } from '../models/HomeModel';
import router from '@ohos.router';
@Component
export struct GoodsListComponent {
@Prop data: Array<GoodsModel> = [];
build() {
List({ space: 16 }) {
ForEach(this.data, (item: GoodsModel) => {
ListItem() {
GoodsItemComponent({ goods: item });
}
.width('100%')
.height('auto');
}, (item: GoodsModel) => item.id.toString());
}
.width('100%')
.height('auto')
.padding(0, 16, 0, 16);
}
}
@Component
struct GoodsItemComponent {
@Prop goods: GoodsModel;
build() {
Column({ space: 12 }) {
// 商品圖片
Image(this.goods.imageUrl)
.width('100%')
.height(200)
.objectFit(ImageFit.Cover)
.borderRadius(12);
// 商品信息
Column({ space: 8 }) {
Text(this.goods.name)
.fontSize(16)
.fontWeight(FontWeight.Bold)
.textColor('#000000')
.maxLines(2)
.ellipsis({ overflow: TextOverflow.Ellipsis });
// 價(jià)格與銷量
Row({ space: 16 }) {
Column({ space: 4 }) {
Text(`¥${this.goods.price}`)
.fontSize(18)
.fontWeight(FontWeight.Bold)
.textColor('#FF0000');
Text(`¥${this.goods.originalPrice}`)
.fontSize(14)
.textColor('#999999')
.decoration({ type: TextDecorationType.LineThrough });
}
.alignItems(HorizontalAlign.Start);
Text(`已售${this.goods.sales}`)
.fontSize(14)
.textColor('#666666');
}
.width('100%')
.justifyContent(FlexAlign.SpaceBetween);
}
.width('100%')
.alignItems(HorizontalAlign.Start)
.padding(0, 0, 0, 8);
}
.width('100%')
.height('auto')
.padding(16)
.backgroundColor('#FFFFFF')
.borderRadius(12)
.onClick(() => {
router.pushUrl({ url: 'pages/ProductDetailPage' });
});
}
}
4. 底部導(dǎo)航欄組件
?? entry/src/main/ets/components/TabBarComponent.ets
import { TabBarModel } from '../models/HomeModel';
import router from '@ohos.router';
@Component
export struct TabBarComponent {
@Prop data: Array<TabBarModel> = [];
@Prop selectedIndex: number = 0;
build() {
Row({ space: 0 }) {
ForEach(this.data, (item: TabBarModel, index: number) => {
Column({ space: 4 }) {
Image(index === this.selectedIndex ? item.selectedIconUrl : item.iconUrl)
.width(24)
.height(24)
.objectFit(ImageFit.Contain);
Text(item.name)
.fontSize(12)
.textColor(index === this.selectedIndex ? '#007DFF' : '#666666');
}
.width('25%')
.height('100%')
.justifyContent(FlexAlign.Center)
.onClick(() => {
router.pushUrl({ url: item.pageUrl });
});
}, (item: TabBarModel) => item.id.toString());
}
.width('100%')
.height(56)
.backgroundColor('#FFFFFF')
.borderRadius(16, 16, 0, 0)
.padding(0, 8, 0, 8);
}
}
2.5 ?? 首頁頁面實(shí)現(xiàn)
?? entry/src/main/ets/pages/Index.ets(替換默認(rèn)代碼)
import { BannerComponent } from '../components/BannerComponent';
import { CategoryComponent } from '../components/CategoryComponent';
import { GoodsListComponent } from '../components/GoodsListComponent';
import { TabBarComponent } from '../components/TabBarComponent';
import { bannerData, categoryData, goodsData, tabBarData } from '../models/HomeData';
@Entry
@Component
struct Index {
@State selectedIndex: number = 0;
build() {
Column({ space: 0 }) {
// 頁面內(nèi)容
Scroll() {
Column({ space: 24 }) {
// 輪播圖
BannerComponent({ data: bannerData });
// 分類導(dǎo)航
CategoryComponent({ data: categoryData });
// 熱門商品標(biāo)題
Text('熱門商品')
.fontSize(18)
.fontWeight(FontWeight.Bold)
.textColor('#000000')
.width('100%')
.padding(0, 0, 0, 16);
// 商品列表
GoodsListComponent({ data: goodsData });
}
.width('100%')
.padding(20);
}
.width('100%')
.height('100%')
.layoutWeight(1);
// 底部導(dǎo)航欄
TabBarComponent({
data: tabBarData,
selectedIndex: this.selectedIndex
});
}
.width('100%')
.height('100%')
.backgroundColor('#F5F5F5');
}
}
三、 組件交互效果優(yōu)化 ??
3.1 懸停動(dòng)畫
為商品列表組件添加懸停動(dòng)畫,提升用戶體驗(yàn):
?? entry/src/main/ets/components/GoodsListComponent.ets(修改GoodsItemComponent)
@Component
struct GoodsItemComponent {
@Prop goods: GoodsModel;
@State isHover: boolean = false;
build() {
Column({ space: 12 }) {
// 商品圖片
Image(this.goods.imageUrl)
.width('100%')
.height(200)
.objectFit(ImageFit.Cover)
.borderRadius(12)
.scale({ x: this.isHover ? 1.05 : 1, y: this.isHover ? 1.05 : 1 })
.transition({ duration: 300, curve: Curve.EaseOut });
// 商品信息
// ...
}
.width('100%')
.height('auto')
.padding(16)
.backgroundColor('#FFFFFF')
.borderRadius(12)
.onClick(() => {
router.pushUrl({ url: 'pages/ProductDetailPage' });
})
.onHover(() => {
this.isHover = true;
})
.onHoverEnd(() => {
this.isHover = false;
});
}
}
3.2 點(diǎn)擊動(dòng)畫
為按鈕組件添加點(diǎn)擊動(dòng)畫,反饋用戶操作:
?? entry/src/main/ets/components/GoodsListComponent.ets(添加立即購買按鈕)
@Component
struct GoodsItemComponent {
@Prop goods: GoodsModel;
@State isHover: boolean = false;
@State isPressed: boolean = false;
build() {
Column({ space: 12 }) {
// 商品圖片
// ...
// 商品信息
Column({ space: 8 }) {
// 商品名稱
// ...
// 價(jià)格與銷量
// ...
// 立即購買按鈕
Button('立即購買')
.width('100%')
.height(48)
.backgroundColor('#007DFF')
.onClick(() => {
console.log('點(diǎn)擊了立即購買按鈕');
})
.onPress(() => {
this.isPressed = true;
})
.onPressEnd(() => {
this.isPressed = false;
})
.scale({ x: this.isPressed ? 0.95 : 1, y: this.isPressed ? 0.95 : 1 })
.transition({ duration: 100, curve: Curve.EaseOut });
}
.width('100%')
.alignItems(HorizontalAlign.Start)
.padding(0, 0, 0, 8);
}
.width('100%')
.height('auto')
.padding(16)
.backgroundColor('#FFFFFF')
.borderRadius(12)
.onClick(() => {
router.pushUrl({ url: 'pages/ProductDetailPage' });
})
.onHover(() => {
this.isHover = true;
})
.onHoverEnd(() => {
this.isHover = false;
});
}
}
四、 項(xiàng)目運(yùn)行與效果驗(yàn)證 ??
4.1 圖片資源準(zhǔn)備
在「entry/src/main/resources/base/media」目錄下添加以下圖片資源(圖片格式為.png,尺寸符合要求):
banner1.png、banner2.png、banner3.png(輪播圖);category1.png、category2.png、category3.png、category4.png、category5.png、category6.png(分類導(dǎo)航);goods1.png、goods2.png、goods3.png、goods4.png、goods5.png(商品列表);tab1.png、tab1_selected.png、tab2.png、tab2_selected.png、tab3.png、tab3_selected.png、tab4.png、tab4_selected.png(底部導(dǎo)航欄)。
4.2 ?? 項(xiàng)目運(yùn)行
① 在DevEco Studio中點(diǎn)擊「Run」按鈕;
② 選擇調(diào)試設(shè)備,點(diǎn)擊「OK」;
③ 等待編譯安裝完成,應(yīng)用會自動(dòng)在設(shè)備上啟動(dòng)。
效果驗(yàn)證
? 輪播圖:自動(dòng)輪播促銷活動(dòng),點(diǎn)擊可跳轉(zhuǎn);
? 分類導(dǎo)航:顯示6個(gè)商品分類,點(diǎn)擊可跳轉(zhuǎn);
? 商品列表:顯示5個(gè)熱門商品,懸停有動(dòng)畫效果;
? 底部導(dǎo)航欄:實(shí)現(xiàn)4個(gè)頁面的切換;
? 響應(yīng)式布局:自動(dòng)適配不同設(shè)備尺寸。
五、 總結(jié)與未來學(xué)習(xí)路徑 ??
5.1 總結(jié)
本文完成:
- 對ArkUI組件庫分類與核心特性的理解;
- 15個(gè)常用ArkUI組件的實(shí)戰(zhàn)應(yīng)用;
- 一個(gè)完整的電商首頁組件的創(chuàng)建;
- 組件交互效果的優(yōu)化(懸停、點(diǎn)擊動(dòng)畫)。
到此這篇關(guān)于鴻蒙HarmonyOS中的ArkUI組件庫特性與常用組件實(shí)例演示的文章就介紹到這了,更多相關(guān)鴻蒙HarmonyOS的ArkUI組件庫內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- HarmonyOS中使用Node-API開發(fā)的典型場景示例
- HarmonyOS系統(tǒng)利用AVPlayer開發(fā)視頻播放功能
- 鴻蒙中@State的原理使用詳解(HarmonyOS 5)
- HarmonyOS Next音樂播放器項(xiàng)目實(shí)現(xiàn)代碼
- 鴻蒙HarmonyOS開發(fā):Navigation路由導(dǎo)航功能和實(shí)踐
- 鴻蒙(HarmonyOS)實(shí)現(xiàn)隱私政策彈窗效果
- 鴻蒙HarmonyOS App開發(fā)造輪子之自定義圓形圖片組件的實(shí)例代碼
- 鴻蒙開發(fā)之處理圖片位圖操作的方法詳解(HarmonyOS鴻蒙開發(fā)基礎(chǔ)知識)
相關(guān)文章
Android 中Fragment與Activity通訊的詳解
這篇文章主要介紹了Android 中Fragment與Activity通訊的詳解的相關(guān)資料,希望通過本文能幫助到大家,讓大家理解掌握如何通信的,需要的朋友可以參考下2017-10-10
Android利用動(dòng)畫實(shí)現(xiàn)背景逐漸變暗
這篇文章主要為大家詳細(xì)介紹了Android利用動(dòng)畫實(shí)現(xiàn)背景逐漸變暗的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-12-12
Android2.3實(shí)現(xiàn)Android4.0風(fēng)格EditText的方法
這篇文章主要介紹了Android2.3實(shí)現(xiàn)Android4.0風(fēng)格EditText的方法,涉及Android界面布局及控件調(diào)用的相關(guān)技巧,需要的朋友可以參考下2016-03-03
基于Android6.0實(shí)現(xiàn)彈出Window提示框
這篇文章主要為大家詳細(xì)介紹了基于Android6.0實(shí)現(xiàn)彈出Window提示框,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-10-10
Android集成GreenDao數(shù)據(jù)庫的操作步驟
這篇文章主要介紹了Android集成GreenDao數(shù)據(jù)庫,使用數(shù)據(jù)庫存儲時(shí)候,一般都會使用一些第三方ORM框架,比如GreenDao,本文分幾步給大家介紹Android集成GreenDao數(shù)據(jù)庫的方法,需要的朋友可以參考下2022-10-10
android開發(fā)教程之開機(jī)啟動(dòng)服務(wù)service示例
如果開機(jī)啟動(dòng)一個(gè)Activity,開機(jī)首先看的界面,是你的程序界面,如果為了,開機(jī)后也啟動(dòng)你的程序,但是不顯示自己程序的界面,就要用Service服務(wù),下面是開機(jī)啟動(dòng)服務(wù)service示例2014-03-03
3種Android隱藏頂部狀態(tài)欄及標(biāo)題欄的方法
這篇文章主要為大家詳細(xì)介紹了3種Android隱藏頂部狀態(tài)欄及標(biāo)題欄的方法,還涉及一種隱藏Android 4.0平板底部狀態(tài)欄的方法,感興趣的小伙伴們可以參考一下2016-02-02
Android 高仿微信轉(zhuǎn)賬金錢輸入框規(guī)則
這篇文章主要介紹了Android 高仿微信金錢輸入框規(guī)則的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-12-12
基于Android實(shí)現(xiàn)可滾動(dòng)的環(huán)形菜單效果
這篇文章主要為大家詳細(xì)介紹了Android如何使用kotlin實(shí)現(xiàn)可滾動(dòng)的環(huán)形菜單,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03

