You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中如何展示从Firebase实时数据库获取的最近播放歌曲

最近播放歌曲展示方案(Flutter + Firebase)

一、数据层处理(核心逻辑)

1. Firebase数据结构设计

在实时数据库中给每个用户单独维护一个recentlyPlayed节点,每条记录包含:

  • songId: 歌曲唯一标识
  • playTime: 播放时间戳(用于排序)
  • 可选:歌曲名称、歌手、封面URL(避免每次拉取详情,提升加载速度)

示例结构:

"users": {
  "userId_123": {
    "recentlyPlayed": {
      "record_01": {
        "songId": "song_001",
        "playTime": 1699999999000,
        "title": "XXX",
        "artist": "YYY",
        "coverUrl": "https://xxx.com/cover.jpg"
      },
      "record_02": {
        // ... 其他歌曲数据
      }
    }
  }
}

2. 更新最近播放记录

每次播放歌曲时,向recentlyPlayed节点写入新记录,同时限制只保留最近10条(可自定义数量):

import 'package:firebase_database/firebase_database.dart';

Future<void> updateRecentlyPlayed(String userId, Map<String, dynamic> songData) async {
  final ref = FirebaseDatabase.instance.ref('users/$userId/recentlyPlayed');
  // 先获取当前已有记录数量
  final snapshot = await ref.limitToLast(10).get();
  if (snapshot.children.length >= 10) {
    // 删除最早的一条记录
    final oldestKey = snapshot.children.first.key;
    await ref.child(oldestKey!).remove();
  }
  // 添加新记录(用时间戳作为键,保证唯一性)
  await ref.child('${DateTime.now().millisecondsSinceEpoch}').set({
    ...songData,
    'playTime': DateTime.now().millisecondsSinceEpoch,
  });
}

3. 获取最近播放列表

通过时间戳倒序获取最近N条记录,用StreamBuilder监听实时更新:

Stream<List<Map<String, dynamic>>> getRecentlyPlayedStream(String userId) {
  final ref = FirebaseDatabase.instance.ref('users/$userId/recentlyPlayed')
      .orderByChild('playTime')
      .limitToLast(10);
  
  return ref.onValue.map((event) {
    final data = event.snapshot.value as Map<dynamic, dynamic>?;
    if (data == null) return [];
    // 转换为列表并反转(因为orderByChild是升序,反转后变成最新的在前)
    final list = data.values.map((e) => Map<String, dynamic>.from(e)).toList();
    list.sort((a, b) => b['playTime'].compareTo(a['playTime']));
    return list;
  });
}

二、UI层展示

1. 基础列表实现

用ListView.builder配合StreamBuilder实现实时更新的列表:

StreamBuilder<List<Map<String, dynamic>>>(
  stream: getRecentlyPlayedStream('当前用户ID'),
  builder: (context, snapshot) {
    if (!snapshot.hasData) return const Center(child: CircularProgressIndicator());
    final songs = snapshot.data!;
    if (songs.isEmpty) return const Center(child: Text('暂无最近播放'));
    
    return ListView.builder(
      itemCount: songs.length,
      itemBuilder: (context, index) {
        final song = songs[index];
        return ListTile(
          leading: ClipRRect(
            borderRadius: BorderRadius.circular(8),
            child: Image.network(
              song['coverUrl'],
              width: 50,
              height: 50,
              fit: BoxFit.cover,
              errorBuilder: (_, __, ___) => const Icon(Icons.music_note),
            ),
          ),
          title: Text(song['title']),
          subtitle: Text(song['artist']),
          onTap: () {
            // 触发播放逻辑(已有播放功能,直接调用对应方法)
            playSong(song['songId']);
          },
        );
      },
    );
  },
)

2. 增强UI体验

  • 图片缓存:用cached_network_image包替代Image.network,避免重复加载网络图片
    CachedNetworkImage(
      imageUrl: song['coverUrl'],
      width: 50,
      height: 50,
      fit: BoxFit.cover,
      placeholder: (_, __) => const Icon(Icons.music_note),
      errorWidget: (_, __, ___) => const Icon(Icons.music_note),
    )
    
  • 滑动删除:用flutter_slidable实现滑动删除最近播放条目
    Slidable(
      endActionPane: ActionPane(
        motion: const ScrollMotion(),
        children: [
          SlidableAction(
            onPressed: (_) => deleteRecentRecord('当前用户ID', songs[index]['recordKey']),
            backgroundColor: Colors.red,
            foregroundColor: Colors.white,
            icon: Icons.delete,
            label: '删除',
          ),
        ],
      ),
      child: ListTile(/* ... 原有内容 ... */),
    )
    

三、推荐包总结

  • 核心数据操作:firebase_database(官方包,稳定可靠,直接对接实时数据库)
  • 图片缓存:cached_network_image(提升图片加载性能)
  • 交互增强:flutter_slidable(滑动操作)、pull_to_refresh(下拉刷新,按需使用)
  • 本地缓存(可选):hive(适合存储结构化的最近播放数据,离线时也能展示)

内容的提问来源于stack exchange,提问作者Lavina Daryanani

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 14:22:45