import { WidgetController } from '../../common/widget/WidgetController'; /** * 大尺寸播放器卡片 (4x3) * 显示专辑封面、完整信息和扩展控制 * 需求: 5.3, 2.3, 2.4 */ @Entry @Component struct PlayerWidgetLarge { @LocalStorageProp('isPlaying') isPlaying: boolean = false; @LocalStorageProp('songTitle') songTitle: string = '暂无播放'; @LocalStorageProp('songArtist') songArtist: string = '未知艺术家'; @LocalStorageProp('songAlbum') songAlbum: string = '未知专辑'; @LocalStorageProp('coverImage') coverImage: string = ''; @LocalStorageProp('currentTime') currentTime: string = '00:00'; @LocalStorageProp('totalTime') totalTime: string = '00:00'; @LocalStorageProp('progressPercentage') progressPercentage: number = 0; @LocalStorageProp('hasNext') hasNext: boolean = false; @LocalStorageProp('hasPrevious') hasPrevious: boolean = false; @LocalStorageProp('showProgress') showProgress: boolean = true; @LocalStorageProp('showCover') showCover: boolean = true; @LocalStorageProp('isLoading') isLoading: boolean = false; /** * 获取播放按钮图标 */ private getPlayButtonIcon(): Resource { if (this.isLoading) { return $r('app.media.icon_load'); } return this.isPlaying ? $r('app.media.hm_pause') : $r('app.media.hm_play'); } /** * 格式化显示文本 */ private getDisplayText(text: string, defaultText: string): string { return (!text || text.trim() === '') ? defaultText : text; } /** * 获取文本颜色 */ private getTextColor(text: string, defaultText: string, normalColor: string): string { return text === defaultText ? '#99000000' : normalColor; } /** * 获取专辑封面图片 */ private getCoverImage(): Resource | string { if (this.coverImage && this.coverImage.trim() !== '' && this.coverImage !== 'undefined') { return this.coverImage; } return $r('app.media.bg_music'); } build() { Column() { // 顶部信息区域 Row() { // 专辑封面 - 更大更圆润 Stack() { Image(this.getCoverImage()) .width(72) .height(72) .borderRadius(16) .objectFit(ImageFit.Cover) // 播放状态指示器 - 简化版本 if (this.isPlaying) { Text('♪') .fontSize(12) .fontColor('#FFFFFF') .padding(4) .backgroundColor('#FF6B6B') .borderRadius(6) .position({ x: 4, y: 4 }) } else { Text('⏸') .fontSize(12) .fontColor('#FFFFFF') .padding(4) .backgroundColor('#666666') .borderRadius(6) .position({ x: 4, y: 4 }) } } .margin({ right: 16 }) .stateStyles({ pressed: { .opacity(0.7) }, normal: { .opacity(1.0) } }) .onClick(() => { console.info('Heanup PlayerWidgetLarge: Cover image clicked'); postCardAction(this, { 'action': 'router', 'abilityName': 'EntryAbility' }); }) // 歌曲信息 - 更现代的排版 Column() { // 歌曲标题 - 更大更醒目 Text(this.getDisplayText(this.songTitle, '暂无播放')) .fontSize(18) .fontColor(this.getTextColor(this.songTitle, '暂无播放', '#1A1A1A')) .fontWeight(FontWeight.Bold) .maxLines(2) .textOverflow({ overflow: TextOverflow.Ellipsis }) .width('100%') .textAlign(TextAlign.Start) .lineHeight(24) // 艺术家信息 - 更柔和的颜色 Text(this.getDisplayText(this.songArtist, '未知艺术家')) .fontSize(14) .fontColor('#666666') .fontWeight(FontWeight.Medium) .maxLines(1) .textOverflow({ overflow: TextOverflow.Ellipsis }) .width('100%') .textAlign(TextAlign.Start) .margin({ top: 4 }) // 专辑信息 - 更小更淡 Text(this.getDisplayText(this.songAlbum, '未知专辑')) .fontSize(12) .fontColor('#999999') .fontWeight(FontWeight.Normal) .maxLines(1) .textOverflow({ overflow: TextOverflow.Ellipsis }) .width('100%') .textAlign(TextAlign.Start) .margin({ top: 2 }) } .layoutWeight(1) .alignItems(HorizontalAlign.Start) .justifyContent(FlexAlign.Start) .stateStyles({ pressed: { .opacity(0.7) }, normal: { .opacity(1.0) } }) .onClick(() => { console.info('Heanup PlayerWidgetLarge: Song info area clicked'); postCardAction(this, { 'action': 'router', 'abilityName': 'EntryAbility' }); }) } .width('100%') .alignItems(VerticalAlign.Top) .margin({ bottom: 20 }) // 播放进度区域 - 重新设计 if (this.showProgress) { Column() { // 进度条 - 更粗更现代 Stack() { // 背景进度条 Row() .width('100%') .height(6) .backgroundColor('#F0F0F0') .borderRadius(3) // 当前进度 Row() .width(`${this.progressPercentage}%`) .height(6) .backgroundColor('#FF6B6B') // 使用纯色替代渐变 .borderRadius(3) } .width('100%') .stateStyles({ pressed: { .opacity(0.7) }, normal: { .opacity(1.0) } }) .onClick((event) => { if (!this.isLoading) { console.info('Heanup PlayerWidgetLarge: Progress bar clicked'); const width = Number(event.target.area.width); const percentage = width > 0 ? (event.x / width * 100) : 0; postCardAction(this, { 'action': 'message', 'params': { "func":"seek_to", 'percentage': percentage } }); } }) // 时间显示 - 更现代的样式 Row() { Text(this.currentTime) .fontSize(12) .fontColor('#666666') .fontWeight(FontWeight.Medium) Blank() Text(this.totalTime) .fontSize(12) .fontColor('#666666') .fontWeight(FontWeight.Medium) } .width('100%') .margin({ top: 8 }) } .width('100%') .margin({ bottom: 20 }) } // 播放控制区域 - 重新设计 Row() { // 上一首按钮 - 更现代的设计 Button() { Image($r('app.media.ic_previous')) .width(24) .height(24) .fillColor(this.hasPrevious ? '#333333' : '#CCCCCC') } .width(48) .height(48) .backgroundColor('#F8F8F8') .borderRadius(24) .enabled(!this.isLoading) .opacity(this.hasPrevious ? 1.0 : 0.6) .stateStyles({ pressed: { .opacity(0.7) .backgroundColor('#EEEEEE') }, normal: { .opacity(this.hasPrevious ? 1.0 : 0.6) .backgroundColor('#F8F8F8') } }) .onClick(() => { console.info(`Heanup PlayerWidgetLarge: Previous button clicked, hasPrevious=${this.hasPrevious}, isLoading=${this.isLoading}`); if (!this.isLoading) { console.info('Heanup PlayerWidgetLarge: Previous button action sent'); postCardAction(this, { 'action': 'message', 'params': { "func":"prev_song" } }); } else { console.info('Heanup PlayerWidgetLarge: Previous button disabled due to loading'); } }) Blank() // 播放/暂停按钮 - 更大更突出 Button() { Image(this.getPlayButtonIcon()) .width(32) .height(32) .fillColor('#FFFFFF') } .width(64) .height(64) .backgroundColor(this.isLoading ? '#CCCCCC' : '#FF6B6B') // 使用纯色替代渐变 .borderRadius(32) .enabled(!this.isLoading) .stateStyles({ pressed: { .opacity(0.8) .backgroundColor(this.isLoading ? '#AAAAAA' : '#FF5252') }, normal: { .opacity(1.0) .backgroundColor(this.isLoading ? '#CCCCCC' : '#FF6B6B') } }) .onClick(() => { if (!this.isLoading) { console.info('Heanup PlayerWidgetLarge: Play/Pause button clicked'); postCardAction(this, { 'action': 'message', 'params': { "func":"play_pause" } }); } }) Blank() // 下一首按钮 - 与上一首对称 Button() { Image($r('app.media.ic_next')) .width(24) .height(24) .fillColor(this.hasNext ? '#333333' : '#CCCCCC') } .width(48) .height(48) .backgroundColor('#F8F8F8') .borderRadius(24) .enabled(!this.isLoading && this.hasNext) // 确保按钮状态正确 .opacity(this.hasNext ? 1.0 : 0.6) .stateStyles({ pressed: { .opacity(0.7) .backgroundColor('#EEEEEE') }, normal: { .opacity(this.hasNext ? 1.0 : 0.6) .backgroundColor('#F8F8F8') } }) .onClick(() => { console.info(`Heanup PlayerWidgetLarge: Next button clicked, hasNext=${this.hasNext}, isLoading=${this.isLoading}`); if (!this.isLoading && this.hasNext) { console.info('Heanup PlayerWidgetLarge: Next button action sent'); postCardAction(this, { 'action': 'message', 'params': { "func":"next_song" } }); } else { console.info('Heanup PlayerWidgetLarge: Next button disabled due to loading or no next song'); } }) } .width('100%') .justifyContent(FlexAlign.SpaceBetween) .alignItems(VerticalAlign.Center) } .width('100%') .height('100%') .padding(20) .backgroundColor('#FFFFFF') .borderRadius(20) .alignItems(HorizontalAlign.Start) .justifyContent(FlexAlign.SpaceBetween) .shadow({ radius: 8, color: '#20000000', offsetX: 0, offsetY: 4 }) // 移除手势支持,form应用不支持复杂交互 } }