介紹
本示例介紹運用Stack元件以構建多層次堆疊的視覺效果。透過繫結Scroll元件的onScroll滾動事件回撥函式,精準捕獲滾動動作的發生。當滾動時,實時地調節元件的透明度、高度等屬性,從而成功實現了巢狀滾動效果、透明度動態變化以及平滑的元件切換。
效果圖預覽
使用說明
- 載入完成後顯示整個介面,超過一屏可以上下滑動可見堆疊效果。
實現思路
- 在向上滑動過程中觀察到頭部元件是處於層級底部,而其他元件覆蓋在其上方,為此,選擇Stack元件來獲取堆疊效果。
Stack({ alignContent: Alignment.Top }) {
Scroll(this.scroller) {
...
}
}
- 在頂部的可滾動區域,透過使用Scroll元件來獲取堆疊效果。
Scroll(this.scroller) {
Column() {
...
}
}
- 實現滾動過程中動態調整文字框高度的功能時,運用Scroll元件滾動事件回撥函式onScroll在滾動時修改文字框的高度及元件的透明度。
.onScroll(() => {
let yOffset: number = this.scroller2.currentOffset().yOffset;
this.Height2 = this.Height2_raw - yOffset * 0.5;
// 根據yOffset的偏移量來設定IconList2的透明度,當偏移量大於等於IconList2原始高度就是透明的。
if (1 - yOffset / this.IconList2_raw >= 0) {
this.Opacity2 = 1 - yOffset / this.IconList2_raw; // IconList2的透明度
} else {
this.Opacity2 = 0;
}
// 巧妙利用IconList2的透明度的值Opacity2來設定IconList2的縮放。
this.ratio = this.Opacity2;
// 根據yOffset的偏移量來設定IconList1的透明度和IconList3的間距,當偏移量大於等於IconList1原始高度就是透明的同時IconList3的間距也是最小的。
if (1 - yOffset / this.IconList1_raw > 0) {
this.isChange = false;
this.Opacity = 1 - yOffset / this.IconList1_raw; // IconList1的透明度
this.marginSpace = this.maxMarginSpace; // IconList3預設間距
} else {
this.isChange = true;
this.Opacity = (yOffset - this.IconList1_raw) / this.maxMarginSpace; // IconList1的透明度
this.marginSpace = this.IconList3_raw - yOffset > this.minmarginSpace ?
(this.IconList3_raw - yOffset) : this.minmarginSpace; // IconList3的間距
}
})
- 存在多層巢狀滾動的情況時,應該先滾動父元件,再滾動自身。只需要在內層的Scroll元件的屬性nestedScroll設定向前向後兩個方向上的巢狀滾動模式,實現與父元件的滾動聯動。
Scroll(this.scroller2){
...
}
.width('100%')
.scrollBar(BarState.Off)
.nestedScroll({
scrollForward: NestedScrollMode.PARENT_FIRST, // 可滾動元件往末尾端滾動時的巢狀滾動選項,父元件先滾動,父元件滾動到邊緣以後自身滾動。
scrollBackward: NestedScrollMode.SELF_FIRST // 可滾動元件往起始端滾動時的巢狀滾動選項,自身先滾動,自身滾動到邊緣以後父元件滾動。
})
- 在商品列表區域,採用瀑布流(WaterFlow)容器進行佈局,將商品資訊動態分佈並分成兩列呈現,每列商品自上而下排列。
WaterFlow() {
LazyForEach(this.productData, (item: ProductDataModel) => {
FlowItem() {
...
}, (item: ProductDataModel) => item.id.toString())
}
.nestedScroll({
scrollForward: NestedScrollMode.PARENT_FIRST,
scrollBackward: NestedScrollMode.SELF_FIRST
})
.columnsTemplate("1fr 1fr")
}
高效能知識點
本示例使用了LazyForEach進行資料懶載入,WaterFlow佈局時會根據可視區域按需建立FlowItem元件,並在FlowItem滑出可視區域外時銷燬以降低記憶體佔用。 本例中Scroll元件繫結onScroll滾動事件回撥,onScroll屬於頻繁回撥,在回撥中需要儘量減少耗時和冗餘操作,例如減少不必要的日誌列印。
工程結構&模組型別
componentstack // har型別
|---mock
| |---IconMock.ets // 本地資料來源
|---model
| |---DataSource.ets // 列表資料模型
| |---IconModel.ets // 資料型別定義
|---view
| |---ComponentStack.ets // 元件堆疊主頁面
| |---IconView.ets // 按鈕快捷入口自定義元件
| |---ProductList.ets // 商品列表自定義元件
模組依賴
本例項依賴common模組來實現資源的呼叫。 還需要依賴EntryAbility.ets模組。
參考資料
WaterFlow
Stack
Z序控制
元件可見區域變化事件
寫在最後
- 如果你覺得這篇內容對你還蠻有幫助,我想邀請你幫我三個小忙:
- 點贊,轉發,有你們的 『點贊和評論』,才是我創造的動力。
- 關注小編,同時可以期待後續文章ing🚀,不定期分享原創知識。
- 想要獲取更多完整鴻蒙最新VIP學習資源,請移步前往小編:
https://qr21.cn/FV7h05