This commit is contained in:
2025-08-13 12:55:27 +08:00
parent db0b040fd8
commit 53e2687546
4 changed files with 89 additions and 58 deletions
@@ -39,9 +39,22 @@ export class ChatContentsLayout extends Component {
}
this.bubbles = [];
this.updateDialogLayout(dialogs);
// 清理多余的缓存气泡,避免内存泄漏
this.cleanupExcessCachedBubbles();
}
private updateDialogLayout(dialogs: Dialog[]) {
let initPosY: number = BUTTOM_Y;
for (let i = dialogs.length - 1; i >= 0; i--) {
const dialog = dialogs[i]; //倒序
let pendingUpdates = 0;
const updateNextBubble = (index: number) => {
if (index < 0) {
return;
}
const dialog = dialogs[index];
let newBubble: DialogBubble = null;
// 尝试从缓存中获取合适的气泡
@@ -69,17 +82,25 @@ export class ChatContentsLayout extends Component {
}
newBubble.node.active = true;
let offset = newBubble.updateBubbleContent(dialog.content);
let pos = newBubble.node.position;
newBubble.node.position = new Vec3(pos.x, initPosY, pos.z);
initPosY += offset + 20;
pendingUpdates++;
newBubble.updateBubbleContent(dialog.content, (actualHeight: number) => {
initPosY += actualHeight + 20;
pendingUpdates--;
// 当当前气泡更新完成后,处理下一个
if (pendingUpdates === 0) {
updateNextBubble(index - 1);
}
});
this.bubbles.push(newBubble);
}
};
// 清理多余的缓存气泡,避免内存泄漏
this.cleanupExcessCachedBubbles();
// 从最后一个对话开始处理(倒序)
updateNextBubble(dialogs.length - 1);
}
private cleanupExcessCachedBubbles() {
@@ -11,47 +11,54 @@ export class DialogBubble extends Component {
@property(UITransform)
contentT: UITransform = null;
updateBubbleContent(str: string) {
const lines = str.split("\n");
let len = 0;
let index = 0;
for (let i = 0; i < lines.length; i++) {
const element = lines[i];
if (element.length > len) {
len = element.length;
index = i;
}
}
let finalLen = 0;
// for (let i = 0; i < lines[index].length; i++) {
// const element = lines[index][i];
// if ("\u4e00" <= element[i] && element[i] <= "\u9fff") {
// finalLen += 35;
// } else {
// finalLen += 18;
// }
// }
if (Tools.IsChinese(lines[index])) {
finalLen = 35 * lines[index].length;
} else {
finalLen = 21 * lines[index].length;
}
updateBubbleContent(str: string, callback?: (actualHeight: number) => void) {
// 设置文本内容
this.content.string = str;
this.contentT.setContentSize(
new Size(Math.min(finalLen, 950), this.contentT.contentSize.y)
);
this.content.updateRenderData();
this.bg.setContentSize(
new Size(
this.contentT.contentSize.x + 30,
this.contentT.contentSize.y + 20
)
);
// 计算最大宽度(估算)
const lines = str.split("\n");
let maxWidth = 0;
return this.bg.contentSize.y;
for (const line of lines) {
let lineWidth = 0;
if (Tools.IsChinese(line)) {
lineWidth = 35 * line.length;
} else {
lineWidth = 21 * line.length;
}
maxWidth = Math.max(maxWidth, lineWidth);
}
// 限制最大宽度
const contentWidth = Math.min(maxWidth, 950);
// 设置内容区域宽度,让Label自动计算高度
this.contentT.setContentSize(new Size(contentWidth, 0));
this.bg.setContentSize(new Size(contentWidth + 20, 0));
// 强制更新Label的渲染数据以获取正确的高度
this.content.updateRenderData(true);
// 等待一帧后获取Label的实际高度
this.scheduleOnce(() => {
const actualHeight =
this.content.node.getComponent(UITransform).contentSize.height;
// 更新内容区域的实际大小
this.contentT.setContentSize(new Size(contentWidth, actualHeight));
// 根据内容大小调整背景大小,添加适当的内边距
const bgHeight = actualHeight + 20;
this.bg.setContentSize(new Size(contentWidth + 50, bgHeight));
// 回调通知实际高度
if (callback) {
callback(bgHeight);
}
}, 0);
// 返回预估的背景高度(用于同步计算)
const estimatedHeight = Math.max(lines.length * 35 + 20, 60); // 最小高度60
return estimatedHeight;
}
}
@@ -76,6 +76,7 @@ export class ChatPanel extends li_BaseView {
Utils.addInnerEL(InnerMsgCode.LanguageChange, this, this.onLanguageChangeCallback);
}
onDestroy(): void {
Utils.removeInnerEL(InnerMsgCode.Chat_DialogRefresh, this, this.onDialogUpdate);
Utils.removeInnerEL(InnerMsgCode.LanguageChange, this, this.onLanguageChangeCallback);
}
refresh(id: number) {
@@ -107,7 +108,9 @@ export class ChatPanel extends li_BaseView {
});
}
onDialogUpdate() {
this.layout.UpdateDialog(DialogManager.getInstance().getDialogs());
if (this.layout) {
this.layout.UpdateDialog(DialogManager.getInstance().getDialogs());
}
}
protected onEnable(): void {
if (!this.manager) this.manager = DialogManager.getInstance();
+9 -9
View File
@@ -2327,7 +2327,7 @@
},
"_contentSize": {
"__type__": "cc.Size",
"width": 35,
"width": 37.399993896484375,
"height": 44.352000000000004
},
"_anchorPoint": {
@@ -2366,8 +2366,8 @@
"_string": "慵",
"_horizontalAlign": 0,
"_verticalAlign": 1,
"_actualFontSize": 35,
"_fontSize": 35,
"_actualFontSize": 37.4,
"_fontSize": 37.4,
"_fontFamily": "NotoSans-Regular",
"_lineHeight": 35.2,
"_overflow": 3,
@@ -3002,7 +3002,7 @@
"_lpos": {
"__type__": "cc.Vec3",
"x": -20,
"y": 67.376,
"y": 32.176,
"z": 0
},
"_lrot": {
@@ -3042,8 +3042,8 @@
},
"_contentSize": {
"__type__": "cc.Size",
"width": 435.786523,
"height": 114.752
"width": 247.62884521484375,
"height": 44.352000000000004
},
"_anchorPoint": {
"__type__": "cc.Vec2",
@@ -3078,11 +3078,11 @@
"b": 5,
"a": 255
},
"_string": "asdasddsasdasdadasdasdasdasdasdasdasdadasdasdasdas",
"_string": "asdasddsasda",
"_horizontalAlign": 0,
"_verticalAlign": 1,
"_actualFontSize": 35,
"_fontSize": 35,
"_actualFontSize": 37.4,
"_fontSize": 37.4,
"_fontFamily": "NotoSans-Regular",
"_lineHeight": 35.2,
"_overflow": 3,