update
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user