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

如何在Flutter中实现Android原生风格的Bubble Conversation?

在Flutter中实现Android官方对话气泡(Bubble)方案

目前Flutter框架本身没有提供直接调用Android系统气泡通知的API,要实现Android官方文档定义的对话气泡效果,必须通过**平台通道(MethodChannel)**调用原生Android代码完成,以下是具体实现步骤:

一、Android端配置与代码实现

1. 配置AndroidManifest.xml

先在清单文件中声明气泡相关权限,并设置用于显示对话的Activity属性:

<!-- 声明通知权限(Android 13+必需) -->
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />

<!-- 对话页面Activity配置 -->
<activity
    android:name=".ConversationActivity"
    android:allowEmbedded="true"
    android:documentLaunchMode="always"
    android:resizeableActivity="true">
</activity>

2. 编写原生气泡通知工具类

创建NotificationHelper类,负责构建并发送气泡通知(以Kotlin为例):

import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.os.Build
import androidx.core.app.NotificationCompat

class NotificationHelper(private val context: Context) {
    private val notificationManager = context.getSystemService(NotificationManager::class.java)

    init {
        // 创建通知渠道(Android O及以上必需)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannel(
                "BUBBLE_CHANNEL",
                "对话气泡频道",
                NotificationManager.IMPORTANCE_HIGH
            ).apply {
                description = "用于显示对话气泡通知"
                setAllowBubbles(true)
            }
            notificationManager.createNotificationChannel(channel)
        }
    }

    fun showBubbleNotification(conversationId: String, title: String, content: String) {
        // 跳转对话页面的Intent
        val intent = Intent(context, ConversationActivity::class.java).apply {
            putExtra("CONVERSATION_ID", conversationId)
            flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
        }
        val pendingIntent = PendingIntent.getActivity(
            context,
            0,
            intent,
            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
        )

        // 构建气泡元数据
        val bubbleMetadata = NotificationCompat.BubbleMetadata.Builder(
            pendingIntent,
            NotificationCompat.BubbleMetadata.PERSISTENT_ACTION_NONE
        ).apply {
            setDesiredHeight(600) // 设置气泡高度
            setAutoExpandBubble(true)
            setSuppressNotification(true) // 隐藏通知栏的普通通知
        }.build()

        // 构建并发送通知
        val notification = NotificationCompat.Builder(context, "BUBBLE_CHANNEL")
            .setSmallIcon(R.drawable.ic_notification)
            .setContentTitle(title)
            .setContentText(content)
            .setPriority(NotificationCompat.PRIORITY_HIGH)
            .setCategory(NotificationCompat.CATEGORY_MESSAGE)
            .setBubbleMetadata(bubbleMetadata)
            .build()

        notificationManager.notify(conversationId.hashCode(), notification)
    }
}

3. 实现对话Activity

ConversationActivity需要支持嵌入气泡并显示对话内容,示例代码:

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_conversation.*

class ConversationActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_conversation)

        val conversationId = intent.getStringExtra("CONVERSATION_ID")
        tv_conversation_title.text = "与用户$conversationId 的对话"
        // 此处可根据conversationId加载对应对话内容
    }
}

二、Flutter端调用原生方法

通过MethodChannel触发原生的气泡通知逻辑:

import 'package:flutter/services.dart';

class BubbleNotificationService {
  static const MethodChannel _channel = MethodChannel('bubble_notification');

  // 调用原生显示气泡通知
  static Future<void> showBubbleNotification({
    required String conversationId,
    required String title,
    required String content,
  }) async {
    try {
      await _channel.invokeMethod('showBubble', {
        'conversationId': conversationId,
        'title': title,
        'content': content,
      });
    } on PlatformException catch (e) {
      print('显示气泡失败: ${e.message}');
    }
  }
}

在MainActivity中注册MethodChannel(Kotlin):

import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel

class MainActivity : FlutterActivity() {
    private val CHANNEL = "bubble_notification"

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
            if (call.method == "showBubble") {
                val conversationId = call.argument<String>("conversationId")
                val title = call.argument<String>("title")
                val content = call.argument<String>("content")
                if (conversationId != null && title != null && content != null) {
                    NotificationHelper(this).showBubbleNotification(conversationId, title, content)
                    result.success(null)
                } else {
                    result.error("INVALID_ARGUMENTS", "参数不能为空", null)
                }
            } else {
                result.notImplemented()
            }
        }
    }
}

注意事项

  • 气泡功能仅支持Android 10(API 29)及以上系统
  • Android 13及以上需动态申请POST_NOTIFICATIONS权限
  • 部分厂商对气泡功能有自定义限制,需测试适配

内容的提问来源于stack exchange,提问作者Nguyễn Minh Khoa

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 02:45:54