diff --git a/OAT.xml b/OAT.xml
index e36ebac38a93f40671c67ac114bceaf8b3cc7757..f4250d13dd79af0a31a59ceb2c9be33d567109a7 100644
--- a/OAT.xml
+++ b/OAT.xml
@@ -103,6 +103,11 @@ Note:If the text contains special characters, please escape them according to th
+
+
+
+
+
@@ -2053,6 +2058,13 @@ Note:If the text contains special characters, please escape them according to th
+
+
+
+
+
+
+
diff --git a/code/UI/ListBeExchange/.gitignore b/code/UI/ListBeExchange/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..d2ff20141ceed86d87c0ea5d99481973005bab2b
--- /dev/null
+++ b/code/UI/ListBeExchange/.gitignore
@@ -0,0 +1,12 @@
+/node_modules
+/oh_modules
+/local.properties
+/.idea
+**/build
+/.hvigor
+.cxx
+/.clangd
+/.clang-format
+/.clang-tidy
+**/.test
+/.appanalyzer
\ No newline at end of file
diff --git a/code/UI/ListBeExchange/AppScope/app.json5 b/code/UI/ListBeExchange/AppScope/app.json5
new file mode 100644
index 0000000000000000000000000000000000000000..b360573b97d476682e53305cba89dd49e05b428f
--- /dev/null
+++ b/code/UI/ListBeExchange/AppScope/app.json5
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+{
+ "app": {
+ "bundleName": "com.samples.ListExchange",
+ "vendor": "example",
+ "versionCode": 1000000,
+ "versionName": "1.0.0",
+ "icon": "$media:app_icon",
+ "label": "$string:app_name"
+ }
+}
diff --git a/code/UI/ListBeExchange/AppScope/resources/base/element/string.json b/code/UI/ListBeExchange/AppScope/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..66d68b87864cfece36031613d291e00378a8ec1f
--- /dev/null
+++ b/code/UI/ListBeExchange/AppScope/resources/base/element/string.json
@@ -0,0 +1,8 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "new"
+ }
+ ]
+}
diff --git a/code/UI/ListBeExchange/AppScope/resources/base/media/app_icon.png b/code/UI/ListBeExchange/AppScope/resources/base/media/app_icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..a39445dc87828b76fed6d2ec470dd455c45319e3
Binary files /dev/null and b/code/UI/ListBeExchange/AppScope/resources/base/media/app_icon.png differ
diff --git a/code/UI/ListBeExchange/ListExchange/.gitignore b/code/UI/ListBeExchange/ListExchange/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..e2713a2779c5a3e0eb879efe6115455592caeea5
--- /dev/null
+++ b/code/UI/ListBeExchange/ListExchange/.gitignore
@@ -0,0 +1,6 @@
+/node_modules
+/oh_modules
+/.preview
+/build
+/.cxx
+/.test
\ No newline at end of file
diff --git a/code/UI/ListBeExchange/ListExchange/Index.ets b/code/UI/ListBeExchange/ListExchange/Index.ets
new file mode 100644
index 0000000000000000000000000000000000000000..b3e3dd70f01ee42aadf1b81f6a2aa399b25f0434
--- /dev/null
+++ b/code/UI/ListBeExchange/ListExchange/Index.ets
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export { ListExchangeView } from './src/main/ets/FeatureComponent'
diff --git a/code/UI/ListBeExchange/ListExchange/build-profile.json5 b/code/UI/ListBeExchange/ListExchange/build-profile.json5
new file mode 100644
index 0000000000000000000000000000000000000000..881fc3637e5df365b5777ec6341505218ce70905
--- /dev/null
+++ b/code/UI/ListBeExchange/ListExchange/build-profile.json5
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+{
+ "apiType": "stageMode",
+ "buildOption": {
+ },
+ "buildOptionSet": [
+ {
+ "name": "release",
+ "arkOptions": {
+ "obfuscation": {
+ "ruleOptions": {
+ "enable": false,
+ "files": [
+ "./obfuscation-rules.txt"
+ ]
+ },
+ "consumerFiles": [
+ "./consumer-rules.txt"
+ ]
+ }
+ },
+ },
+ ],
+ "targets": [
+ {
+ "name": "default"
+ },
+ {
+ "name": "ohosTest"
+ }
+ ]
+}
diff --git a/code/UI/ListBeExchange/ListExchange/consumer-rules.txt b/code/UI/ListBeExchange/ListExchange/consumer-rules.txt
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/code/UI/ListBeExchange/ListExchange/hvigorfile.ts b/code/UI/ListBeExchange/ListExchange/hvigorfile.ts
new file mode 100644
index 0000000000000000000000000000000000000000..70842da662501ca9b88d435d29a1e58c51e8646d
--- /dev/null
+++ b/code/UI/ListBeExchange/ListExchange/hvigorfile.ts
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { harTasks } from '@ohos/hvigor-ohos-plugin';
+
+export default {
+ system: harTasks, /* Built-in plugin of Hvigor. It cannot be modified. */
+ plugins:[] /* Custom plugin to extend the functionality of Hvigor. */
+}
diff --git a/code/UI/ListBeExchange/ListExchange/obfuscation-rules.txt b/code/UI/ListBeExchange/ListExchange/obfuscation-rules.txt
new file mode 100644
index 0000000000000000000000000000000000000000..272efb6ca3f240859091bbbfc7c5802d52793b0b
--- /dev/null
+++ b/code/UI/ListBeExchange/ListExchange/obfuscation-rules.txt
@@ -0,0 +1,23 @@
+# Define project specific obfuscation rules here.
+# You can include the obfuscation configuration files in the current module's build-profile.json5.
+#
+# For more details, see
+# https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/source-obfuscation-V5
+
+# Obfuscation options:
+# -disable-obfuscation: disable all obfuscations
+# -enable-property-obfuscation: obfuscate the property names
+# -enable-toplevel-obfuscation: obfuscate the names in the global scope
+# -compact: remove unnecessary blank spaces and all line feeds
+# -remove-log: remove all console.* statements
+# -print-namecache: print the name cache that contains the mapping from the old names to new names
+# -apply-namecache: reuse the given cache file
+
+# Keep options:
+# -keep-property-name: specifies property names that you want to keep
+# -keep-global-name: specifies names that you want to keep in the global scope
+
+-enable-property-obfuscation
+-enable-toplevel-obfuscation
+-enable-filename-obfuscation
+-enable-export-obfuscation
\ No newline at end of file
diff --git a/code/UI/ListBeExchange/ListExchange/oh-package.json5 b/code/UI/ListBeExchange/ListExchange/oh-package.json5
new file mode 100644
index 0000000000000000000000000000000000000000..7e2f768204f6c37dd5f428cb707505a8b8d324a0
--- /dev/null
+++ b/code/UI/ListBeExchange/ListExchange/oh-package.json5
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+{
+ "name": "listexchange",
+ "version": "1.0.0",
+ "description": "Please describe the basic information.",
+ "main": "Index.ets",
+ "author": "",
+ "license": "Apache-2.0",
+ "dependencies": {}
+}
diff --git a/code/UI/ListBeExchange/ListExchange/src/main/ets/FeatureComponent.ets b/code/UI/ListBeExchange/ListExchange/src/main/ets/FeatureComponent.ets
new file mode 100644
index 0000000000000000000000000000000000000000..8b1a72bb48c0a3bf6579de75c763af64fb365923
--- /dev/null
+++ b/code/UI/ListBeExchange/ListExchange/src/main/ets/FeatureComponent.ets
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { ListExchangeViewComponent } from './view/ListExchangeView';
+
+@Component
+export struct ListExchangeView {
+ build() {
+ ListExchangeViewComponent()
+ }
+}
\ No newline at end of file
diff --git a/code/UI/ListBeExchange/ListExchange/src/main/ets/common/commonConstants.ets b/code/UI/ListBeExchange/ListExchange/src/main/ets/common/commonConstants.ets
new file mode 100644
index 0000000000000000000000000000000000000000..564db0fe6f9a85f72f6ec0f415b2768fb3bcbb8f
--- /dev/null
+++ b/code/UI/ListBeExchange/ListExchange/src/main/ets/common/commonConstants.ets
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export class CommonConstants {
+ // 初始化列表项高度
+ public static readonly LIST_ITEM_HEIGHT = 50;
+ // 初始化动画时间
+ public static readonly ANIMATE_DURATION = 300;
+ // 初始化列表项名称
+ public static readonly LIST_NAME = '标题1';
+}
\ No newline at end of file
diff --git a/code/UI/ListBeExchange/ListExchange/src/main/ets/generated/RouterBuilder.ets b/code/UI/ListBeExchange/ListExchange/src/main/ets/generated/RouterBuilder.ets
new file mode 100644
index 0000000000000000000000000000000000000000..67166b18a662da44ae46425323afa39a529fe04f
--- /dev/null
+++ b/code/UI/ListBeExchange/ListExchange/src/main/ets/generated/RouterBuilder.ets
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// auto-generated
+import { DynamicsRouter, AppRouterInfo } from 'routermodule/Index';
+import { ListExchangeView } from '../FeatureComponent'
+
+@Builder
+function listExchangeViewBuilder() {
+ ListExchangeView();
+}
+
+export function listExchangeViewRegister(routerInfo: AppRouterInfo) {
+ DynamicsRouter.registerAppRouterPage(routerInfo, wrapBuilder(listExchangeViewBuilder));
+}
+
diff --git a/code/UI/ListBeExchange/ListExchange/src/main/ets/model/AttributeModifier.ets b/code/UI/ListBeExchange/ListExchange/src/main/ets/model/AttributeModifier.ets
new file mode 100644
index 0000000000000000000000000000000000000000..105c2117333b3307f84763f51983db8c6e8e3247
--- /dev/null
+++ b/code/UI/ListBeExchange/ListExchange/src/main/ets/model/AttributeModifier.ets
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * 通过实现AttributeModifier接口,自定义属性修改器
+ * 将拖拽排序相关样式封装成属性修改器,可以方便移植
+ */
+export class ListItemModifier implements AttributeModifier {
+ // 阴影
+ public hasShadow: boolean = false;
+ // 缩放
+ public scale: number = 1;
+ // 纵轴偏移量
+ public offsetY: number = 0;
+ // 横轴偏移量
+ public offsetX: number = 0;
+ // 透明度
+ public opacity: number = 1;
+ // 是否被删除
+ public isDeleted: boolean = false;
+ public static instance: ListItemModifier | null = null;
+
+ public static getInstance(): ListItemModifier {
+ if (!ListItemModifier.instance) {
+ ListItemModifier.instance = new ListItemModifier();
+ }
+ return ListItemModifier.instance;
+ }
+
+ /**
+ * 定义组件普通状态时的样式
+ * @param instance: ListItem属性
+ */
+ applyNormalAttribute(instance: ListItemAttribute): void {
+ if (this.hasShadow) {
+ instance.shadow({ radius: $r('app.integer.list_exchange_shadow_radius'), color: $r('app.color.list_exchange_box_shadow') });
+ instance.zIndex(1);
+ instance.opacity(0.5);
+ } else {
+ instance.opacity(this.opacity);
+ }
+ instance.translate({ x: this.offsetX, y: this.offsetY });
+ instance.scale({ x: this.scale, y: this.scale });
+ }
+}
\ No newline at end of file
diff --git a/code/UI/ListBeExchange/ListExchange/src/main/ets/model/ListExchangeCtrl.ets b/code/UI/ListBeExchange/ListExchange/src/main/ets/model/ListExchangeCtrl.ets
new file mode 100644
index 0000000000000000000000000000000000000000..b9fa9eeb0d81d0bd45908e5b01e662bfa5b53501
--- /dev/null
+++ b/code/UI/ListBeExchange/ListExchange/src/main/ets/model/ListExchangeCtrl.ets
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { ListItemModifier } from '../model/AttributeModifier';
+import curves from '@ohos.curves';
+import { logger } from '../utils/Logger';
+import { CommonConstants } from '../common/commonConstants';
+
+const ITEM_HEIGHT: number = 50; // 行高
+
+// 操作状态枚举
+enum OperationStatus {
+ IDLE,
+ PRESSING,
+ MOVING,
+ DROPPING,
+ DELETE
+}
+
+/**
+ * 列表项切换控制
+ */
+@Observed
+export class ListExchangeCtrl {
+ private deductionData: Array = []; // 列表数据
+ private modifier: Array = []; // 属性数据
+ private dragRefOffset: number = 0;
+ private offsetY: number = 0;
+ private state: OperationStatus = OperationStatus.IDLE;
+
+ initData(deductionData: Array) {
+ this.deductionData = deductionData;
+ deductionData.forEach(() => {
+ this.modifier.push(new ListItemModifier());
+ })
+ }
+
+ /**
+ * 获取ListItem的属性
+ * @param item
+ * @returns 返回自定义属性对象
+ */
+ getModifier(item: T): ListItemModifier {
+ const index: number = this.deductionData.indexOf(item);
+ return this.modifier[index];
+ }
+
+ /**
+ * ListItem长按函数
+ * @param item
+ */
+ onLongPress(item: T): void {
+ const index: number = this.deductionData.indexOf(item);
+ this.dragRefOffset = 0;
+ // TODO:知识点:长按当前列表项透明度和放大动画
+ animateTo({ curve: Curve.Friction, duration: CommonConstants.ANIMATE_DURATION }, () => {
+ this.state = OperationStatus.PRESSING;
+ this.modifier[index].hasShadow = true;
+ this.modifier[index].scale = 1.04; // 放大比例为1.04
+ })
+ }
+
+ /**
+ * ListItem移动函数
+ * @param item
+ * @param offsetY
+ */
+ onMove(item: T, offsetY: number): void {
+ try {
+ const index: number = this.deductionData.indexOf(item);
+ this.offsetY = offsetY - this.dragRefOffset;
+ this.modifier[index].offsetY = this.offsetY;
+ const direction: number = this.offsetY > 0 ? 1 : -1;
+ // 触发拖动时,被覆盖子组件缩小与恢复的动画
+ const curveValue: ICurve = curves.initCurve(Curve.Sharp);
+ const value: number = curveValue.interpolate(Math.abs(this.offsetY) / ITEM_HEIGHT);
+ const shrinkScale: number = 1 - value / 10; // 计算缩放比例,value值缩小10倍
+ if (index < this.modifier.length - 1) { // 当拖拽的时候,被交换的对象会缩放
+ this.modifier[index + 1].scale = direction > 0 ? shrinkScale : 1;
+ }
+ if (index > 0) {
+ this.modifier[index - 1].scale = direction > 0 ? 1 : shrinkScale;
+ }
+ // TODO:知识点:处理列表项的切换操作
+ if (Math.abs(this.offsetY) > ITEM_HEIGHT / 2) {
+ if (index === 0 && direction === -1) {
+ return;
+ }
+ if (index === this.deductionData.length - 1 && direction === 1) {
+ return;
+ }
+ animateTo({ curve: Curve.Friction, duration: CommonConstants.ANIMATE_DURATION }, () => {
+ this.offsetY -= direction * ITEM_HEIGHT;
+ this.dragRefOffset += direction * ITEM_HEIGHT;
+ this.modifier[index].offsetY = this.offsetY;
+ const target = index + direction // 目标位置索引
+ if (target !== -1 && target <= this.modifier.length) {
+ this.changeItem(index, target);
+ }
+ })
+ }
+ } catch (err) {
+ logger.error(`onMove err:${JSON.stringify(err)}`);
+ }
+ }
+
+ /**
+ * ListItem放置函数
+ * @param item
+ */
+ onDrop(item: T): void {
+ logger.info(`onDrop start`);
+ try {
+ const index: number = this.deductionData.indexOf(item);
+ this.dragRefOffset = 0;
+ this.offsetY = 0;
+ /**
+ * 恢复拖动中,被缩小的子组件,并提供动画。
+ * 通过interpolatingSpring(0, 1, 400, 38)构造插值器弹簧曲线对象初始速度为0,质量为1,刚度为400,阻尼为38
+ */
+ animateTo({ curve: curves.interpolatingSpring(0, 1, 400, 38) }, () => {
+ this.state = OperationStatus.DROPPING;
+ if (index < this.modifier.length - 1) {
+ this.modifier[index + 1].scale = 1;
+ }
+ if (index > 0) {
+ this.modifier[index - 1].scale = 1;
+ }
+ })
+ /**
+ * 恢复被拖拽子组件的放大与阴影效果,并提供动画。
+ * 通过interpolatingSpring(0, 1, 400, 38)构造插值器弹簧曲线对象初始速度为14,质量为1,刚度为170,阻尼为17
+ */
+ animateTo({ curve: curves.interpolatingSpring(14, 1, 170, 17) }, () => {
+ this.state = OperationStatus.IDLE;
+ this.modifier[index].hasShadow = false;
+ this.modifier[index].scale = 1; // 初始化缩放比例
+ this.modifier[index].offsetY = 0; // 初始化偏移量
+ })
+ logger.info(`onDrop end`);
+ } catch (err) {
+ console.error(`onDrop err:${JSON.stringify(err)}`);
+ }
+ }
+
+ /**
+ * Item交换位置
+ * @param index
+ * @param newIndex
+ */
+ changeItem(index: number, newIndex: number): void {
+ const tmp: Array = this.deductionData.splice(index, 1);
+ this.deductionData.splice(newIndex, 0, tmp[0]);
+ const tmp2: Array = this.modifier.splice(index, 1);
+ this.modifier.splice(newIndex, 0, tmp2[0]);
+ }
+
+ /**
+ * 删除列表项
+ * @param item: 列表项
+ */
+ deleteItem(item: T): void {
+ try {
+ const index: number = this.deductionData.indexOf(item);
+ this.dragRefOffset = 0;
+ // TODO:知识点:左偏移以及透明度动画
+ animateTo({
+ // 总时间300ms
+ curve: Curve.Friction, duration: 300, onFinish: () => {
+ // TODO:知识点:列表项删除动画
+ animateTo({
+ // 总时间500ms
+ curve: Curve.Friction, duration: 500, onFinish: () => {
+ this.state = OperationStatus.IDLE;
+ }
+ }, () => {
+ this.modifier.splice(index, 1);
+ this.deductionData.splice(index, 1);
+ })
+ }
+ }, () => {
+ this.state = OperationStatus.DELETE;
+ this.modifier[index].offsetX = 150; // 列表项左偏移150
+ this.modifier[index].opacity = 0; // 列表项透明度为0
+ })
+ } catch (err) {
+ console.error(`delte err:${JSON.stringify(err)}`);
+ }
+ }
+
+ /**
+ * 添加列表项
+ * @param item: 列表项
+ */
+ addItem(item: T): void {
+ this.deductionData.push(item);
+ this.modifier.push(new ListItemModifier());
+ }
+}
\ No newline at end of file
diff --git a/code/UI/ListBeExchange/ListExchange/src/main/ets/model/ListInfo.ets b/code/UI/ListBeExchange/ListExchange/src/main/ets/model/ListInfo.ets
new file mode 100644
index 0000000000000000000000000000000000000000..025520398d3269276fe805bd74b1055463b68552
--- /dev/null
+++ b/code/UI/ListBeExchange/ListExchange/src/main/ets/model/ListInfo.ets
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * 列表信息,包括图标、名字、是否可见
+ * icon: 列表项图标
+ * name: 列表项名称
+ */
+@Observed
+export class ListInfo {
+ public icon: ResourceStr = '';
+ public name: ResourceStr = '';
+
+ constructor(icon: ResourceStr = '', name: ResourceStr = '') {
+ this.icon = icon;
+ this.name = name;
+ }
+}
\ No newline at end of file
diff --git a/code/UI/ListBeExchange/ListExchange/src/main/ets/model/MockData.ets b/code/UI/ListBeExchange/ListExchange/src/main/ets/model/MockData.ets
new file mode 100644
index 0000000000000000000000000000000000000000..e803776af459c3c4b24dcfbbad330661c1e91974
--- /dev/null
+++ b/code/UI/ListBeExchange/ListExchange/src/main/ets/model/MockData.ets
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { ListInfo } from './ListInfo';
+
+// Mock数据
+export const MEMO_DATA: ListInfo[] = [
+ new ListInfo($r('app.media.list_exchange_ic_public_cards_filled'), '账户余额'),
+ new ListInfo($r('app.media.list_exchange_ic_public_cards_filled2'), 'xx银行储蓄卡(1234)'),
+ new ListInfo($r('app.media.list_exchange_ic_public_cards_filled3'), 'xx银行储蓄卡(1238)'),
+ new ListInfo($r('app.media.list_exchange_ic_public_cards_filled4'), 'xx银行储蓄卡(1236)')
+];
\ No newline at end of file
diff --git a/code/UI/ListBeExchange/ListExchange/src/main/ets/utils/ListExchange.ets b/code/UI/ListBeExchange/ListExchange/src/main/ets/utils/ListExchange.ets
new file mode 100644
index 0000000000000000000000000000000000000000..a533d303d291eb21b4da62d1fb1e0cc36d054f04
--- /dev/null
+++ b/code/UI/ListBeExchange/ListExchange/src/main/ets/utils/ListExchange.ets
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { ListExchangeCtrl } from '../model/ListExchangeCtrl';
+import { ListInfo } from '../model/ListInfo';
+import { logger } from './Logger';
+import { CommonConstants } from '../common/commonConstants';
+
+/**
+ * 功能描述:
+ * 1. 长按列表项,向上或向下拖动,当前列表项和目标列表项位置互换。
+ * 2. 列表项向左滑动,显示删除按钮。
+ * 3. 点击删除按钮,当前列表项删除。
+ *
+ * 实现原理:
+ * 1. 创建一个数组modifier来添加自定义属性对象,根据组合手势GestureGroup来控制自定义属性的值并通过attributeModifier绑定自定义属性对象来动态加载属性。
+ * 2. 然后swipeAction属性绑定删除组件,左滑显示此删除组件,点击实现列表项的删除。
+ *
+ * @param appInfoList - 列表数据
+ * @param appInfoList - 列表元素交换类
+ * @param deductionView - 列表项UI模块
+ */
+@Component
+export struct ListExchange {
+ // -------------------对外暴露变量-----------------------
+ @Link appInfoList: Object[];
+ // 控制列表项交换的类
+ @Link listExchangeCtrl: ListExchangeCtrl