Files
18xchat/assets/Scripts/chat18x/ui/components/DialogBubble.ts
T
xionglijia 24c2a946a3 fix
设置页面资源
2025-09-10 18:12:26 +08:00

114 lines
3.1 KiB
TypeScript

import {
_decorator,
Component,
Label,
Node,
Overflow,
Size,
UITransform,
view,
} from "cc";
import Tools from "../../utils/tools";
const { ccclass, property } = _decorator;
@ccclass("DialogBubble")
export class DialogBubble extends Component {
@property(UITransform)
bg: UITransform = null;
@property(Label)
content: Label = null;
@property(UITransform)
contentT: UITransform = null;
fixMaxWidth: number;
private loadingAnimationId: number = null;
init(maxWidth?: number) {
// 如果没有提供maxWidth,使用屏幕宽度的80%
if (maxWidth === undefined) {
this.fixMaxWidth = view.getVisibleSize().width * 0.8;
} else {
this.fixMaxWidth = maxWidth;
}
}
updateBubbleContent(
str: string,
callback?: (actualHeight: number) => void,
isLoading: boolean = false
) {
// 停止之前的加载动画
this.stopLoadingAnimation();
this.content.overflow = Overflow.NONE;
// 如果是加载状态,使用固定的"..."
if (isLoading && str === "...") {
this.content.string = "...";
// 设置固定尺寸用于加载显示
const contentWidth = 60;
this.contentT.setContentSize(new Size(contentWidth, 40));
this.bg.setContentSize(new Size(contentWidth + 30, 50));
if (callback) {
callback(40); // 返回固定高度
}
return;
}
// 设置文本内容
this.content.string = str;
// 计算最大宽度(估算)
const lines = str.split("\n");
let maxWidth = 0;
for (const line of lines) {
let lineWidth = 0;
if (Tools.IsChinese(line)) {
lineWidth = 30 * line.length;
} else {
lineWidth = 18 * line.length;
}
maxWidth = Math.max(maxWidth, lineWidth);
}
if (maxWidth > this.fixMaxWidth)
this.content.overflow = Overflow.RESIZE_HEIGHT;
// 限制最大宽度
const contentWidth = Math.min(maxWidth, this.fixMaxWidth);
// 设置内容区域宽度,让Label自动计算高度
this.contentT.setContentSize(new Size(contentWidth, 0));
this.bg.setContentSize(new Size(contentWidth + 37, 0));
// 强制更新Label的渲染数据以获取正确的高度
this.content.updateRenderData(true);
// 等待一帧后获取Label的实际高度
this.scheduleOnce(() => {
const actualSize =
this.content.node.getComponent(UITransform).contentSize;
// 更新内容区域的实际大小
//this.contentT.setContentSize(new Size(contentWidth, actualHeight));
// 根据内容大小调整背景大小,添加适当的内边距
//const bgHeight = actualHeight + 17;
this.bg.setContentSize(new Size(actualSize.x + 40, actualSize.y + 30));
// 回调通知实际高度
if (callback) {
callback(actualSize.y);
}
}, 0);
// 返回预估的背景高度(用于同步计算)
const estimatedHeight = Math.max(lines.length * 35 + 20, 60); // 最小高度60
return estimatedHeight;
}
private stopLoadingAnimation() {
// 预留方法,当前实现中不需要动画,但保留接口以备将来使用
}
}