ソースを参照

播放页手势上滑 切歌
蓝牙设备断开暂停播放 设置可以增加了控制开关

onecold 6 ヶ月 前
コミット
f52f03ef78

+ 33 - 0
entry/src/main/ets/pages/SettingPage.ets

@@ -53,9 +53,11 @@ export struct SettingPage {
   static readonly WEBDAV_UPLOAD_AUTO_CLEAR: string = 'webdavUploadAutoClear';
   static readonly WEBDAV_UPLOAD_ALLOW_MOBILE: string = 'webdavUploadAllowMobile';
   static readonly WEBDAV_UPLOAD_RETRY_COUNT: string = 'webdavUploadRetryCount';
+  static readonly BLUETOOTH_DISCONNECT_PAUSE: string = 'bluetoothDisconnectPause';
   @State fastForwardSeconds: string = '10'
   @State isShowBackFast: boolean = true//快进快退按钮
   @State preloadNextSong: boolean = true // 提前缓存下一首
+  @State bluetoothDisconnectPause: boolean = false // 蓝牙设备断开暂停
   @State isClearingCache: boolean = false
   @Consume isShowDrawer: boolean;
   @Consume offsetX: number;
@@ -308,6 +310,7 @@ export struct SettingPage {
     this.isShowBackFast  = PreferencesUtil.getBooleanSync('isShowBackFast', false)
     this.fastForwardSeconds  = PreferencesUtil.getStringSync('fastForwardSeconds', '10')
     this.preloadNextSong = PreferencesUtil.getBooleanSync('preload_next_song', true)
+    this.bluetoothDisconnectPause = PreferencesUtil.getBooleanSync(SettingPage.BLUETOOTH_DISCONNECT_PAUSE, false)
     this.isCopyFileToDownLoad = PreferencesUtil.getBooleanSync(SettingPage.IS_COPYFILE_TO_DOWNLOAD, false)
     this.isNoJumpToHome = PreferencesUtil.getBooleanSync('isNoJumpToHome', true)
     this.webdavUploadDuplicateAction = PreferencesUtil.getStringSync(SettingPage.WEBDAV_UPLOAD_DUPLICATE_ACTION, 'skip')
@@ -1629,6 +1632,36 @@ export struct SettingPage {
             .clickEffect({ level: ClickEffectLevel.HEAVY })
             Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
 
+            // 蓝牙设备断开暂停
+            Row() {
+              SymbolGlyph($r('sys.symbol.bluetooth'))
+                .fontSize(20)
+                .fontColor([this.themeColor])
+                .alignSelf(ItemAlign.Center)
+                .margin({ left: 15 })
+              Text('蓝牙设备断开暂停播放')
+                .margin({ left: 8 })
+                .fontSize(15)
+                .fontColor(Color.Gray)
+                .fontWeight(480)
+                .layoutWeight(1)
+              Toggle({ type: ToggleType.Switch, isOn: this.bluetoothDisconnectPause })
+                .selectedColor(this.themeColor)
+                .switchPointColor(Color.White)
+                .margin({ right: 18 })
+                .onChange((checked: boolean) => {
+                  this.bluetoothDisconnectPause = checked;
+                  PreferencesUtil.put(SettingPage.BLUETOOTH_DISCONNECT_PAUSE, this.bluetoothDisconnectPause)
+                  this.sendChangeEvent()
+                  ToastUtil.showToast(checked ? '已开启蓝牙断开暂停' : '已关闭蓝牙断开暂停')
+                })
+                .width(50)
+                .height(30);
+            }
+            .height(55)
+            .clickEffect({ level: ClickEffectLevel.HEAVY })
+            Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
+
             // 均衡器设置入口
             Button({ type: ButtonType.Normal, stateEffect: true }) {
               Row() {

+ 63 - 40
entry/src/main/ets/view/LocalMusic.ets

@@ -343,6 +343,7 @@ export enum SortMode {
 @Preview
 @Component
 export struct LocalMusic {
+  @State bluetoothDisconnectPause: boolean = false // 蓝牙设备断开暂停
   @State showFindLocation: boolean = true
   @StorageProp("EnablePointLight") enablePointLight: boolean = true
   @State showSimple: boolean = true//开启沉浸模式
@@ -1039,7 +1040,7 @@ export struct LocalMusic {
       console.info(`onecold device descriptor size : ${deviceChanged.deviceDescriptors.length}`);
       console.info(`onecold device change descriptor : ${deviceChanged.deviceDescriptors[0].deviceRole}`);  // 设备角色。
       console.info(`onecold device change descriptor : ${deviceChanged.deviceDescriptors[0].deviceType}`);
-      if(deviceChanged.type==1&&deviceChanged.deviceDescriptors[0].deviceRole==2&&
+      if(this.bluetoothDisconnectPause&&deviceChanged.type==1&&deviceChanged.deviceDescriptors[0].deviceRole==2&&
         (deviceChanged.deviceDescriptors[0].deviceType==8)){
         console.info('heanup onecold 蓝牙音响断开, 暂停播放')
         this.pause();
@@ -1206,6 +1207,7 @@ export struct LocalMusic {
     context.getApplicationContext().setColorMode(colorMode)
   }
   initSetting() {
+    this.bluetoothDisconnectPause = PreferencesUtil.getBooleanSync(SettingPage.BLUETOOTH_DISCONNECT_PAUSE, false)
     this.isShowSpectrum  = PreferencesUtil.getBooleanSync('isShowSpectrum', false)
     this.spectrumModeIndex = PreferencesUtil.getNumberSync('spectrumModeIndex', 0)
     this.enablePointLight = PreferencesUtil.getBooleanSync('enablePointLight', true)
@@ -9650,52 +9652,73 @@ export struct LocalMusic {
       PanGesture(this.panOption)
         .onActionUpdate((event?: GestureEvent) => {
           if (event) {
-            // 只允许向下滑动,向上滑动时限制为0
-            this.translateY = Math.max(0, event.offsetY);
+            // 判断滑动方向
+            const offsetY = event.offsetY ?? 0;
+            const isSwipeUp = offsetY < 0;
 
-            this.getUIContext().animateTo({
-              duration: 500,
-              curve: Curve.Sharp
-            }, () => {
-              this.scaleValueImage = Math.min(1, Math.max(0.38, 1 - event.offsetY / 500));
-              console.info('onecold scaleValueImage:', this.scaleValueImage)
+            if (isSwipeUp) {
+              // 向上滑动:不应用位移动画,保持 translateY = 0
+              this.translateY = 0;
+            } else {
+              // 向下滑动:应用位移动画
+              this.translateY = offsetY;
 
-              this.scaleValueText =Math.min(1, Math.max(0.6, 1 - event.offsetY / 700));
-            })
+              // 向下滑动时的缩放效果
+              this.getUIContext().animateTo({
+                duration: 500,
+                curve: Curve.Sharp
+              }, () => {
+                this.scaleValueImage = Math.min(1, Math.max(0.38, 1 - this.translateY / 500));
+                console.info('onecold scaleValueImage:', this.scaleValueImage)
+                this.scaleValueText = Math.min(1, Math.max(0.6, 1 - this.translateY / 700));
+              })
+            }
           }
         })
         .onActionEnd((event?: GestureEvent) => {
-          // 使用更低的阈值和滑动速度判断
-          const minDistance = 300; // 最小滑动距离 100vp
+          // 判断滑动方向
+          const offsetY = event?.offsetY ?? 0;
+          const isSwipeUp = offsetY < 0;
+          const minDistance = 300; // 最小滑动距离
           const minVelocity = 500; // 最小滑动速度
+          const velocity = event?.velocityY ?? 0;
 
-          // 获取滑动速度(如果可用)
-          const velocity = event?.velocityY || 0;
-
-          // 判断是否应该关闭:距离足够 或者 速度足够快
-          const shouldClose = this.translateY > minDistance || velocity > minVelocity;
-
-          if (shouldClose) {
-            // 添加关闭动画
-            this.getUIContext().animateTo({
-              duration: 600,
-              curve: Curve.Friction
-            }, () => {
-              this.isShowPlay = false;
-              this.scaleValueImage = 1
-              this.scaleValueText = 1
-              this.translateY = 0;
-            })
+          if (isSwipeUp) {
+            // 向上滑动:切换下一首
+            const shouldSwitch = Math.abs(offsetY) > minDistance || Math.abs(velocity) > minVelocity;
+
+            if (shouldSwitch) {
+              // 直接切换下一首,无需动画(因为界面没有移动)
+              this.playNext().catch(() => {
+                Logger.error('heanup MusicPlayBuilder', '向上滑动切换下一首失败');
+              });
+            }
           } else {
-            // 回弹动画
-            this.getUIContext().animateTo({
-              duration: 600,
-              curve: Curve.Friction
-            }, () => {
-              this.scaleValueImage = 1
-              this.scaleValueText = 1
-              this.translateY = 0;
-            })
+            // 向下滑动:关闭播放页
+            const shouldClose = this.translateY > minDistance || velocity > minVelocity;
+
+            if (shouldClose) {
+              // 添加关闭动画
+              this.getUIContext().animateTo({
+                duration: 600,
+                curve: Curve.Friction
+              }, () => {
+                this.isShowPlay = false;
+                this.scaleValueImage = 1
+                this.scaleValueText = 1
+                this.translateY = 0;
+              })
+            } else {
+              // 回弹动画
+              this.getUIContext().animateTo({
+                duration: 600,
+                curve: Curve.Friction
+              }, () => {
+                this.scaleValueImage = 1
+                this.scaleValueText = 1
+                this.translateY = 0;
+              })
+            }
           }
         })
     )
@@ -15357,7 +15380,7 @@ export struct LocalMusic {
       isVisible: this.currentSwiperIndex === 0,
       isPlaying: this.CONTROL_PlayStatus === PlayStatus.PLAY
     })
-      .width( '84%')
+      .width( '83%')
       .height(this.isCoverOpacity() ? 80 : 100)
       .margin({bottom: 3 })
       .clip(true)

+ 4 - 5
entry/src/main/ets/view/spectrum/BarSpectrumRenderer.ets

@@ -14,17 +14,16 @@ export class BarSpectrumRenderer implements SpectrumRenderer {
     if (originalBandCount === 0) return
 
     // 根据宽度动态计算最佳柱子数量和尺寸
-    const minBarWidth: number = 3 // 最小柱子宽度
-    const maxBarWidth: number = 8 // 最大柱子宽度
+    const targetBarWidth: number = 2.5 // 目标柱子宽度
     const gap: number = 1.5 // 柱子之间的间隙
 
     // 计算在这个宽度下能容纳多少个柱子
-    let optimalBarCount: number = Math.floor(width / (minBarWidth + gap))
+    let optimalBarCount: number = Math.floor(width / (targetBarWidth + gap))
     optimalBarCount = Math.min(optimalBarCount, originalBandCount) // 不超过原始频段数
-    optimalBarCount = Math.max(optimalBarCount, 8) // 至少8个柱子
+    optimalBarCount = Math.max(optimalBarCount, 16) // 至少16个柱子
 
     // 根据优化后的柱子数量计算实际柱子宽度
-    const actualBarWidth: number = Math.min(maxBarWidth, (width - gap * (optimalBarCount + 1)) / optimalBarCount)
+    const actualBarWidth: number = (width - gap * (optimalBarCount + 1)) / optimalBarCount
 
     // 重采样 bands 数据以匹配 optimalBarCount
     const resampledBands: number[] = []

+ 1 - 1
entry/src/main/ets/view/spectrum/SpectrumView.ets

@@ -14,7 +14,7 @@ import { normalizeHexColor } from './SpectrumRenderer'
 import Logger from '../../common/util/Logger'
 
 const TAG: string = 'heanup-SpectrumView'
-const BAND_COUNT: number = 48 // 增加频段数量,从32增加到48
+const BAND_COUNT: number = 48 // 频段数量
 const PREFERENCE_SELECTED_EFFECT: string = 'selectedSpectrumEffectId'
 
 @Component