文档中心>直播 SDK>UI 自定义>弹幕消息组件>聊天弹幕组件 (Android Java)

聊天弹幕组件 (Android Java)

最近更新时间:2025-11-21 14:15:34

我的收藏

功能预览

TUILiveKit 直播弹幕为直播场景提供完整互动解决方案,能够增强直播的互动性和趣味性。通过本文档,您可快速实现直播间弹幕互动功能,并支持深度定制以满足业务需求。
弹幕消息发送组件(BarrageInputView)
弹幕消息展示组件(BarrageStreamView)





组件构成

组件名称
具体内容
弹幕消息组件(BarrageStreamView)
负责实时展示和管理弹幕消息流的组件,提供消息列表渲染、时间聚合、用户交互和响应式适配等完整的消息展示解决方案。
消息发送组件(BarrageInputView)
提供富文本编辑和消息发送功能的输入组件,集成表情选择器、字符限制、状态管理和跨平台适配,为用户提供流畅的消息输入体验。

快速开始

步骤 1. 开通服务

参考 开通服务 文档开通「体验版」或「大规模直播版」套餐。

步骤 2. 代码集成

参考 准备工作 接入 TUILiveKit

步骤 3. 接入弹幕消息发送组件

在您的应用中接入弹幕消息发送组件,使主播/观众能够方便地发送弹幕消息。请参考示例代码创建 BarrageInputView 组件并添加到您的视图:
Java
// 1. 创建 BarrageInputView 对象
BarrageInputView barrageInputView = new BarrageInputView(mContext);

// 2. 初始化 BarrageInputView ,roomId为您当前进入的直播间房间id
barrageInputView.init("roomId");

// 3. 将 BarrageInputView 对象添加到您的视图上
yourBarrageInputContainerView.addView(barrageInputView);
说明:
1. 弹幕消息发送组件支持系统键盘表情键盘切换。
2. 为尊重表情设计版权,TUILiveKit 工程中不包含大表情元素切图,正式上线商用前请您替换为自己设计或拥有版权的其他表情包。下图所示默认的小黄脸表情包版权归腾讯云所有,可有偿授权使用,如果需要获得授权可 提交工单 联系我们。




步骤 4. 接入弹幕消息展示组件

在您的应用中接入弹幕消息展示组件,使主播/观众能够直观地看到已发送的弹幕消息列表。请参考示例代码创建 BarrageStreamView 组件并添加到视图:
Java
// 1. 创建 BarrageStreamView 对象
BarrageStreamView barrageStreamView = new BarrageStreamView(mContext);

// 2. 初始化 BarrageStreamView 对象,roomId为您当前进入的直播间房间id,ownerId 为当前房主的 userId,用来区分房主与观众的显示效果
barrageStreamView.init(roomId, ownerId);

// 3. 将 BarrageStreamView 对象添加到您的视图上
yourBarrageContainerView.addView(barrageStreamView);

自定义组件

自定义弹幕消息样式

弹幕消息样式默认有两种:普通弹幕(样式为 0)和自定义消息样式。如果您需要更多样式,可以参考示例代码(示例为自定义弹幕等级)来实现自定义弹幕消息样式
效果示例

代码示例
Java
// 1. 重写 BarrageItemTypeDelegate ,根据 Barrage 的 extInfo 字段判断消息的类型,并返回对应的样式 ID。
public static final int BARRAGE_TYPE_VIP = 1;
public class YourViewTypeDelegate implements BarrageItemTypeDelegate {
@Override
public 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
@Override
public 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);
}

@Override
public 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 提供了插入自定义消息的能力,您可以参考如下代码创建自定义消息并显示到本地弹幕消息中(代码示例为在弹幕中插入一条礼物消息):
Java
// 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);

常见问题

为什么我无法看到弹幕消息?

请检查以下几点:
确保您已经正确初始化了 BarrageInputViewBarrageStreamView,并且传递了正确的 roomId
检查网络连接是否正常。

如何在弹幕消息中区分房主和观众?

在初始化 BarrageStreamView 时,您需要传入 ownerId 参数。组件会根据 ownerId 自动识别房主发送的弹幕,并应用不同的样式。您也可以通过自定义弹幕样式,根据 Barrage 消息中的 user.userId 字段来判断是否为房主,并显示您想要的特定效果。