温馨提示:本篇博客的详细代码已发布到 git : https://gitcode.com/nutpi/HarmonyosNext 可以下载运行哦!

HarmonyOS NEXT系列教程之列表交换组件列表项操作实现

效果演示

1. 列表项基础结构

1.1 数据结构

// 列表项接口
interface ListItem {
    id: string;           // 唯一标识
    icon: ResourceStr;    // 图标资源
    name: ResourceStr;    // 显示名称
    isSelected: boolean;  // 选中状态
}

// 列表项实现
@Observed
class ListItemImpl implements ListItem {
    constructor(
        public id: string,
        public icon: ResourceStr,
        public name: ResourceStr,
        public isSelected: boolean = false
    ) {}
}

1.2 视图结构

@Builder
function ListItemView(item: ListItem) {
    Row() {
        Image(item.icon)
            .width($r('app.integer.list_item_icon_size'))
            .height($r('app.integer.list_item_icon_size'))
        
        Text(item.name)
            .margin({ left: $r('app.integer.list_item_margin') })
            .fontSize($r('app.integer.list_item_font_size'))
        
        if (item.isSelected) {
            Image($r('app.media.ic_selected'))
                .width($r('app.integer.list_item_selected_size'))
                .height($r('app.integer.list_item_selected_size'))
        }
    }
    .width('100%')
    .height($r('app.integer.list_item_height'))
    .padding($r('app.integer.list_item_padding'))
}

2. 增删改查操作

2.1 添加操作

class ListOperations {
    // 添加列表项
    static addItem(item: ListItem): void {
        try {
            // 验证数据
            this.validateItem(item);
            // 添加到列表
            this.items.push(item);
            // 触发更新
            this.notifyDataChanged();
        } catch (error) {
            console.error('Add item failed:', error);
        }
    }

    // 批量添加
    static addItems(items: ListItem[]): void {
        items.forEach(item => this.addItem(item));
    }
}

2.2 删除操作

class ListOperations {
    // 删除列表项
    static deleteItem(id: string): void {
        const index = this.findItemIndex(id);
        if (index !== -1) {
            // 执行删除动画
            this.animateDelete(index, () => {
                this.items.splice(index, 1);
                this.notifyDataChanged();
            });
        }
    }

    // 批量删除
    static deleteItems(ids: string[]): void {
        ids.forEach(id => this.deleteItem(id));
    }
}

3. 拖拽排序实现

3.1 拖拽处理

class DragHandler {
    private dragStartIndex: number = -1;
    private currentDragIndex: number = -1;

    // 开始拖拽
    onDragStart(index: number): void {
        this.dragStartIndex = index;
        this.currentDragIndex = index;
        // 应用拖拽样式
        this.applyDragStyle(index);
    }

    // 拖拽移动
    onDragMove(event: GestureEvent): void {
        const newIndex = this.calculateNewIndex(event.offsetY);
        if (newIndex !== this.currentDragIndex) {
            this.swapItems(this.currentDragIndex, newIndex);
            this.currentDragIndex = newIndex;
        }
    }

    // 结束拖拽
    onDragEnd(): void {
        this.resetDragState();
    }
}

3.2 位置计算

class PositionCalculator {
    // 计算新位置
    static calculateNewIndex(offsetY: number): number {
        const itemHeight = px2vp($r('app.integer.list_item_height'));
        return Math.floor(offsetY / itemHeight);
    }

    // 计算动画位置
    static calculateAnimationPosition(
        currentIndex: number, 
        targetIndex: number
    ): number {
        const itemHeight = px2vp($r('app.integer.list_item_height'));
        return (targetIndex - currentIndex) * itemHeight;
    }
}

4. 滑动删除功能

4.1 滑动处理

class SwipeHandler {
    private swipeThreshold: number = 0.3;  // 触发删除的阈值

    // 处理滑动
    onSwipe(event: GestureEvent): void {
        const offset = event.offsetX;
        if (Math.abs(offset) > this.swipeThreshold) {
            this.showDeleteButton();
        } else {
            this.hideDeleteButton();
        }
    }

    // 显示删除按钮
    private showDeleteButton(): void {
        animateTo({
            duration: 300,
            curve: Curve.EaseOut
        }, () => {
            this.deleteButtonVisible = true;
        });
    }
}

4.2 删除确认

class DeleteConfirmation {
    // 确认删除
    static async confirmDelete(item: ListItem): Promise<boolean> {
        return new Promise((resolve) => {
            AlertDialog.show({
                title: '确认删除',
                message: '是否确认删除该项?',
                primaryButton: {
                    value: '确认',
                    action: () => resolve(true)
                },
                secondaryButton: {
                    value: '取消',
                    action: () => resolve(false)
                }
            });
        });
    }
}

5. 动画效果处理

5.1 拖拽动画

class DragAnimation {
    // 应用拖拽动画
    static applyDragAnimation(index: number): void {
        animateTo({
            duration: 300,
            curve: Curve.EaseInOut
        }, () => {
            // 缩放效果
            this.scale = 1.05;
            // 添加阴影
            this.shadow = true;
            // 提升层级
            this.zIndex = 999;
        });
    }
}

5.2 交换动画

class SwapAnimation {
    // 执行交换动画
    static animateSwap(fromIndex: number, toIndex: number): void {
        const offset = PositionCalculator.calculateAnimationPosition(
            fromIndex, 
            toIndex
        );

        animateTo({
            duration: 300,
            curve: Curve.EaseInOut
        }, () => {
            this.items[fromIndex].offsetY = offset;
            this.items[toIndex].offsetY = -offset;
        });
    }
}

6. 性能优化

6.1 列表优化

class ListOptimizer {
    // 虚拟列表优化
    static setupVirtualList(): void {
        List() {
            LazyForEach(this.dataSource, (item) => {
                ListItemView(item)
            })
        }
        .onScrollIndex((firstIndex: number) => {
            this.loadMoreIfNeeded(firstIndex);
        })
    }
}

6.2 事件优化

class EventOptimizer {
    private static lastEventTime: number = 0;
    private static readonly EVENT_THRESHOLD = 16;  // 60fps

    // 事件节流
    static throttleEvent(handler: () => void): void {
        const now = Date.now();
        if (now - this.lastEventTime >= this.EVENT_THRESHOLD) {
            handler();
            this.lastEventTime = now;
        }
    }
}

7. 错误处理

7.1 数据验证

class DataValidator {
    // 验证列表项
    static validateItem(item: ListItem): boolean {
        if (!item.id || !item.name) {
            throw new Error('Invalid item data');
        }
        return true;
    }

    // 验证操作
    static validateOperation(operation: string, item: ListItem): boolean {
        // 验证逻辑
        return true;
    }
}

7.2 异常恢复

class ErrorRecovery {
    // 恢复状态
    static async recover(): Promise<void> {
        try {
            // 恢复到上一个有效状态
            const lastValidState = await this.getLastValidState();
            this.restoreState(lastValidState);
        } catch (error) {
            console.error('Recovery failed:', error);
        }
    }
}

8. 最佳实践

8.1 开发建议

  1. 实现数据验证
  2. 优化性能表现
  3. 处理异常情况
  4. 添加动画效果

8.2 使用建议

  1. 合理使用事件
  2. 优化列表性能
  3. 实现错误处理
  4. 提供用户反馈

9. 小结

本篇教程详细介绍了:

  1. 列表项的基础结构设计
  2. 增删改查操作的实现
  3. 拖拽排序的处理方式
  4. 滑动删除的实现方法
  5. 动画效果的处理策略

下一篇将介绍性能优化的具体实现。


全栈若城
1 声望2 粉丝