網(wǎng)格元素交換案例
介紹
直接進(jìn)行交換和刪除元素會(huì)給用戶帶來(lái)不好的體驗(yàn)效果,因此需要在此過(guò)程中注入一些特色的動(dòng)畫(huà)來(lái)提升體驗(yàn)效果,本案例通過(guò)Grid組件、attributeModifier、以
及animateTo函數(shù)實(shí)現(xiàn)了拖拽動(dòng)畫(huà)和刪除動(dòng)畫(huà)。
效果圖預(yù)覽
使用說(shuō)明:
- 進(jìn)入頁(yè)面,點(diǎn)擊編輯,長(zhǎng)按網(wǎng)格元素,執(zhí)行拖拽操作,拖拽過(guò)程中顯示此網(wǎng)格元素,拖拽到一定的位置時(shí),會(huì)進(jìn)行網(wǎng)格元素的位置交換。
- 編輯模式下,點(diǎn)擊網(wǎng)格元素,此元素會(huì)被刪除。
實(shí)現(xiàn)思路
本示例主要通過(guò)attributeModifier、supportAnimation、animateTo等實(shí)現(xiàn)了刪除動(dòng)畫(huà)以及長(zhǎng)按拖拽動(dòng)畫(huà)。attributeModifier綁定自定義屬性對(duì)象,
控制每個(gè)網(wǎng)格元素的屬性更新。執(zhí)行刪除操作時(shí),通過(guò)animateTo去更新offset值以及opacity等屬性。supportAnimation設(shè)置為true,支持GridItem
拖拽動(dòng)畫(huà),在onItemDragStart開(kāi)始拖拽網(wǎng)格元素時(shí)觸發(fā),onItemDragStart可以返回一個(gè)@Builder修飾的自定義組件,這樣在拖拽的時(shí)候,
能夠顯示目標(biāo)元素。onItemDrop在網(wǎng)格元素內(nèi)停止拖拽時(shí)觸發(fā)。此時(shí)執(zhí)行元素位置的切換功能。
- 聲明一個(gè)數(shù)組,添加自定義屬性對(duì)象,每個(gè)自定義屬性對(duì)象對(duì)應(yīng)一個(gè)網(wǎng)格元素,源碼參考AttributeModifier.ets和GridItemDeletionCtrl.ets。
constructor(data: T[]) {
this.gridData = data;
data.forEach(() => {
this.modifier.push(new GridItemModifier());
})
}
/**
* 聲明GridItem動(dòng)態(tài)屬性
*/
@Observed
export class GridItemModifier implements AttributeModifier<GridItemAttribute> {
public offsetX: number = 0;
public offsetY: number = 0;
public opacity: number = 1;
/**
* 定義組件普通狀態(tài)時(shí)的樣式
* @param instance
*/
applyNormalAttribute(instance: GridItemAttribute): void {
instance.translate({ x: this.offsetX, y: this.offsetY });
instance.opacity(this.opacity);
}
}
- 綁定attributeModifier屬性,attributeModifier屬性的值為對(duì)應(yīng)的自定義屬性對(duì)象。源碼參考GridExchange.ets。
GridItem() {
IconWithNameView({ app: item })
}
.onAreaChange((oldValue: Area, newValue: Area) => {
this.itemAreaWidth = Number(newValue.width);
})
.onTouch((event: TouchEvent) => {
if (event.type === TouchType.Down) {
this.movedItem = this.appInfoList[index];
}
})
// TODO:知識(shí)點(diǎn):動(dòng)態(tài)綁定屬性信息
.attributeModifier(this.GridItemDeletion.getModifier(item) ? this.GridItemDeletion.getModifier(item) : undefined)
- 編輯模式下點(diǎn)擊網(wǎng)格元素,執(zhí)行刪除操作,刪除過(guò)程中使用animateTo來(lái)更新元素的偏移量并實(shí)現(xiàn)動(dòng)畫(huà)效果。源碼參考GridItemDeletionCtrl.ets。
deleteGridItem(item: T, itemAreaWidth: number): void {
const index: number = this.gridData.indexOf(item);
// 最后一條數(shù)據(jù)不執(zhí)行偏移
if (index === this.gridData.length - 1) {
this.gridData.splice(index, 1);
this.modifier.splice(index, 1);
return;
}
// TODO:知識(shí)點(diǎn):實(shí)現(xiàn)刪除動(dòng)畫(huà)。先讓目標(biāo)元素的opacity為0,不可視,直接刪除目標(biāo)元素會(huì)導(dǎo)致偏移的時(shí)候位置異常,接著遍歷元素的屬性對(duì)象,修改偏移量。
this.modifier[index].opacity = 0;
animateTo({
curve: Curve.Friction, duration: ANIMATION_DURATION, onFinish: () => {
// 初始化偏移位置
this.modifier.forEach((item) => {
item.offsetX = 0;
item.offsetY = 0;
})
// 刪除對(duì)應(yīng)的數(shù)據(jù)
this.gridData.splice(index, 1);
this.modifier.splice(index, 1);
this.status = DeletionStatus.FINISH;
}
}, () => {
this.modifier.forEach((item: GridItemModifier, ind: number) => {
if (ind > index && ind % COLUMN_COUNT !== 0) {
item.offsetX = -itemAreaWidth;
} else if (ind > index && ind % COLUMN_COUNT === 0) {
item.offsetX = itemAreaWidth * 4; // 位置偏移到上一行的最后一列,因此偏移4個(gè)gridItem所占的寬度
item.offsetY = -GRID_ITEM_HEIGHT;
}
})
this.status = DeletionStatus.START;
})
}
- 交換網(wǎng)格元素,onItemDragStart以及onItemDrop來(lái)完成元素的交換功能,supportAnimation設(shè)置為true,支持在拖拽時(shí)顯示動(dòng)畫(huà)效果。onItemDragStart函數(shù)中
返回目標(biāo)自定義組件,可以在拖拽過(guò)程中顯示。onItemDrop函數(shù)執(zhí)行最后網(wǎng)格元素的交換。 源碼參考GridExchange.ets。
.supportAnimation(true)
.editMode(this.isEdit)
.onItemDragStart((event: ItemDragInfo, itemIndex: number) => {
// TODO:知識(shí)點(diǎn):在onItemDragStart函數(shù)返回自定義組件,可在拖拽過(guò)程中顯示此自定義組件。
return this.pixelMapBuilder();
})
.onItemDrop((event: ItemDragInfo, itemIndex: number, insertIndex: number, isSuccess: boolean) => {
// TODO:知識(shí)點(diǎn):執(zhí)行g(shù)ridItem切換操作
if (isSuccess && insertIndex < this.appInfoList.length) {
this.changeIndex(itemIndex, insertIndex);
}
})
高性能知識(shí)點(diǎn)
- 動(dòng)態(tài)加載數(shù)據(jù)場(chǎng)景可以使用LazyForEach遍歷數(shù)據(jù)。
-
onAreaChange
在區(qū)域發(fā)生大小變化的時(shí)候會(huì)進(jìn)行調(diào)用,由于刪除操作或者網(wǎng)格元素的交互都能夠觸發(fā)區(qū)域函數(shù)的使用,操作頻繁,
建議此處減少日志的打印、復(fù)用函數(shù)邏輯來(lái)降低性能的內(nèi)耗。 -
onTouch
在進(jìn)行手勢(shì)操作的時(shí)候會(huì)進(jìn)行多次調(diào)用,建議此處減少日志的打印、復(fù)用函數(shù)邏輯來(lái)降低性能的內(nèi)耗。
工程結(jié)構(gòu)&模塊類型
gridexchange // har類型
|---model
| |---AppInfo.ets // App信息
| |---AttributeModifier.ets // 屬性對(duì)象
| |---GridItemDeletionCtrl.ets // 列表項(xiàng)交換
| |---MockData.ets // 模擬數(shù)據(jù)
|---view
| |---GridExchange.ets // 視圖層-應(yīng)用主頁(yè)面
模塊依賴
本實(shí)例依賴common模塊來(lái)實(shí)現(xiàn)日志的打印、資源 的調(diào)用、依賴動(dòng)態(tài)路由模塊來(lái)實(shí)現(xiàn)頁(yè)面的動(dòng)態(tài)加載。
參考資料
Grid
animateTo
attributeModifier
為了能讓大家更好的學(xué)習(xí)鴻蒙(HarmonyOS NEXT)開(kāi)發(fā)技術(shù),這邊特意整理了《鴻蒙開(kāi)發(fā)學(xué)習(xí)手冊(cè)》(共計(jì)890頁(yè)),希望對(duì)大家有所幫助:https://qr21.cn/FV7h05
《鴻蒙開(kāi)發(fā)學(xué)習(xí)手冊(cè)》:
如何快速入門(mén):https://qr21.cn/FV7h05
- 基本概念
- 構(gòu)建第一個(gè)ArkTS應(yīng)用
- ……
開(kāi)發(fā)基礎(chǔ)知識(shí):https://qr21.cn/FV7h05
- 應(yīng)用基礎(chǔ)知識(shí)
- 配置文件
- 應(yīng)用數(shù)據(jù)管理
- 應(yīng)用安全管理
- 應(yīng)用隱私保護(hù)
- 三方應(yīng)用調(diào)用管控機(jī)制
- 資源分類與訪問(wèn)
- 學(xué)習(xí)ArkTS語(yǔ)言
- ……
基于ArkTS 開(kāi)發(fā):https://qr21.cn/FV7h05
- Ability開(kāi)發(fā)
- UI開(kāi)發(fā)
- 公共事件與通知
- 窗口管理
- 媒體
- 安全
- 網(wǎng)絡(luò)與鏈接
- 電話服務(wù)
- 數(shù)據(jù)管理
- 后臺(tái)任務(wù)(Background Task)管理
- 設(shè)備管理
- 設(shè)備使用信息統(tǒng)計(jì)
- DFX
- 國(guó)際化開(kāi)發(fā)
- 折疊屏系列
- ……
鴻蒙開(kāi)發(fā)面試真題(含參考答案):https://qr18.cn/F781PH
鴻蒙開(kāi)發(fā)面試大盤(pán)集篇(共計(jì)319頁(yè)):https://qr18.cn/F781PH
1.項(xiàng)目開(kāi)發(fā)必備面試題
2.性能優(yōu)化方向
3.架構(gòu)方向
4.鴻蒙開(kāi)發(fā)系統(tǒng)底層方向
5.鴻蒙音視頻開(kāi)發(fā)方向
6.鴻蒙車載開(kāi)發(fā)方向
7.鴻蒙南向開(kāi)發(fā)方向文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-856873.html
文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-856873.html
到了這里,關(guān)于HarmonyOS NEXT 網(wǎng)格元素交換案例的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!