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

如何为集成Firebase Cloud Messaging的应用创建RecyclerView通知列表Activity?

嘿,我来帮你搞定这个需求!要实现用RecyclerView展示用户收到的所有FCM通知,核心是先把收到的通知存下来(毕竟FCM不会自动帮你保存历史通知),再用RecyclerView把存储的数据渲染出来。下面是一步步的具体操作,非常清晰:

第一步:先把FCM通知存储到本地

推荐用Room数据库来存储通知数据,它适合结构化数据的持久化,比SharedPreferences更适合多通知场景:

  1. 定义Notification实体类,用来映射数据库表
@Entity(tableName = "notifications")
data class NotificationEntity(
    @PrimaryKey(autoGenerate = true) val id: Int = 0,
    val title: String,
    val content: String,
    val timestamp: Long // 记录通知收到的时间戳,方便排序
)
  1. 创建Dao接口,定义数据库操作方法
@Dao
interface NotificationDao {
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insertNotification(notification: NotificationEntity)

    @Query("SELECT * FROM notifications ORDER BY timestamp DESC")
    fun getAllNotifications(): Flow<List<NotificationEntity>> // 用Flow实现数据变化监听
}
  1. 创建Room数据库单例类
@Database(entities = [NotificationEntity::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
    abstract fun notificationDao(): NotificationDao

    companion object {
        @Volatile
        private var INSTANCE: AppDatabase? = null

        fun getDatabase(context: Context): AppDatabase {
            return INSTANCE ?: synchronized(this) {
                val instance = Room.databaseBuilder(
                    context.applicationContext,
                    AppDatabase::class.java,
                    "app_database"
                ).build()
                INSTANCE = instance
                instance
            }
        }
    }
}
  1. 在FCM消息服务中存储通知
    不管前台还是后台收到FCM消息,都要在FirebaseMessagingService的onMessageReceived回调里把通知数据插入数据库:
class MyFirebaseMessagingService : FirebaseMessagingService() {
    private lateinit var notificationDao: NotificationDao

    override fun onCreate() {
        super.onCreate()
        val db = AppDatabase.getDatabase(this)
        notificationDao = db.notificationDao()
    }

    override fun onMessageReceived(remoteMessage: RemoteMessage) {
        super.onMessageReceived(remoteMessage)
        // 提取通知内容,兼容没有标题/内容的情况
        val title = remoteMessage.notification?.title ?: "无标题"
        val content = remoteMessage.notification?.body ?: "无内容"
        val timestamp = System.currentTimeMillis()

        // 用协程在IO线程插入数据库
        CoroutineScope(Dispatchers.IO).launch {
            notificationDao.insertNotification(
                NotificationEntity(title = title, content = content, timestamp = timestamp)
            )
        }

        // 保留你原来的通知推送逻辑
        // ...
    }
}
第二步:编写RecyclerView适配器

这个适配器负责把数据库里的通知数据渲染到列表项上:

class NotificationAdapter(private val notifications: List<NotificationEntity>) :
    RecyclerView.Adapter<NotificationAdapter.NotificationViewHolder>() {

    inner class NotificationViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        val tvTitle: TextView = itemView.findViewById(R.id.tv_notification_title)
        val tvContent: TextView = itemView.findViewById(R.id.tv_notification_content)
        val tvTime: TextView = itemView.findViewById(R.id.tv_notification_time)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): NotificationViewHolder {
        val view = LayoutInflater.from(parent.context)
            .inflate(R.layout.item_notification, parent, false)
        return NotificationViewHolder(view)
    }

    override fun onBindViewHolder(holder: NotificationViewHolder, position: Int) {
        val notification = notifications[position]
        holder.tvTitle.text = notification.title
        holder.tvContent.text = notification.content
        // 把时间戳格式化成可读的日期时间
        val dateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.getDefault())
        holder.tvTime.text = dateFormat.format(Date(notification.timestamp))
    }

    override fun getItemCount() = notifications.size
}

对应的列表项布局item_notification.xml可以这样写:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:padding="12dp"
    android:background="?android:attr/selectableItemBackground">

    <TextView
        android:id="@+id/tv_notification_title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="16sp"
        android:textStyle="bold"/>

    <TextView
        android:id="@+id/tv_notification_content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="14sp"
        android:layout_marginTop="4dp"/>

    <TextView
        android:id="@+id/tv_notification_time"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="12sp"
        android:textColor="@android:color/darker_gray"
        android:layout_marginTop="8dp"/>

</LinearLayout>
第三步:创建通知列表Activity

先写Activity的布局activity_notification_list.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rv_notifications"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="8dp"/>

</LinearLayout>

然后写Activity的逻辑代码,监听数据库数据变化,实时更新RecyclerView:

class NotificationListActivity : AppCompatActivity() {
    private lateinit var notificationDao: NotificationDao
    private lateinit var adapter: NotificationAdapter

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_notification_list)

        val db = AppDatabase.getDatabase(this)
        notificationDao = db.notificationDao()

        // 初始化RecyclerView
        val rvNotifications = findViewById<RecyclerView>(R.id.rv_notifications)
        rvNotifications.layoutManager = LinearLayoutManager(this)
        adapter = NotificationAdapter(emptyList())
        rvNotifications.adapter = adapter

        // 用生命周期协程监听数据库数据变化,自动更新列表
        lifecycleScope.launch {
            notificationDao.getAllNotifications().collect { notifications ->
                adapter = NotificationAdapter(notifications)
                rvNotifications.adapter = adapter
            }
        }
    }
}

最后别忘在AndroidManifest.xml里注册这个Activity:

<activity android:name=".NotificationListActivity"/>
额外小提示
  • 如果你用Java开发,只需要把Kotlin代码转成对应的Java语法就行,核心逻辑完全一致。
  • 要是通知数量特别多,可以考虑添加分页加载,避免一次性加载大量数据拖慢性能。
  • 还能给列表项加点击事件,比如点击跳转到对应内容的详情页面。

内容的提问来源于stack exchange,提问作者Shubham Kumar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 02:28:46