1/** 2 * 3 * Copyright (c) 2025 Huawei Device Co., Ltd. 4 * 5 * All rights reserved. 6 * Redistribution and use in source and binary forms, with or without modification, 7 * are permitted provided that the following conditions are met: 8 * 9 * Redistributions of source code must retain the above copyright notice,this 10 * list of conditions and the following disclaimer. 11 * 12 * Redistributions in binary form must reproduce the above copyright notice, 13 * this list of conditions and the following disclaimer in the documentation 14 * and/or other materials provided with the distribution. 15 * 16 * THIS IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, 17 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 21 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 22 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS, 23 * 24 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26import { memo, __memo_context_type, __memo_id_type } from '@ohos.arkui.stateManagement'; // should be insert by ui-plugins 27import {IDataSource,DataChangeListener,Text, TextAttribute, Column, Component, Button, ButtonAttribute, ClickEvent, UserView ,Image,Row} from '@ohos.arkui.component'; // TextAttribute should be insert by ui-plugins 28import { State, StateDecoratedVariable, MutableState, stateOf, observableProxy ,Provide} from '@ohos.arkui.stateManagement'; // should be insert by ui-plugins 29const CONTENT_PER_TAG = 10; // 每个TAG对应多少个元素 30/** 31 * 代表自定义类型数据的接口。 32 * 33 * @interface 34 * @property {string} desc - 描述。 35 * @property {string} tag - 类别。 36 */ 37export interface CustomDataType { 38 desc: string, 39 tag: string, 40} 41 42/** 43 * 一级列表可视区域的起始索引和终点索引。 44 * 45 * @interface 46 * @property {number} start - 可视区域起点索引。 47 * @property {number} end - 可视区域终点索引。 48 */ 49export interface ListIndexPosition { 50 start: number, 51 end: number 52} 53 54/** 55 * Basic implementation of IDataSource to handle data listener 56 * 57 * @class 58 * @implements {IDataSource} 59 */ 60class BasicDataSource implements IDataSource<CustomDataType> { 61 private listeners: DataChangeListener[] = Array<DataChangeListener>(); 62 private originDataArray: CustomDataType[] = Array<CustomDataType>(); 63 64 /** 65 * 获取数组长度。 66 * @returns {number} 返回数组长度。 67 */ 68 public totalCount(): double { 69 return 0; 70 } 71 72 /** 73 * 获取指定索引数据。 74 * @param {number} index - 索引值。 75 * @returns {CustomDataType} 返回指定索引数据。 76 */ 77 public getData(index: double): CustomDataType { 78 return this.originDataArray[index]; 79 } 80 81 /** 82 * 为LazyForEach组件向其数据源处添加listener监听。 83 * @param {DataChangeListener} listener - 监听对象。 84 */ 85 registerDataChangeListener(listener: DataChangeListener): void { 86 if (this.listeners.indexOf(listener) < 0) { 87 console.info('add listener'); 88 this.listeners.push(listener); 89 } 90 } 91 92 /** 93 * 为对应的LazyForEach组件在数据源处去除listener监听。 94 * @param {DataChangeListener} listener - 监听对象。 95 */ 96 unregisterDataChangeListener(listener: DataChangeListener): void { 97 const pos = this.listeners.indexOf(listener); 98 if (pos >= 0) { 99 console.info('remove listener'); 100 this.listeners.splice(pos, 1); 101 } 102 } 103 104 /** 105 * 通知LazyForEach组件需要在index对应索引处添加子组件。 106 * @param {number} index - 索引值。 107 */ 108 notifyDataAdd(index: double): void { 109 this.listeners.forEach(listener => { 110 listener.onDataAdd(index); 111 }) 112 } 113 114 /** 115 * 通知LazyForEach组件在index对应索引处数据有变化,需要重建该子组件。 116 * @param {number} index - 索引值。 117 */ 118 notifyDataChange(index: double): void { 119 this.listeners.forEach(listener => { 120 listener.onDataChange(index); 121 }) 122 } 123 124 /** 125 * 通知LazyForEach组件需要在index对应索引处删除该子组件 126 * @param {number} index - 索引值。 127 */ 128 notifyDataDelete(index: double): void { 129 this.listeners.forEach(listener => { 130 listener.onDataDelete(index); 131 }) 132 } 133 134 /** 135 * 通知LazyForEach组件将from索引和to索引处的子组件进行交换 136 * @param {number} from - 起始值。 137 * @param {number} to - 终点值。 138 */ 139 notifyDataMove(from: double, to: double): void { 140 this.listeners.forEach(listener => { 141 listener.onDataMove(from, to); 142 }) 143 } 144} 145 146/** 147 * 继承自BasicDataSource的子类,重写了方法。 148 * 149 * @class 150 * @extends {BasicDataSource} 151 */ 152export class MyDataSource extends BasicDataSource { 153 public dataArray: CustomDataType[] = Array<CustomDataType>(); 154 155 /** 156 * 获取数组长度。 157 * @returns {number} 返回数组长度。 158 */ 159 public totalCount(): double { 160 return this.dataArray.length; 161 } 162 163 /** 164 * 获取指定索引数据。 165 * @param {number} index - 索引值。 166 * @returns {CustomDataType} 返回指定索引数据。 167 */ 168 public getData(index: double): CustomDataType { 169 return this.dataArray[index]; 170 } 171 172 /** 173 * 改变单个数据。 174 * @param {number} index - 索引值。 175 * @param {CustomDataType} data - 修改后的值。 176 */ 177 public addData(index: double, data: CustomDataType): void { 178 this.dataArray.splice(index, 0, data); 179 this.notifyDataAdd(index); 180 } 181 182 /** 183 * 添加数据。 184 * @param {CustomDataType} data - 需要添加的数据。 185 */ 186 public pushData(data: CustomDataType[]): void { 187 if (Array.isArray(data)) { 188 for (let i = 0; i < CONTENT_PER_TAG; ++i) { 189 this.dataArray.push(data[i]); 190 } 191 } 192 this.notifyDataAdd(this.dataArray.length - 1); 193 } 194} 195 196// 常量数据 197export enum ComponentStyle { 198 ITEM_GUTTER = 12, 199 TAG_TEXT_HEIGHT= 75, 200 SUB_ITEM_GUTTER= 7, 201 SUB_ITEM_HEIGHT= 96, 202 SUB_ITEM_TEXT_WIDTH_TITLE= 56, 203 SUB_ITEM_TEXT_HEIGHT= 12, 204 SUB_ITEM_TEXT_WIDTH_BODY= 120, 205 BOTTOM_TOAST_TEXT_MAX_HEIGHT= 200 206};