WaterFlow
瀑布流容器,由“行”和“列”分割的單元格所組成,通過(guò)容器自身的排列規(guī)則,將不同大小的“項(xiàng)目”自上而下,如瀑布般緊密布局。
說(shuō)明:
該組件從API Version 9 開(kāi)始支持。后續(xù)版本如有新增內(nèi)容,則采用上角標(biāo)單獨(dú)標(biāo)記該內(nèi)容的起始版本。
子組件
包含[FlowItem]子組件。
說(shuō)明:
WaterFlow子組件的visibility屬性設(shè)置為None時(shí)不顯示,但該子組件周?chē)膅ap還會(huì)生效。
接口
WaterFlow(options?: {footer?: CustomBuilder, scroller?: Scroller})
參數(shù)名 | 參數(shù)類(lèi)型 | 必填 開(kāi)發(fā)前請(qǐng)熟悉鴻蒙開(kāi)發(fā)指導(dǎo)文檔 :[gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md ]。 | 參數(shù)描述 |
---|---|---|---|
footer | [CustomBuilder] | 否 | 設(shè)置WaterFlow尾部組件。 |
scroller | [Scroller] | 否 | 可滾動(dòng)組件的控制器,與可滾動(dòng)組件綁定。 目前瀑布流僅支持Scroller組件的scrollToIndex接口。 |
屬性
除支持[通用屬性]外,還支持以下屬性:
名稱(chēng) | 參數(shù)類(lèi)型 | 描述 |
---|---|---|
columnsTemplate | string | 設(shè)置當(dāng)前瀑布流組件布局列的數(shù)量,不設(shè)置時(shí)默認(rèn)1列。 例如, '1fr 1fr 2fr' 是將父組件分3列,將父組件允許的寬分為4等份,第一列占1份,第二列占1份,第三列占2份。并支持[auto-fill]。 默認(rèn)值:'1fr' |
rowsTemplate | string | 設(shè)置當(dāng)前瀑布流組件布局行的數(shù)量,不設(shè)置時(shí)默認(rèn)1行。 例如, '1fr 1fr 2fr'是將父組件分三行,將父組件允許的高分為4等份,第一行占1份,第二行占一份,第三行占2份。并支持[auto-fill]。 默認(rèn)值:'1fr' |
itemConstraintSize | [ConstraintSizeOptions] | 設(shè)置約束尺寸,子組件布局時(shí),進(jìn)行尺寸范圍限制。 |
columnsGap | Length | 設(shè)置列與列的間距。 默認(rèn)值:0 |
rowsGap | Length | 設(shè)置行與行的間距。 默認(rèn)值:0 |
layoutDirection | [FlexDirection] | 設(shè)置布局的主軸方向。 默認(rèn)值:FlexDirection.Column |
enableScrollInteraction10+ | boolean | 設(shè)置是否支持滾動(dòng)手勢(shì),當(dāng)設(shè)置為false時(shí),無(wú)法通過(guò)手指或者鼠標(biāo)滾動(dòng),但不影響控制器的滾動(dòng)接口。 默認(rèn)值:true |
nestedScroll10+ | [NestedScrollOptions] | 嵌套滾動(dòng)選項(xiàng)。設(shè)置向前向后兩個(gè)方向上的嵌套滾動(dòng)模式,實(shí)現(xiàn)與父組件的滾動(dòng)聯(lián)動(dòng)。 |
friction10+ | number | [Resource] |
layoutDirection優(yōu)先級(jí)高于rowsTemplate和columnsTemplate。根據(jù)layoutDirection設(shè)置情況,分為以下三種設(shè)置模式:
- layoutDirection設(shè)置縱向布局(FlexDirection.Column 或 FlexDirection.ColumnReverse)
此時(shí)columnsTemplate有效(如果未設(shè)置,取默認(rèn)值)。例如columnsTemplate設(shè)置為"1fr 1fr"、rowsTemplate設(shè)置為"1fr 1fr 1fr"時(shí),瀑布流組件縱向布局,輔軸均分成橫向2列。 - layoutDirection設(shè)置橫向布局(FlexDirection.Row 或 FlexDirection.RowReverse)
此時(shí)rowsTemplate有效(如果未設(shè)置,取默認(rèn)值)。例如columnsTemplate設(shè)置為"1fr 1fr"、rowsTemplate設(shè)置為"1fr 1fr 1fr"時(shí),瀑布流組件橫向布局,輔軸均分成縱向3列。 - layoutDirection未設(shè)置布局方向
布局方向?yàn)閘ayoutDirection的默認(rèn)值:FlexDirection.Column,此時(shí)columnsTemplate有效。例如columnsTemplate設(shè)置為"1fr 1fr"、rowsTemplate設(shè)置為"1fr 1fr 1fr"時(shí),瀑布流組件縱向布局,輔軸均分成橫向2列。
事件
除支持[通用事件]外,還支持以下事件:
名稱(chēng) | 功能描述 |
---|---|
onReachStart(event: () => void) | 瀑布流組件到達(dá)起始位置時(shí)觸發(fā)。 |
onReachEnd(event: () => void) | 瀑布流組件到底末尾位置時(shí)觸發(fā)。 |
onScrollFrameBegin10+(event: (offset: number, state: ScrollState) => { offsetRemain }) | 瀑布流開(kāi)始滑動(dòng)時(shí)觸發(fā),事件參數(shù)傳入即將發(fā)生的滑動(dòng)量,事件處理函數(shù)中可根據(jù)應(yīng)用場(chǎng)景計(jì)算實(shí)際需要的滑動(dòng)量并作為事件處理函數(shù)的返回值返回,瀑布流將按照返回值的實(shí)際滑動(dòng)量進(jìn)行滑動(dòng)。 - offset:即將發(fā)生的滑動(dòng)量,單位vp。 - state:當(dāng)前滑動(dòng)狀態(tài)。 - offsetRemain:實(shí)際滑動(dòng)量,單位vp。 觸發(fā)該事件的條件:手指拖動(dòng)WaterFlow、WaterFlow慣性劃動(dòng)時(shí)每幀開(kāi)始時(shí)觸發(fā);List超出邊緣回彈、使用滾動(dòng)控制器的滾動(dòng)不會(huì)觸發(fā)。HarmonyOS與OpenHarmony鴻蒙文檔籽料:mau123789是v直接拿 |
auto-fill說(shuō)明
WaterFlow的columnsTemplate、rowsTemplate屬性的auto-fill僅支持以下格式:
repeat(auto-fill, track-size)
其中repeat、auto-fill為關(guān)鍵字。track-size為行高或者列寬,支持的單位包括px、vp、%或有效數(shù)字,track-size至少包括一個(gè)有效行高或者列寬。
示例
// WaterFlowDataSource.ets
// 實(shí)現(xiàn)IDataSource接口的對(duì)象,用于瀑布流組件加載數(shù)據(jù)
export class WaterFlowDataSource implements IDataSource {
private dataArray: number[] = []
private listeners: DataChangeListener[] = []
constructor() {
for (let i = 0; i < 100; i++) {
this.dataArray.push(i)
}
}
// 獲取索引對(duì)應(yīng)的數(shù)據(jù)
public getData(index: number): number {
return this.dataArray[index]
}
// 通知控制器數(shù)據(jù)重新加載
notifyDataReload(): void {
this.listeners.forEach(listener = > {
listener.onDataReloaded()
})
}
// 通知控制器數(shù)據(jù)增加
notifyDataAdd(index: number): void {
this.listeners.forEach(listener = > {
listener.onDataAdd(index)
})
}
// 通知控制器數(shù)據(jù)變化
notifyDataChange(index: number): void {
this.listeners.forEach(listener = > {
listener.onDataChange(index)
})
}
// 通知控制器數(shù)據(jù)刪除
notifyDataDelete(index: number): void {
this.listeners.forEach(listener = > {
listener.onDataDelete(index)
})
}
// 通知控制器數(shù)據(jù)位置變化
notifyDataMove(from: number, to: number): void {
this.listeners.forEach(listener = > {
listener.onDataMove(from, to)
})
}
// 獲取數(shù)據(jù)總數(shù)
public totalCount(): number {
return this.dataArray.length
}
// 注冊(cè)改變數(shù)據(jù)的控制器
registerDataChangeListener(listener: DataChangeListener): void {
if (this.listeners.indexOf(listener) < 0) {
this.listeners.push(listener)
}
}
// 注銷(xiāo)改變數(shù)據(jù)的控制器
unregisterDataChangeListener(listener: DataChangeListener): void {
const pos = this.listeners.indexOf(listener)
if (pos >= 0) {
this.listeners.splice(pos, 1)
}
}
// 增加數(shù)據(jù)
public Add1stItem(): void {
this.dataArray.splice(0, 0, this.dataArray.length)
this.notifyDataAdd(0)
}
// 在數(shù)據(jù)尾部增加一個(gè)元素
public AddLastItem(): void {
this.dataArray.splice(this.dataArray.length, 0, this.dataArray.length)
this.notifyDataAdd(this.dataArray.length - 1)
}
// 在指定索引位置增加一個(gè)元素
public AddItem(index: number): void {
this.dataArray.splice(index, 0, this.dataArray.length)
this.notifyDataAdd(index)
}
// 刪除第一個(gè)元素
public Delete1stItem(): void {
this.dataArray.splice(0, 1)
this.notifyDataDelete(0)
}
// 刪除第二個(gè)元素
public Delete2ndItem(): void {
this.dataArray.splice(1, 1)
this.notifyDataDelete(1)
}
// 刪除最后一個(gè)元素
public DeleteLastItem(): void {
this.dataArray.splice(-1, 1)
this.notifyDataDelete(this.dataArray.length)
}
// 重新加載數(shù)據(jù)
public Reload(): void {
this.dataArray.splice(1, 1)
this.dataArray.splice(3, 2)
this.notifyDataReload()
}
}
// Index.ets
import { WaterFlowDataSource } from './WaterFlowDataSource'
@Entry
@Component
struct WaterflowDemo {
@State minSize: number = 80
@State maxSize: number = 180
@State fontSize: number = 24
@State colors: number[] = [0xFFC0CB, 0xDA70D6, 0x6B8E23, 0x6A5ACD, 0x00FFFF, 0x00FF7F]
scroller: Scroller = new Scroller()
datasource: WaterFlowDataSource = new WaterFlowDataSource()
private itemWidthArray: number[] = []
private itemHeightArray: number[] = []
// 計(jì)算flow item寬/高
getSize() {
let ret = Math.floor(Math.random() * this.maxSize)
return (ret > this.minSize ? ret : this.minSize)
}
// 保存flow item寬/高
getItemSizeArray() {
for (let i = 0; i < 100; i++) {
this.itemWidthArray.push(this.getSize())
this.itemHeightArray.push(this.getSize())
}
}
aboutToAppear() {
this.getItemSizeArray()
}
@Builder
itemFoot() {
Column() {
Text(`Footer`)
.fontSize(10)
.backgroundColor(Color.Red)
.width(50)
.height(50)
.align(Alignment.Center)
.margin({ top: 2 })
}
}
build() {
Column({ space: 2 }) {
WaterFlow() {
LazyForEach(this.datasource, (item: number) = > {
FlowItem() {
Column() {
Text("N" + item).fontSize(12).height('16')
Image('res/waterFlowTest(' + item % 5 + ').jpg')
.objectFit(ImageFit.Fill)
.width('100%')
.layoutWeight(1)
}
}
.onAppear(() = > {
// 即將觸底時(shí)提前增加數(shù)據(jù)
if (item + 20 == this.datasource.totalCount()) {
for (let i = 0; i < 100; i++) {
this.datasource.AddLastItem()
}
}
})
.width('100%')
.height(this.itemHeightArray[item % 100])
.backgroundColor(this.colors[item % 5])
}, (item: string) = > item)
}
.columnsTemplate("1fr 1fr")
.columnsGap(10)
.rowsGap(5)
.backgroundColor(0xFAEEE0)
.width('100%')
.height('100%')
}
}
}
審核編輯 黃宇
-
組件
+關(guān)注
關(guān)注
1文章
513瀏覽量
17849 -
鴻蒙
+關(guān)注
關(guān)注
57文章
2365瀏覽量
42894
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論