Jelajahi Sumber

歌曲统计增加下拉刷新功能

onecold 11 bulan lalu
induk
melakukan
36f2207734

+ 1 - 3
entry/src/main/ets/common/util/MediaTable.ets

@@ -656,14 +656,13 @@ export default class MediaTable {
 
   public countSongsByQualityOptimized(callback: (result: Record<AudioQuality, number>) => void): void {
     const predicates = new relationalStore.RdbPredicates(RdbUtils.MEDIA_TABLE.tableName);
-    predicates.in('md5Str',  [AudioQuality.LQ, AudioQuality.SQ, AudioQuality.HQ, AudioQuality.LOSSLESS, AudioQuality.HIRES, AudioQuality.HR]);
+    predicates.in('md5Str',  [AudioQuality.LQ, AudioQuality.SQ, AudioQuality.HQ, AudioQuality.HIRES, AudioQuality.HR]);
 
     this.accountTable.query(predicates,  (resultSet: relationalStore.ResultSet) => {
       const result: Record<AudioQuality, number> = {
         [AudioQuality.LQ]: 0,
         [AudioQuality.SQ]: 0,
         [AudioQuality.HQ]: 0,
-        [AudioQuality.LOSSLESS]: 0,
         [AudioQuality.HIRES]: 0 , // 只保留HR,HIRES的统计将合并到这里
         [AudioQuality.HR]: 0  // 只保留HR,HIRES的统计将合并到这里
       };
@@ -675,7 +674,6 @@ export default class MediaTable {
           if (quality === AudioQuality.LQ ||
             quality === AudioQuality.SQ ||
             quality === AudioQuality.HQ ||
-            quality === AudioQuality.LOSSLESS ||
             quality === AudioQuality.HIRES ||  // HIRES的统计将被合并到HR
             quality === AudioQuality.HR) {
 

+ 4 - 8
entry/src/main/ets/common/util/Utility.ets

@@ -1914,9 +1914,8 @@ function formatBitrateToKbps(bitRate: string, decimalPlaces: number = 0): string
 // 定义音质等级
 export enum AudioQuality {
   LQ = "LQ",             // 低音质
-  SQ = "SQ",             // 标准音质
   HQ = "HQ",             // 高音质
-  LOSSLESS = "Lossless", // 无损
+  SQ = "SQ",             // 无损
   HIRES = "Hi-Res",      // 高解析度
   HR = "HR"       // 高解析度
 }
@@ -1954,11 +1953,11 @@ function determineAudioQuality(
   if (isLossless) {
     // Hi-Res标准:采样率≥96kHz且位深≥24bit
     if (sampleRate >= 48000 ) {
-      return AudioQuality.HR;
+      return AudioQuality.HIRES;
     }
     // CD级无损标准:采样率≥44.1kHz且位深≥16bit
     if (sampleRate >= 44100) {
-      return AudioQuality.LOSSLESS;
+      return AudioQuality.SQ;
     }
   }
 
@@ -1967,10 +1966,7 @@ function determineAudioQuality(
   if (bitrate >= 256000 && sampleRate >= 44100) {
     return AudioQuality.HQ;
   }
-  // 标准音质:比特率≥128kbps且采样率≥22.05kHz
-  else if (bitrate >= 128000 && sampleRate >= 22050) {
-    return AudioQuality.SQ;
-  }
+
   // 其余情况为低音质
   else {
     return AudioQuality.LQ;

+ 92 - 49
entry/src/main/ets/pages/ChartsCount.ets

@@ -11,6 +11,7 @@ import { util } from '@kit.ArkTS';
 import { AudioQuality, FFMpegTags } from '../common/util/Utility';
 import MediaTable from '../common/util/MediaTable';
 import { McPieChart, Options } from '@mcui/mccharts'
+import { ComponentContent } from '@kit.ArkUI';
 
 // 批量编辑标签
 @Component
@@ -37,6 +38,10 @@ export struct ChartsCount {
     ConfigurationConstant.ColorMode.COLOR_MODE_LIGHT;
   @StorageProp('themeColor') themeColor: string = CommonConstants.DEFAULT_THEME_COLOR;
   context =  this.getUIContext().getHostContext() as common.UIAbilityContext
+  private contentNode?: ComponentContent<Object> = undefined;
+  @State isRefreshing: boolean = false;
+  @State ratio: number = 1;
+  @State maxRefreshingHeight: number = 100.0;
 
   private table: MediaTable = new MediaTable(this.context)
   @State defOption: Options = new Options({
@@ -83,13 +88,40 @@ export struct ChartsCount {
   }
 
   async aboutToAppear() {
+    let uiContext = this.getUIContext();
+    this.contentNode = new ComponentContent(uiContext, wrapBuilder(customRefreshingContent));
     this.centerChart()
+
+
+  }
+
+  async centerChart(){
+    this.mediaKuCount = PreferencesUtil.getNumberSync('mediaKuCount', 0)
+    this.artistCount = PreferencesUtil.getNumberSync('artistCount', 0)
+    this.albumCount = PreferencesUtil.getNumberSync('albumCount', 0)
+    setTimeout(() => {
+      // 使用Option实例对象的setVal方法来实现,修改什么属性就传什么
+      this.defOption.setVal({
+        animation:true,
+        series: [
+          {
+            data:[
+              {value:this.mediaKuCount, name:'媒体库'},
+              {value:this.artistCount, name:'艺术家'},
+              {value:this.albumCount, name:'专辑'},
+            ]
+          }
+        ]
+      })
+    }, 1000)
+
+
     await new Promise<void>((resolve, reject) => {
       this.table.getRdbStore(this.context,  (err:Error) => {
         err ? reject(err) : resolve();
       });
     });
-    this.table.queryByPlayCountDesc(0, async (result: VideoItem[]) => {
+    this.table.queryByPlayCountDesc(1000, async (result: VideoItem[]) => {
       this.selectedFiles = result
       // 确保 selectedFiles 有默认值后再初始化 dataSource
       if (this.selectedFiles && this.selectedFiles.length > 0) {
@@ -106,7 +138,6 @@ export struct ChartsCount {
       this.hqCount = result.HQ
       this.hrCount = result.HR
       this.sqCount = result.SQ
-      this.losslessCount = result.Lossless
       setTimeout(() => {
         // 使用Option实例对象的setVal方法来实现,修改什么属性就传什么
         this.HrOption.setVal({
@@ -115,9 +146,8 @@ export struct ChartsCount {
             {
               data:[
                 {value:this.lqCount, name:'LQ'},
-                {value:this.sqCount, name:'SQ'},
                 {value:this.hqCount, name:'HQ'},
-                {value:this.losslessCount, name:'Lossless'},
+                {value:this.sqCount, name:'SQ'},
                 {value:this.hrCount, name:'Hi-Res'},
               ]
             }
@@ -129,27 +159,6 @@ export struct ChartsCount {
 
   }
 
-  centerChart(){
-    this.mediaKuCount = PreferencesUtil.getNumberSync('mediaKuCount', 0)
-    this.artistCount = PreferencesUtil.getNumberSync('artistCount', 0)
-    this.albumCount = PreferencesUtil.getNumberSync('albumCount', 0)
-    setTimeout(() => {
-      // 使用Option实例对象的setVal方法来实现,修改什么属性就传什么
-      this.defOption.setVal({
-        animation:true,
-        series: [
-          {
-            data:[
-              {value:this.mediaKuCount, name:'媒体库'},
-              {value:this.artistCount, name:'艺术家'},
-              {value:this.albumCount, name:'专辑'},
-            ]
-          }
-        ]
-      })
-    }, 2000)
-  }
-
 
 
   build() {
@@ -186,33 +195,52 @@ export struct ChartsCount {
   @Builder
   listView() {
     Column(){
-      List({ scroller: this.listScroller }) {
-        ListItemGroup({ header: this.centerCharts() }) {
-          LazyForEach(this.dataSource, (item: VideoItem, index: number) => {
-            ListItem() {
-              Column() {
-                this.MusicItem(item, index)
+      Refresh({ refreshing: $$this.isRefreshing, refreshingContent: this.contentNode }) {
+        List({ scroller: this.listScroller }) {
+          ListItemGroup({ header: this.centerCharts() }) {
+            LazyForEach(this.dataSource, (item: VideoItem, index: number) => {
+              ListItem() {
+                Column() {
+                  this.MusicItem(item, index)
+                }
               }
-            }
-            .borderRadius(14)
-            .backgroundColor($r('app.color.start_window_background'))
-            .margin({top:7,bottom:7})
-            .transition(TransitionEffect.asymmetric(
-              TransitionEffect.scale({ x: 1.2, y: 1.2 }).animation({ duration: 500 }),
-              TransitionEffect.scale({ x: 0, y: 0 })
-            ))
-            .clickEffect({ level: ClickEffectLevel.LIGHT })
-          }, (item: VideoItem) => item.filePath)
-        }
+              .borderRadius(14)
+              .backgroundColor($r('app.color.start_window_background'))
+              .margin({top:7,bottom:7})
+              .transition(TransitionEffect.asymmetric(
+                TransitionEffect.scale({ x: 1.2, y: 1.2 }).animation({ duration: 500 }),
+                TransitionEffect.scale({ x: 0, y: 0 })
+              ))
+              .clickEffect({ level: ClickEffectLevel.LIGHT })
+            }, (item: VideoItem) => item.filePath)
+          }
 
+        }
+        .cachedCount(2)
+        // .layoutWeight(1)
+        // .height('100%')
+        .transition(TransitionEffect.asymmetric(
+          TransitionEffect.scale({ x: 1.2, y: 1.2 }).animation({ duration: 500 }),
+          TransitionEffect.scale({ x: 0, y: 0 })
+        ))
       }
-      .cachedCount(2)
-      // .layoutWeight(1)
-      // .height('100%')
-      .transition(TransitionEffect.asymmetric(
-        TransitionEffect.scale({ x: 1.2, y: 1.2 }).animation({ duration: 500 }),
-        TransitionEffect.scale({ x: 0, y: 0 })
-      ))
+      .pullDownRatio(this.ratio)
+      .pullToRefresh(true)
+      .refreshOffset(64)
+      .onOffsetChange((offset: number) => {
+        // 越接近最大距离,下拉跟手系数越小。
+        this.ratio = 1 - Math.pow((offset / this.maxRefreshingHeight), 3);
+      })
+      .onStateChange((refreshStatus: RefreshStatus) => {
+        console.info('onecold Refresh onStatueChange state is ' + refreshStatus);
+      })
+      .onRefreshing(async () => {
+        await this.centerChart()
+        setTimeout(() => {
+          this.isRefreshing = false;
+        }, 2000)
+        console.log('onRefreshing test');
+      })
 
     }
     .borderRadius(20)
@@ -343,4 +371,19 @@ export struct ChartsCount {
   }
 }
 
+@Builder
+function customRefreshingContent() {
+  Stack() {
+    Row() {
+      LoadingProgress().height(32)
+    }
+    .alignItems(VerticalAlign.Center)
+  }
+  .align(Alignment.Center)
+  .clip(true)
+  // 设置最小高度约束保证自定义组件高度随刷新区域高度变化时自定义组件高度不会低于minHeight。
+  .constraintSize({ minHeight: 32 })
+  .width("100%")
+}
+