功能预览
TUILiveKit 直播弹幕为直播场景提供完整互动解决方案,能够增强直播的互动性和趣味性。通过本文档,您可快速实现直播间弹幕互动功能,并支持深度定制以满足业务需求。弹幕消息发送组件(BarrageInputView) | 弹幕消息展示组件(BarrageStreamView) |
![]() | ![]() |
组件构成
组件名称 | 具体内容 |
弹幕消息组件(BarrageStreamView) | 负责实时展示和管理弹幕消息流的组件,提供消息列表渲染、时间聚合、用户交互和响应式适配等完整的消息展示解决方案。 |
消息发送组件(BarrageInputView) | 提供富文本编辑和消息发送功能的输入组件,集成表情选择器、字符限制、状态管理和跨平台适配,为用户提供流畅的消息输入体验。 |
快速开始
步骤 1. 开通服务
步骤 2. 代码集成
步骤 3. 接入弹幕消息发送组件
在您的应用中接入弹幕消息发送组件,使主播/观众能够方便地发送弹幕消息。请参考示例代码创建
BarrageInputView 组件并添加到您的视图:// 1. 创建 BarrageInputView 对象BarrageInputView barrageInputView = new BarrageInputView(mContext);// 2. 初始化 BarrageInputView ,roomId为您当前进入的直播间房间idbarrageInputView.init("roomId");// 3. 将 BarrageInputView 对象添加到您的视图上yourBarrageInputContainerView.addView(barrageInputView);
说明:
1. 弹幕消息发送组件支持系统键盘和表情键盘切换。
2. 为尊重表情设计版权,
TUILiveKit 工程中不包含大表情元素切图,正式上线商用前请您替换为自己设计或拥有版权的其他表情包。下图所示默认的小黄脸表情包版权归腾讯云所有,可有偿授权使用,如果需要获得授权可 提交工单 联系我们。

步骤 4. 接入弹幕消息展示组件
在您的应用中接入弹幕消息展示组件,使主播/观众能够直观地看到已发送的弹幕消息列表。请参考示例代码创建
BarrageStreamView 组件并添加到视图:// 1. 创建 BarrageStreamView 对象BarrageStreamView barrageStreamView = new BarrageStreamView(mContext);// 2. 初始化 BarrageStreamView 对象,roomId为您当前进入的直播间房间id,ownerId 为当前房主的 userId,用来区分房主与观众的显示效果barrageStreamView.init(roomId, ownerId);// 3. 将 BarrageStreamView 对象添加到您的视图上yourBarrageContainerView.addView(barrageStreamView);
自定义组件
自定义弹幕消息样式
弹幕消息样式默认有两种:普通弹幕(样式为 0)和自定义消息样式。如果您需要更多样式,可以参考示例代码(示例为自定义弹幕等级)来实现自定义弹幕消息样式
效果示例:

代码示例:
// 1. 重写BarrageItemTypeDelegate ,根据 Barrage 的extInfo字段判断消息的类型,并返回对应的样式 ID。public static final int BARRAGE_TYPE_VIP = 1;public class YourViewTypeDelegate implements BarrageItemTypeDelegate {@Overridepublic int getItemType(int position, Barrage barrage) {if (barrage.extInfo != null && barrage.extInfo.containsKey("BARRAGE_TYPE_VIP")) {String viewTypeString = String.valueOf(barrage.extInfo.get("BARRAGE_TYPE_VIP"));if (String.valueOf(GIFT_VIEW_TYPE_1).equals(viewTypeString)) {return GIFT_VIEW_TYPE_1;}}return 0;}}// 2. 实现自定义样式的Adapter为新的样式(例如 BARRAGE_TYPE_VIP)实现一个BarrageItemAdapter,用于创建和绑定自定义的视图布局。public final class GiftBarrageAdapter implements BarrageItemAdapter {private final Context mContext;public GiftBarrageAdapter(Context context) {mContext = context;}@NonNull@Overridepublic RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent) {// 此处为自定义了等级的代码示例,您可以根据您的业务需求自定义实现LinearLayout ll = new LinearLayout(mContext);TextView levelTextView = new TextView(mContext);levelTextView.setTextSize(9);levelTextView.setGravity(Gravity.START);levelTextView.setPadding(ScreenUtil.dip2px(8), ScreenUtil.dip2px(2), ScreenUtil.dip2px(8), ScreenUtil.dip2px(2));levelTextView.setTypeface(null, Typeface.BOLD);levelTextView.setBackgroundResource(R.drawable.git_barrage_bg_msg_item);ll.addView(levelTextView);TextView mainTextView = new TextView(mContext);ll.addView(mainTextView);return new GiftViewHolder(ll);}@Overridepublic void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position, @NonNull Barrage barrage) {GiftViewHolder viewHolder = (GiftViewHolder) holder;viewHolder.bind(barrage);}private static class GiftViewHolder extends RecyclerView.ViewHolder {private final TextView levelTextView;private final TextView mainTextView;public GiftViewHolder(View itemView) {super(itemView);LinearLayout linearLayout = (LinearLayout) itemView;levelTextView = (TextView) linearLayout.getChildAt(0);mainTextView = (TextView) linearLayout.getChildAt(1);linearLayout.setPadding(0, ScreenUtil.dip2px(3), 0, ScreenUtil.dip2px(3));mainTextView.setTextColor(Color.WHITE);mainTextView.setTextSize(12);mainTextView.setTypeface(null, Typeface.BOLD);mainTextView.setGravity(Gravity.START | Gravity.CENTER_VERTICAL);mainTextView.setPadding(ScreenUtil.dip2px(5), ScreenUtil.dip2px(5),ScreenUtil.dip2px(5), ScreenUtil.dip2px(5));mainTextView.setBackgroundResource(R.drawable.git_barrage_bg_msg_item);}public void bind(Barrage barrage) {int userLevel = getUserLevel(barrage);LevelStyle levelStyle = getUserLevelStyle(userLevel);if (userLevel > 0 && !levelStyle.icon.isEmpty()) {levelTextView.setText(levelStyle.icon);levelTextView.setTextColor(levelStyle.primaryColor);levelTextView.setVisibility(View.VISIBLE);levelTextView.setShadowLayer(3.0f, 0.0f, 0.0f, levelStyle.glowColor);setLevelBackground(levelTextView, levelStyle);} else {levelTextView.setVisibility(View.GONE);}SpannableStringBuilder sb = new SpannableStringBuilder();String sender = barrage.getSender().getUserName();sender = TextUtils.isEmpty(sender) ? "" : sender;sb.append(sender);ForegroundColorSpan senderSpan = new ForegroundColorSpan(levelStyle.primaryColor);sb.setSpan(senderSpan, 0, sender.length(), SPAN_EXCLUSIVE_EXCLUSIVE);sb.append("Your barrage message");mainTextView.setText(sb);}private int getUserLevel(Barrage barrage) {try {String levelObj = barrage.getExtensionInfo().get(GiftConstants.USER_LEVEL);if (levelObj != null) {return Integer.parseInt(levelObj);}} catch (Exception ignored) {}return 0;}private LevelStyle getUserLevelStyle(int level) {if (level == 1) {return LEVEL_STYLES[1];} else {return LEVEL_STYLES[0];}}private void setLevelBackground(TextView textView, LevelStyle levelStyle) {try {android.graphics.drawable.GradientDrawable gradientDrawable =new android.graphics.drawable.GradientDrawable();gradientDrawable.setOrientation(android.graphics.drawable.GradientDrawable.Orientation.LEFT_RIGHT);gradientDrawable.setColors(new int[]{levelStyle.primaryColor, levelStyle.secondaryColor});gradientDrawable.setCornerRadius(ScreenUtil.dip2px(10));gradientDrawable.setStroke(ScreenUtil.dip2px(1), levelStyle.glowColor);textView.setBackground(gradientDrawable);} catch (Exception e) {textView.setBackgroundColor(levelStyle.primaryColor);}}private static final LevelStyle[] LEVEL_STYLES = {new LevelStyle(0xFF00D4FF, 0xFF0099CC, "💎普通", 0xFF4DFFFF), // 等级1 - 蓝色钻石渐变new LevelStyle(0xFFFF6B35, 0xFFFFD700, "👑VIP", 0xFFFFFF00) // 等级2 - 橙金皇冠渐变};private static class LevelStyle {final int primaryColor;final int secondaryColor;final String icon;final int glowColor;LevelStyle(int primaryColor, int secondaryColor, String icon, int glowColor) {this.primaryColor = primaryColor;this.secondaryColor = secondaryColor;this.icon = icon;this.glowColor = glowColor;}}}}// 3. 为您的弹幕消息展示组件 BarrageStreamView 设置自定义样式yourBarrageStreamView.setItemTypeDelegate(new YourViewTypeDelegate());yourBarrageStreamView.setItemAdapter(GIFT_VIEW_TYPE_1, new YourBarrageAdapter(mContext));
插入本地弹幕消息
在您的业务中,您可能需要在弹幕中插入自定义消息(例如礼物消息、直播间公告等),
BarrageStreamView 提供了插入自定义消息的能力,您可以参考如下代码创建自定义消息并显示到本地弹幕消息中(代码示例为在弹幕中插入一条礼物消息):// 1. 创建 Barrage 对象Barrage barrage = new Barrage();// 2. 初始化 Barrage 消息内容,您可以根据业务诉求,通过extInfo灵活的自定义您的消息barrage.content = "gift";barrage.user.userId = "sender.userId";barrage.user.userName = "sender.userName";barrage.user.avatarUrl = "sender.avatarUrl";barrage.extInfo.put("GIFT_VIEW_TYPE", "GIFT_VIEW_TYPE_1");barrage.extInfo.put("GIFT_NAME", "giftName");barrage.extInfo.put("GIFT_COUNT", "giftCount");barrage.extInfo.put("GIFT_ICON_URL", "imageUrl");barrage.extInfo.put("GIFT_RECEIVER_USERNAME"," receiver.userName");// 3. 将创建的弹幕消息插入本地弹幕展示组件中yourBarrageStreamView.insertBarrages(barrage);
常见问题
为什么我无法看到弹幕消息?
请检查以下几点:
确保您已经正确初始化了
BarrageInputView 和 BarrageStreamView,并且传递了正确的 roomId。检查网络连接是否正常。
如何在弹幕消息中区分房主和观众?
在初始化
BarrageStreamView 时,您需要传入 ownerId 参数。组件会根据 ownerId 自动识别房主发送的弹幕,并应用不同的样式。您也可以通过自定义弹幕样式,根据 Barrage 消息中的 user.userId 字段来判断是否为房主,并显示您想要的特定效果。

