154.[HarmonyOS NEXT 实战案例十一 :List系列] 自定义内容列表 - 进阶篇

2025-06-30 22:28:35
103次阅读
0个评论

[HarmonyOS NEXT 实战案例十一 :List系列] 自定义内容列表 - 进阶篇

项目已开源,开源地址: https://gitcode.com/nutpi/HarmonyosNextCaseStudyTutorial , 欢迎fork & star

效果演示

image.png

1. 概述

在基础篇中,我们学习了如何创建一个基本的自定义内容列表,展示不同类型的社交媒体内容。在这个进阶篇中,我们将深入探讨更高级的功能和优化技巧,使自定义内容列表更加完善和专业。

1.1 进阶功能概览

  • 内容交互与动画效果
  • 高级布局与自适应设计
  • 内容过滤与个性化推荐
  • 高级状态管理
  • 手势交互与操作
  • 内容分享与社交功能

2. 高级内容交互与动画

2.1 内容展开与折叠

对于长文本内容,我们可以实现展开与折叠功能,提升用户体验:

@State isExpanded: boolean = false
@State showExpandButton: boolean = false

@Builder
AdvancedTextContent(content: string, maxLines: number = 3) {
    Column() {
        Text(content)
            .fontSize(16)
            .margin({ top: 12, bottom: this.showExpandButton ? 4 : 12 })
            .maxLines(this.isExpanded ? undefined : maxLines)
            .textOverflow({ overflow: TextOverflow.Ellipsis })
            .onlineRender(true) // 提高渲染性能
            .onTouch((event) => {
                if (event.type === TouchType.Down) {
                    // 检测文本是否需要展开按钮
                    // 实际应用中可以通过测量文本高度来判断
                    this.showExpandButton = content.length > 100
                }
                return true
            })

        if (this.showExpandButton) {
            Text(this.isExpanded ? '收起' : '展开')
                .fontSize(14)
                .fontColor('#007AFF')
                .margin({ bottom: 12 })
                .onClick(() => {
                    animateTo({ duration: 300, curve: Curve.EaseOut }, () => {
                        this.isExpanded = !this.isExpanded
                    })
                })
        }
    }
}

2.2 图片浏览与缩放

为图片内容添加点击预览和缩放功能:

@State currentPreviewImage: Resource | null = null
@State showImagePreview: boolean = false

@Builder
AdvancedImageContent(images: Resource[]) {
    // 基本图片布局代码...
    
    // 为每个图片添加点击事件
    .onClick(() => {
        this.currentPreviewImage = image
        this.showImagePreview = true
    })
    
    // 图片预览弹窗
    if (this.showImagePreview && this.currentPreviewImage) {
        Column() {
            // 关闭按钮
            Image($r('app.media.close'))
                .width(32)
                .height(32)
                .position({ top: 40, right: 20 })
                .onClick(() => {
                    this.showImagePreview = false
                })
            
            // 图片预览,支持手势缩放
            Gesture(
                GestureGroup(GestureMode.Exclusive,
                    PinchGesture({ fingers: 2 })
                        .onActionUpdate((event) => {
                            // 实现缩放逻辑
                        }),
                    PanGesture()
                        .onActionUpdate((event) => {
                            // 实现平移逻辑
                        })
                )
            ) {
                Image(this.currentPreviewImage)
                    .width('100%')
                    .height('80%')
                    .objectFit(ImageFit.Contain)
            }
        }
        .width('100%')
        .height('100%')
        .backgroundColor('#000000E6')
        .position({ x: 0, y: 0 })
        .zIndex(999)
    }
}

2.3 视频内容的高级处理

实现视频内容的自动播放、暂停和进度控制:

@State isPlaying: boolean = false
@State currentProgress: number = 0
@State videoDuration: number = 60 // 假设视频时长为60秒

@Builder
AdvancedVideoContent(video: Resource) {
    Stack({ alignContent: Alignment.Center }) {
        // 实际应用中应使用Video组件
        Image(video)
            .width('100%')
            .height(240)
            .objectFit(ImageFit.Cover)
            .borderRadius(8)
            .opacity(this.isPlaying ? 0.8 : 1)

        if (!this.isPlaying) {
            // 播放按钮
            Image($r('app.media.01'))
                .width(60)
                .height(60)
                .onClick(() => {
                    this.isPlaying = true
                    // 开始播放视频的逻辑
                    this.startVideoPlayback()
                })
        } else {
            // 暂停按钮
            Image($r('app.media.pause'))
                .width(60)
                .height(60)
                .opacity(0.7)
                .onClick(() => {
                    this.isPlaying = false
                    // 暂停视频的逻辑
                    this.pauseVideoPlayback()
                })
        }

        // 视频进度条
        if (this.isPlaying) {
            Column() {
                Slider({
                    value: this.currentProgress,
                    min: 0,
                    max: this.videoDuration,
                    step: 1,
                    style: SliderStyle.OutSet
                })
                    .width('90%')
                    .onChange((value) => {
                        this.currentProgress = value
                        // 更新视频播放进度的逻辑
                        this.updateVideoProgress(value)
                    })

                Text(`${Math.floor(this.currentProgress / 60)}:${Math.floor(this.currentProgress % 60).toString().padStart(2, '0')} / ${Math.floor(this.videoDuration / 60)}:${Math.floor(this.videoDuration % 60).toString().padStart(2, '0')}`)
                    .fontSize(12)
                    .fontColor('#FFFFFF')
            }
            .width('100%')
            .position({ y: '85%' })
        }
    }
    .margin({ top: 12, bottom: 12 })

    // 模拟视频播放进度更新
    // 实际应用中应该使用Video组件的事件
    startVideoPlayback() {
        // 模拟视频播放进度更新
        this.videoTimer = setInterval(() => {
            if (this.currentProgress < this.videoDuration) {
                this.currentProgress++
            } else {
                this.isPlaying = false
                clearInterval(this.videoTimer)
                this.currentProgress = 0
            }
        }, 1000)
    }

    pauseVideoPlayback() {
        clearInterval(this.videoTimer)
    }

    updateVideoProgress(value: number) {
        // 实际应用中应该调用Video组件的seek方法
    }
}

3. 高级布局与自适应设计

3.1 响应式布局

实现根据屏幕尺寸自动调整的响应式布局:

@State screenWidth: number = 0

 aboutToAppear() {
    // 获取屏幕宽度
    this.screenWidth = px2vp(window.getWindowWidth())
    
    // 监听屏幕旋转事件
    window.on('resize', () => {
        this.screenWidth = px2vp(window.getWindowWidth())
    })
}

// 根据屏幕宽度调整布局
getImageLayout() {
    if (this.screenWidth < 600) {
        // 窄屏布局
        return {
            columns: 2,
            imageHeight: 120
        }
    } else if (this.screenWidth < 840) {
        // 中等屏幕布局
        return {
            columns: 3,
            imageHeight: 160
        }
    } else {
        // 宽屏布局
        return {
            columns: 4,
            imageHeight: 200
        }
    }
}

3.2 瀑布流布局

实现瀑布流布局,使内容展示更加丰富多样:

@Builder
WaterfallLayout(posts: Post[]) {
    WaterFlow({ footer: this.ListFooter }) {
        ForEach(posts, (post: Post) => {
            FlowItem() {
                // 内容卡片
                Column() {
                    // 用户信息
                    Row() {
                        Image(post.user.avatar)
                            .width(32)
                            .height(32)
                            .borderRadius(16)
                        
                        Text(post.user.name)
                            .fontSize(14)
                            .margin({ left: 8 })
                    }
                    .width('100%')
                    .margin({ bottom: 8 })
                    
                    // 内容展示
                    if (post.contentType === 'image' && post.media) {
                        Image(post.media[0])
                            .width('100%')
                            .aspectRatio(post.id % 3 === 0 ? 1 : (post.id % 3 === 1 ? 4/3 : 3/4))
                            .objectFit(ImageFit.Cover)
                            .borderRadius(8)
                    }
                    
                    // 文本内容
                    Text(post.content)
                        .fontSize(14)
                        .margin({ top: 8, bottom: 8 })
                        .maxLines(3)
                        .textOverflow({ overflow: TextOverflow.Ellipsis })
                    
                    // 互动信息
                    Row() {
                        Row() {
                            Image($r('app.media.heart_outline'))
                                .width(16)
                                .height(16)
                            Text(post.likes.toString())
                                .fontSize(12)
                                .margin({ left: 4 })
                        }
                        
                        Row() {
                            Image($r('app.media.note_icon'))
                                .width(16)
                                .height(16)
                            Text(post.comments.toString())
                                .fontSize(12)
                                .margin({ left: 4 })
                        }
                        .margin({ left: 16 })
                    }
                    .width('100%')
                }
                .width('100%')
                .padding(12)
                .backgroundColor('#FFFFFF')
                .borderRadius(8)
            }
            .width('100%')
        })
    }
    .columnsTemplate('1fr 1fr')
    .columnsGap(8)
    .rowsGap(8)
    .layoutWeight(1)
    .padding(8)
}

@Builder
ListFooter() {
    Column() {
        if (this.isLoading) {
            LoadingProgress()
                .width(24)
                .height(24)
            Text('加载中...')
                .fontSize(14)
                .margin({ top: 8 })
        } else {
            Text('没有更多内容了')
                .fontSize(14)
                .fontColor('#999999')
        }
    }
    .width('100%')
    .padding({ top: 16, bottom: 16 })
    .justifyContent(FlexAlign.Center)
}

4. 内容过滤与个性化推荐

4.1 内容分类与标签

实现内容分类和标签过滤功能:

// 内容分类
enum ContentCategory {
    All = '全部',
    Recommended = '推荐',
    Following = '关注',
    Trending = '热门',
    Nearby = '附近'
}

// 内容标签
interface ContentTag {
    id: number;
    name: string;
}

// 为Post添加分类和标签
interface Post {
    // 原有属性...
    category: ContentCategory;
    tags: ContentTag[];
}

@State currentCategory: ContentCategory = ContentCategory.All
@State selectedTags: number[] = []

// 过滤内容
getFilteredPosts(): Post[] {
    return this.posts.filter(post => {
        // 分类过滤
        if (this.currentCategory !== ContentCategory.All && post.category !== this.currentCategory) {
            return false
        }
        
        // 标签过滤
        if (this.selectedTags.length > 0) {
            const hasSelectedTag = post.tags.some(tag => this.selectedTags.includes(tag.id))
            if (!hasSelectedTag) {
                return false
            }
        }
        
        return true
    })
}

// 分类选择器UI
@Builder
CategorySelector() {
    Row() {
        ForEach(Object.values(ContentCategory), (category: string) => {
            Text(category)
                .fontSize(16)
                .fontWeight(this.currentCategory === category ? FontWeight.Bold : FontWeight.Normal)
                .fontColor(this.currentCategory === category ? '#FF5722' : '#333333')
                .padding({ left: 12, right: 12, top: 8, bottom: 8 })
                .backgroundColor(this.currentCategory === category ? '#FFF3F0' : 'transparent')
                .borderRadius(16)
                .margin({ right: 8 })
                .onClick(() => {
                    this.currentCategory = category as ContentCategory
                })
        })
    }
    .width('100%')
    .padding({ left: 16, right: 16, top: 8, bottom: 8 })
    .scrollable(ScrollDirection.Horizontal)
}

4.2 内容搜索功能

实现内容搜索功能:

@State searchText: string = ''
@State isSearching: boolean = false
@State searchResults: Post[] = []

// 搜索内容
searchPosts() {
    if (this.searchText.trim() === '') {
        this.searchResults = []
        return
    }
    
    // 简单的文本匹配搜索
    this.searchResults = this.posts.filter(post => {
        return post.content.toLowerCase().includes(this.searchText.toLowerCase()) ||
               post.user.name.toLowerCase().includes(this.searchText.toLowerCase())
    })
}

// 搜索框UI
@Builder
SearchBar() {
    Row() {
        if (!this.isSearching) {
            Image($r('app.media.search'))
                .width(24)
                .height(24)
                .margin({ right: 8 })
        } else {
            Image($r('app.media.back'))
                .width(24)
                .height(24)
                .margin({ right: 8 })
                .onClick(() => {
                    this.isSearching = false
                    this.searchText = ''
                    this.searchResults = []
                })
        }
        
        TextInput({ placeholder: '搜索内容', text: this.searchText })
            .width('80%')
            .height(40)
            .backgroundColor('#F5F5F5')
            .borderRadius(20)
            .padding({ left: 16, right: 16 })
            .onChange((value) => {
                this.searchText = value
                this.searchPosts()
            })
            .onSubmit(() => {
                this.searchPosts()
            })
            .onClick(() => {
                this.isSearching = true
            })
        
        if (this.searchText !== '') {
            Image($r('app.media.clear'))
                .width(24)
                .height(24)
                .margin({ left: 8 })
                .onClick(() => {
                    this.searchText = ''
                    this.searchResults = []
                })
        }
    }
    .width('100%')
    .padding({ left: 16, right: 16, top: 8, bottom: 8 })
}

5. 高级状态管理

5.1 使用AppStorage进行状态管理

// 在应用启动时初始化
AppStorage.SetOrCreate('likedPosts', new Set<number>())
AppStorage.SetOrCreate('savedPosts', new Set<number>())

// 在组件中使用
@StorageLink('likedPosts') likedPosts: Set<number> = new Set<number>()
@StorageLink('savedPosts') savedPosts: Set<number> = new Set<number>()

// 点赞操作
toggleLike(id: number) {
    if (this.likedPosts.has(id)) {
        this.likedPosts.delete(id)
    } else {
        this.likedPosts.add(id)
    }
    
    // 更新UI状态
    this.posts = this.posts.map(post => {
        if (post.id === id) {
            post.isLiked = this.likedPosts.has(id)
            post.likes = post.isLiked ? post.likes + 1 : post.likes - 1
        }
        return post
    })
}

// 保存操作
toggleSave(id: number) {
    if (this.savedPosts.has(id)) {
        this.savedPosts.delete(id)
    } else {
        this.savedPosts.add(id)
    }
}

5.2 使用PersistentStorage持久化状态

// 定义持久化存储
PersistentStorage.PersistProp<Set<number>>('likedPosts', new Set<number>())
PersistentStorage.PersistProp<Set<number>>('savedPosts', new Set<number>())

// 在组件中使用
@StorageProp('likedPosts') likedPosts: Set<number> = new Set<number>()
@StorageProp('savedPosts') savedPosts: Set<number> = new Set<number>()

6. 手势交互与操作

6.1 滑动操作菜单

实现滑动显示操作菜单的功能:

@State swipedPostId: number | null = null

@Builder
SwipeablePostItem(post: Post) {
    Stack() {
        // 操作菜单背景
        Row() {
            Button() {
                Image($r('app.media.share'))
                    .width(24)
                    .height(24)
                    .fillColor('#FFFFFF')
            }
            .width(80)
            .height('100%')
            .backgroundColor('#4CAF50')
            .onClick(() => {
                // 分享操作
                this.sharePost(post)
            })
            
            Button() {
                Image($r('app.media.delete'))
                    .width(24)
                    .height(24)
                    .fillColor('#FFFFFF')
            }
            .width(80)
            .height('100%')
            .backgroundColor('#F44336')
            .onClick(() => {
                // 删除操作
                this.deletePost(post.id)
            })
        }
        .width('100%')
        .height('100%')
        .justifyContent(FlexAlign.End)
        
        // 内容卡片
        Column() {
            // 帖子内容...
        }
        .width('100%')
        .padding(16)
        .backgroundColor('#FFFFFF')
        .borderRadius(8)
        .translate({ x: this.swipedPostId === post.id ? -160 : 0 })
        .gesture(
            PanGesture({ direction: PanDirection.Horizontal })
                .onActionStart(() => {
                    // 开始滑动时记录当前帖子ID
                    this.swipedPostId = post.id
                })
                .onActionUpdate((event) => {
                    // 限制最大滑动距离
                    if (event.offsetX < -160) {
                        event.offsetX = -160
                    } else if (event.offsetX > 0) {
                        event.offsetX = 0
                    }
                })
                .onActionEnd((event) => {
                    // 根据滑动距离决定是否显示操作菜单
                    if (event.offsetX < -80) {
                        animateTo({ duration: 300 }, () => {
                            // 显示完整操作菜单
                            this.swipedPostId = post.id
                        })
                    } else {
                        animateTo({ duration: 300 }, () => {
                            // 恢复原位
                            this.swipedPostId = null
                        })
                    }
                })
        )
    }
    .width('100%')
    .height(post.contentType === 'text' ? 'auto' : 'auto')
    .clip(true)
}

6.2 双击点赞

实现双击点赞功能:

@Builder
DoubleTapLikeContent(post: Post) {
    Stack() {
        // 内容展示
        // ...
        
        // 点赞动画
        if (this.doubleTapLikePostId === post.id) {
            Image($r('app.media.heart_filled'))
                .width(80)
                .height(80)
                .fillColor('#FF5722')
                .opacity(this.likeAnimationOpacity)
                .scale({ x: this.likeAnimationScale, y: this.likeAnimationScale })
                .onAppear(() => {
                    // 播放点赞动画
                    animateTo(
                        { duration: 600, curve: Curve.Ease },
                        () => {
                            this.likeAnimationScale = 1.2
                            this.likeAnimationOpacity = 0
                        }
                    )
                })
                .onDisAppear(() => {
                    // 重置动画状态
                    this.likeAnimationScale = 0.5
                    this.likeAnimationOpacity = 1
                    this.doubleTapLikePostId = null
                })
        }
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
    .gesture(
        TapGesture({ count: 2 })
            .onAction(() => {
                // 双击点赞
                if (!post.isLiked) {
                    this.toggleLike(post.id)
                }
                
                // 显示点赞动画
                this.doubleTapLikePostId = post.id
            })
    )
}

7. 内容分享与社交功能

7.1 分享菜单

实现内容分享菜单:

@State showShareMenu: boolean = false
@State sharePostId: number | null = null

// 分享帖子
sharePost(post: Post) {
    this.sharePostId = post.id
    this.showShareMenu = true
}

@Builder
ShareMenu() {
    if (this.showShareMenu && this.sharePostId) {
        Column() {
            // 分享标题
            Text('分享到')
                .fontSize(18)
                .fontWeight(FontWeight.Medium)
                .margin({ top: 16, bottom: 16 })
            
            // 分享选项
            Grid() {
                // 微信
                GridItem() {
                    Column() {
                        Image($r('app.media.wechat'))
                            .width(48)
                            .height(48)
                            .borderRadius(24)
                        Text('微信')
                            .fontSize(14)
                            .margin({ top: 8 })
                    }
                    .onClick(() => {
                        // 分享到微信
                        this.shareToWechat()
                    })
                }
                
                // 朋友圈
                GridItem() {
                    Column() {
                        Image($r('app.media.moments'))
                            .width(48)
                            .height(48)
                            .borderRadius(24)
                        Text('朋友圈')
                            .fontSize(14)
                            .margin({ top: 8 })
                    }
                    .onClick(() => {
                        // 分享到朋友圈
                        this.shareToMoments()
                    })
                }
                
                // 微博
                GridItem() {
                    Column() {
                        Image($r('app.media.weibo'))
                            .width(48)
                            .height(48)
                            .borderRadius(24)
                        Text('微博')
                            .fontSize(14)
                            .margin({ top: 8 })
                    }
                    .onClick(() => {
                        // 分享到微博
                        this.shareToWeibo()
                    })
                }
                
                // 更多选项...
            }
            .columnsTemplate('1fr 1fr 1fr 1fr')
            .rowsTemplate('1fr')
            .columnsGap(16)
            .width('100%')
            .padding({ left: 16, right: 16 })
            
            // 取消按钮
            Button('取消')
                .width('90%')
                .height(44)
                .margin({ top: 24, bottom: 16 })
                .backgroundColor('#F5F5F5')
                .fontColor('#333333')
                .onClick(() => {
                    this.showShareMenu = false
                })
        }
        .width('100%')
        .padding({ top: 16, bottom: 16 })
        .backgroundColor('#FFFFFF')
        .borderRadius({ topLeft: 16, topRight: 16 })
        .position({ x: 0, y: '70%' })
    }
}

7.2 评论功能

实现评论功能:

interface Comment {
    id: number;
    postId: number;
    user: User;
    content: string;
    time: string;
    likes: number;
    isLiked: boolean;
    replies?: Comment[];
}

@State showComments: boolean = false
@State currentPostId: number | null = null
@State commentText: string = ''
@State comments: Comment[] = [
    // 初始评论数据
]

// 打开评论面板
openComments(postId: number) {
    this.currentPostId = postId
    this.showComments = true
}

// 添加评论
addComment() {
    if (this.commentText.trim() === '' || !this.currentPostId) {
        return
    }
    
    // 创建新评论
    const newComment: Comment = {
        id: this.comments.length + 1,
        postId: this.currentPostId,
        user: {
            name: '我',
            avatar: $r('app.media.avatar_me')
        },
        content: this.commentText,
        time: '刚刚',
        likes: 0,
        isLiked: false
    }
    
    // 添加到评论列表
    this.comments.unshift(newComment)
    
    // 更新帖子评论数
    this.posts = this.posts.map(post => {
        if (post.id === this.currentPostId) {
            post.comments++
        }
        return post
    })
    
    // 清空输入框
    this.commentText = ''
}

@Builder
CommentPanel() {
    if (this.showComments && this.currentPostId) {
        Column() {
            // 评论标题
            Row() {
                Text('评论')
                    .fontSize(18)
                    .fontWeight(FontWeight.Medium)
                
                Blank()
                
                Image($r('app.media.close'))
                    .width(24)
                    .height(24)
                    .onClick(() => {
                        this.showComments = false
                    })
            }
            .width('100%')
            .padding({ left: 16, right: 16, top: 16, bottom: 16 })
            
            // 评论列表
            List() {
                ForEach(this.getPostComments(this.currentPostId), (comment: Comment) => {
                    ListItem() {
                        Row() {
                            // 用户头像
                            Image(comment.user.avatar)
                                .width(40)
                                .height(40)
                                .borderRadius(20)
                            
                            // 评论内容
                            Column() {
                                Text(comment.user.name)
                                    .fontSize(14)
                                    .fontWeight(FontWeight.Medium)
                                
                                Text(comment.content)
                                    .fontSize(16)
                                    .margin({ top: 4, bottom: 4 })
                                
                                Row() {
                                    Text(comment.time)
                                        .fontSize(12)
                                        .fontColor('#999999')
                                    
                                    Text('回复')
                                        .fontSize(12)
                                        .fontColor('#666666')
                                        .margin({ left: 16 })
                                    
                                    Blank()
                                    
                                    Row() {
                                        Image(comment.isLiked ? $r('app.media.heart_filled') : $r('app.media.heart_outline'))
                                            .width(16)
                                            .height(16)
                                            .fillColor(comment.isLiked ? '#FF5722' : '#666666')
                                        
                                        Text(comment.likes.toString())
                                            .fontSize(12)
                                            .fontColor('#666666')
                                            .margin({ left: 4 })
                                    }
                                    .onClick(() => {
                                        // 点赞评论
                                        this.toggleCommentLike(comment.id)
                                    })
                                }
                                .width('100%')
                            }
                            .alignItems(HorizontalAlign.Start)
                            .margin({ left: 12 })
                            .layoutWeight(1)
                        }
                        .width('100%')
                        .padding({ top: 12, bottom: 12 })
                    }
                })
            }
            .width('100%')
            .layoutWeight(1)
            .padding({ left: 16, right: 16 })
            
            // 评论输入框
            Row() {
                TextInput({ placeholder: '添加评论...', text: this.commentText })
                    .width('80%')
                    .height(40)
                    .backgroundColor('#F5F5F5')
                    .borderRadius(20)
                    .padding({ left: 16, right: 16 })
                    .onChange((value) => {
                        this.commentText = value
                    })
                
                Button() {
                    Text('发送')
                        .fontSize(14)
                        .fontColor(this.commentText.trim() !== '' ? '#FFFFFF' : '#AAAAAA')
                }
                .width(60)
                .height(40)
                .margin({ left: 8 })
                .borderRadius(20)
                .backgroundColor(this.commentText.trim() !== '' ? '#007AFF' : '#F5F5F5')
                .onClick(() => {
                    this.addComment()
                })
            }
            .width('100%')
            .padding({ left: 16, right: 16, top: 8, bottom: 8 })
            .backgroundColor('#FFFFFF')
            .borderColor('#E5E5E5')
            .borderWidth({ top: 1 })
        }
        .width('100%')
        .height('80%')
        .backgroundColor('#FFFFFF')
        .borderRadius({ topLeft: 16, topRight: 16 })
        .position({ x: 0, y: '20%' })
    }
}

// 获取指定帖子的评论
getPostComments(postId: number): Comment[] {
    return this.comments.filter(comment => comment.postId === postId)
}

// 点赞评论
toggleCommentLike(commentId: number) {
    this.comments = this.comments.map(comment => {
        if (comment.id === commentId) {
            comment.isLiked = !comment.isLiked
            comment.likes = comment.isLiked ? comment.likes + 1 : comment.likes - 1
        }
        return comment
    })
}

8. 常见问题与解决方案

8.1 列表性能优化

问题:当列表项较多且复杂时,可能导致滚动卡顿和内存占用过高。

解决方案

  • 使用LazyForEach替代ForEach,实现虚拟列表
  • 设置合理的cachedCount值,控制缓存的列表项数量
  • 使用onlineRender属性提高渲染性能
  • 减少列表项的嵌套层级和复杂度

8.2 图片加载优化

问题:大量图片加载可能导致内存占用过高和UI卡顿。

解决方案

  • 使用syncLoad(false)异步加载图片
  • 实现图片懒加载,只在图片进入视口时才加载
  • 使用适当的图片尺寸和压缩比例
  • 实现图片缓存机制,避免重复加载

8.3 手势冲突处理

问题:多个手势可能发生冲突,导致交互体验不佳。

解决方案

  • 使用GestureGroupGestureMode.Exclusive设置手势优先级
  • 合理设置手势的触发条件和范围
  • 使用event.stopPropagation()阻止事件传播

9. 总结与扩展

在本教程中,我们深入探讨了如何实现一个功能丰富、交互良好的自定义内容列表,包括高级内容交互与动画、响应式布局、内容过滤与搜索、高级状态管理、手势交互以及社交功能等方面。

收藏00

登录 后评论。没有帐号? 注册 一个。

全栈若城

  • 0回答
  • 4粉丝
  • 0关注
相关话题