在这里插入图片描述

前言

好友列表是社交应用的核心功能模块,用户通过它查看和管理自己的社交关系。一个优秀的好友列表组件需要支持高效的数据渲染、流畅的滚动体验、便捷的搜索过滤以及丰富的交互操作。本文将详细讲解如何在Flutter和OpenHarmony平台上构建专业级的好友列表组件。

Flutter好友列表实现

首先定义好友数据模型和列表组件结构。

class Friend {
  final String id;
  final String name;
  final String avatar;
  final bool isOnline;
  final String? lastMessage;
  
  Friend({
    required this.id,
    required this.name,
    required this.avatar,
    this.isOnline = false,
    this.lastMessage,
  });
}

Friend类定义了好友的基本属性,包括唯一标识、昵称、头像地址、在线状态和最后一条消息。使用required关键字确保必要字段不为空,可选字段使用nullable类型。

class FriendListItem extends StatelessWidget {
  final Friend friend;
  final VoidCallback onTap;
  
  const FriendListItem({
    Key? key,
    required this.friend,
    required this.onTap,
  }) : super(key: key);
  
  
  Widget build(BuildContext context) {
    return ListTile(
      onTap: onTap,
      leading: Stack(
        children: [
          CircleAvatar(
            radius: 24,
            backgroundImage: NetworkImage(friend.avatar),
          ),

FriendListItem组件负责渲染单个好友项。ListTile是Flutter提供的标准列表项组件,内置了良好的触摸反馈和布局结构。leading位置放置头像,使用Stack实现头像和在线状态指示器的叠加效果。CircleAvatar简化了圆形头像的实现。

          if (friend.isOnline)
            Positioned(
              right: 0,
              bottom: 0,
              child: Container(
                width: 12,
                height: 12,
                decoration: BoxDecoration(
                  color: Colors.green,
                  shape: BoxShape.circle,
                  border: Border.all(color: Colors.white, width: 2),
                ),
              ),
            ),
        ],
      ),

在线状态指示器使用Positioned定位在头像右下角。绿色圆点配合白色边框,在各种背景下都能清晰可见。条件渲染确保只有在线用户才显示指示器,这种细节处理能够有效传达用户状态信息。

      title: Text(
        friend.name,
        style: TextStyle(
          fontWeight: FontWeight.w600,
          fontSize: 16,
        ),
      ),
      subtitle: friend.lastMessage != null
        ? Text(
            friend.lastMessage!,
            maxLines: 1,
            overflow: TextOverflow.ellipsis,
            style: TextStyle(
              color: Colors.grey[600],
              fontSize: 14,
            ),
          )
        : null,
      trailing: Icon(
        Icons.chevron_right,
        color: Colors.grey[400],
      ),
    );
  }
}

title显示好友昵称,使用稍粗的字重突出显示。subtitle显示最后一条消息,maxLines和overflow处理长文本截断。trailing放置箭头图标提示可点击。这种布局是社交应用好友列表的标准设计模式。

class FriendList extends StatelessWidget {
  final List<Friend> friends;
  final Function(Friend) onFriendTap;
  
  const FriendList({
    Key? key,
    required this.friends,
    required this.onFriendTap,
  }) : super(key: key);
  
  
  Widget build(BuildContext context) {
    return ListView.separated(
      itemCount: friends.length,
      separatorBuilder: (context, index) => Divider(
        height: 1,
        indent: 72,
      ),

FriendList组件管理整个列表的渲染。ListView.separated自动在列表项之间添加分隔线,indent设置左侧缩进,让分隔线从头像右侧开始,视觉效果更加精致。这种细节处理体现了专业的UI设计水准。

      itemBuilder: (context, index) {
        return FriendListItem(
          friend: friends[index],
          onTap: () => onFriendTap(friends[index]),
        );
      },
    );
  }
}

itemBuilder按需构建列表项,只渲染可见区域的内容,这是ListView的核心优化机制。对于包含大量好友的列表,这种懒加载方式能够显著提升性能和内存效率。

OpenHarmony ArkTS实现

接下来看鸿蒙系统上的实现方案。

interface Friend {
  id: string
  name: string
  avatar: string
  isOnline: boolean
  lastMessage?: string
}

@Component
struct FriendListItem {
  @Prop friend: Friend
  onTap: () => void = () => {}

TypeScript接口定义好友数据结构,可选属性使用问号标记。@Component和@Prop的使用方式与之前的组件一致。

  build() {
    Row() {
      Stack({ alignContent: Alignment.BottomEnd }) {
        Image(this.friend.avatar)
          .width(48)
          .height(48)
          .borderRadius(24)
        
        if (this.friend.isOnline) {
          Circle()
            .width(12)
            .height(12)
            .fill(Color.Green)
            .stroke(Color.White)
            .strokeWidth(2)
        }
      }
      .width(48)
      .height(48)

Row作为根容器水平排列头像和文字信息。Stack实现头像和在线指示器的叠加,alignContent设置子元素对齐方式。Image组件加载网络头像,borderRadius实现圆形效果。条件渲染在线指示器的逻辑与Flutter版本一致。

      Column() {
        Text(this.friend.name)
          .fontSize(16)
          .fontWeight(FontWeight.Medium)
          .fontColor('#1C1C1E')
        
        if (this.friend.lastMessage) {
          Text(this.friend.lastMessage)
            .fontSize(14)
            .fontColor('#8E8E93')
            .maxLines(1)
            .textOverflow({ overflow: TextOverflow.Ellipsis })
            .margin({ top: 4 })
        }
      }
      .alignItems(HorizontalAlign.Start)
      .layoutWeight(1)
      .margin({ left: 12 })

Column垂直排列昵称和最后消息。fontWeight设置字重,fontColor使用十六进制颜色值。maxLines和textOverflow处理文本截断。layoutWeight(1)让文字区域占据剩余空间,alignItems设置左对齐。

      Image($r('app.media.ic_arrow_right'))
        .width(20)
        .height(20)
        .fillColor('#C7C7CC')
    }
    .width('100%')
    .height(72)
    .padding({ left: 16, right: 16 })
    .backgroundColor(Color.White)
    .onClick(() => this.onTap())
  }
}

右侧箭头图标使用fillColor设置颜色。整个Row设置固定高度、内边距和背景色,onClick绑定点击事件。72像素的高度是移动端列表项的标准尺寸,既能容纳足够信息又不会过于拥挤。

@Component
struct FriendList {
  @Prop friends: Friend[] = []
  onFriendTap: (friend: Friend) => void = () => {}
  
  build() {
    List() {
      ForEach(this.friends, (friend: Friend, index: number) => {
        ListItem() {
          FriendListItem({
            friend: friend,
            onTap: () => this.onFriendTap(friend)
          })
        }
      })
    }
    .divider({
      strokeWidth: 1,
      startMargin: 76,
      color: '#E5E5EA'
    })
  }
}

List组件配合ForEach实现列表渲染。divider属性设置分隔线样式,startMargin对应Flutter中的indent。ArkTS的List组件同样具备懒加载优化,只渲染可见区域的内容。

总结

本文详细介绍了好友列表组件在Flutter和OpenHarmony两个平台上的实现。好友列表是社交应用的核心组件,需要关注性能优化、视觉细节和交互体验。两个平台都提供了高效的列表渲染机制,开发者可以根据具体需求扩展搜索、分组、侧滑操作等功能。

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐