SettingPage.ets 45 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288
  1. import TitleBar from '../view/TitleBar'
  2. import { promptAction, router } from '@kit.ArkUI'
  3. import { CommonConstants } from '../common/constants/CommonConstants'
  4. import { AppUtil, DeviceUtil, DisplayUtil, FileUtil, MD5, PreferencesUtil, ToastUtil } from '@pura/harmony-utils'
  5. import { CustomContentDialog } from '@kit.ArkUI'
  6. import ConfigurationConstant from '@ohos.app.ability.ConfigurationConstant';
  7. import common from '@ohos.app.ability.common';
  8. import { photoAccessHelper } from '@kit.MediaLibraryKit'
  9. import { fileIo, fileUri } from '@kit.CoreFileKit'
  10. import { BusinessError, emitter } from '@kit.BasicServicesKit'
  11. import { BreakpointTypeEnum } from '../common/util/BreakpointSystem'
  12. import { resourceManager } from '@kit.LocalizationKit'
  13. // import {
  14. // IBestButton,
  15. // IBestColorPicker,
  16. // IBestField,
  17. // IBestIcon,
  18. // IBestPopup,
  19. // IBestRadio,
  20. // IBestRadioGroup
  21. // } from '@ibestservices/ibest-ui'
  22. import { Utility } from '../common/util/Utility'
  23. import { HSBColorPicker } from '@keke/color-picker'
  24. @Preview
  25. @Entry
  26. @Component
  27. export struct SettingPage {
  28. static readonly THEME_MODE: string = 'themeMode';
  29. static readonly SORT_TYPE: string = 'musicSortType';
  30. static readonly IS_BGPLAY_OPEN: string = 'isBgPlayOpen';
  31. static readonly IS_AUTO_RATATE: string = 'isAutoRatate';
  32. static readonly iS_MEMORY_PLAY: string = 'isMemoryPlay';
  33. static readonly IS_MIDIACODEC_OPEN: string = 'isMediacodec';
  34. static readonly iS_MUSIC_MEMORY_PLAY: string = 'isMusicMemoryPlay';
  35. static readonly iS_MUSIC_BG_COVER: string = 'isMusicBGCover';
  36. static readonly iS_SAVE_PLAY_MODE: string = 'isSavePlayMode';
  37. static readonly IS_COVER_RECTANGLE: string = 'isCoverRectangle'; //封面圆形或者方形
  38. static readonly IS_SHOW_SIMI: string = 'isShowSimi';
  39. static readonly IS_SHOW_FAV: string = 'isShowFAV';
  40. static readonly IS_SHOW_HISTORY: string = 'isShowHistory';
  41. static readonly IS_CUSTOMIZE_BG: string = 'is_customize_bg';
  42. static readonly IS_GRID_MUSIC: string = 'is_grid_music';
  43. static readonly IS_CUSTOMIZE_BG_PATH: string = 'is_customize_bg_path';
  44. static readonly IS_SCROLL_HIDE: string = 'isScrollHide';
  45. static readonly IS_SAMETIME_PLAY: string = 'isSameTimePlay';
  46. static readonly CUSTOMIZE_BG_BLUR: string = 'customize_bg_blur';
  47. static readonly BG_BRIGHTNESS: string = 'bg_brightness';
  48. public static THEME_COLOR_KEY: string = 'THEME_COLOR';
  49. public static THEME_COLOR_LIST: Array<ThemeColorItem> = [
  50. { name: '经典蓝', color: '#0A59F7' },
  51. { name: '活力黄', color: '#FFC107' },
  52. { name: '枫叶红', color: '#F44336' },
  53. { name: '玫瑰粉', color: '#FF4081' },
  54. { name: '幻影紫', color: '#9C27B0' },
  55. { name: '翡翠绿', color: '#64BB5C' },
  56. { name: '竹青蓝', color: '#00BCD4' },
  57. { name: '深空灰', color: '#607D8B' },
  58. { name: '橙霞橙', color: '#FF9800' },
  59. { name: '湖水蓝', color: '#00BFFF' },
  60. { name: '柠檬绿', color: '#C6FF00' },
  61. { name: '樱花粉', color: '#FF69B4' },
  62. { name: '暮夜蓝', color: '#283593' },
  63. { name: '薄荷青', color: '#1DE9B6' },
  64. { name: '银沙灰', color: '#B0BEC5' },
  65. { name: '自定义', color: '#ffecec' }
  66. ];
  67. static readonly iS_START_AUTO_PLAY: string = 'isStartAutoPlay';
  68. static readonly iS_MEMORY_LAST_PLAY: string = 'isMemoryLastPlay';
  69. @State showApiDialog: boolean = false
  70. @State tempApiUrl: string = ''
  71. @State lyricApiUrl: string = PreferencesUtil.getStringSync('LRC_API', '')
  72. @State isBgPlayOpen: boolean = true //是否启用后台播放
  73. @State isAutoRatate: boolean = true //是否启用自动横竖屏
  74. @State isMemoryPlay: boolean = true //是否启用记忆播放
  75. @State isMediacodec: boolean = false //是否启用硬件解码
  76. @State isMusicMemoryPlay: boolean = false //是否启用记忆播放
  77. @State isMusicBGCover: boolean = true //播放背景随封面
  78. @State sortType: number = 4 //默认排序方式
  79. @State isStartAutoPlay: boolean = false //启动后自动播放
  80. @State isMemoryLastPlay: boolean = false //是否启用应用退出记忆最后一首的播放进度
  81. @State isShowSimi: boolean = false //是否显示私密音频
  82. @State isShowFAV: boolean = true //是否显示我的收藏
  83. @State isShowHistory: boolean = true //是否显示最近播放
  84. @State isCustomizeBg: boolean = false //自定义背景界面
  85. @State isCustomizeBgSheet: boolean = false //自定义背景界面
  86. @State blurValue: number = 0 //背景模糊
  87. @State bgBrightness: number = 0 //背景亮度
  88. @State isGridMusic: boolean = false //是否网格布局
  89. @State isScrollHide: boolean = false //是否滚动隐藏
  90. @State isSameTimePlay: boolean = false //是否和其他app同时播放
  91. @State isSavePlayMode: boolean = true
  92. @State customizeBgPath: string | undefined = '';
  93. context = getContext(this);
  94. @State showCoverApiDialog: boolean = false
  95. @State tempCoverApiUrl: string = ''
  96. @State coverApiUrl: string = PreferencesUtil.getStringSync('COVER_API', '')
  97. @State apiDialogType: 'lyric' | 'cover' = 'lyric'
  98. @State themeMode: number = 0 // 0: 跟随系统, 1: 浅色, 2: 深色
  99. @StorageProp('currentColorMode') @Watch('onColorModeChange') currentMode: number =
  100. ConfigurationConstant.ColorMode.COLOR_MODE_LIGHT;
  101. @StorageLink('isDarkMode') isDarkMode: boolean = false // 是否启用深色模式
  102. /** 当前断点类型(如大屏/小屏) */
  103. @StorageProp('currentBreakpoint') currentBreakpoint: string = BreakpointTypeEnum.MD;
  104. @State verName: string = ''
  105. @StorageProp('themeColor') themeColor: string = PreferencesUtil.getStringSync('THEME_COLOR', '#FF4081');
  106. @State showColorPicker: boolean = false
  107. @State customColor: string = PreferencesUtil.getStringSync('THEME_COLOR', '#FF4081');
  108. @State isThemeSheet: boolean = false // 主题设置弹窗显示状态
  109. @State colorRows: Array<Array<ThemeColorItem>> = chunkArray(SettingPage.THEME_COLOR_LIST, 2);
  110. @State colorGroup: string = "group"
  111. apiDialogController: CustomDialogController = new CustomDialogController({
  112. builder: CustomContentDialog({
  113. primaryTitle: this.apiDialogType === 'lyric' ? '修改歌词API地址' : '修改封面API地址',
  114. contentBuilder: () => {
  115. this.buildApiDialogContent();
  116. },
  117. buttons: [
  118. {
  119. value: '取消',
  120. action: () => {
  121. this.apiDialogController.close();
  122. }
  123. },
  124. {
  125. value: '保存',
  126. action: () => {
  127. if (this.apiDialogType === 'lyric') {
  128. this.lyricApiUrl = this.tempApiUrl.trim()
  129. PreferencesUtil.put('LRC_API', this.lyricApiUrl)
  130. this.getUIContext().getPromptAction().showToast({
  131. message: '保存成功,当前LRC_API:' + this.lyricApiUrl,
  132. duration: 2000,
  133. showMode: promptAction.ToastShowMode.TOP_MOST,
  134. bottom: 85
  135. })
  136. } else {
  137. this.coverApiUrl = this.tempApiUrl.trim()
  138. PreferencesUtil.put('COVER_API', this.coverApiUrl)
  139. this.getUIContext().getPromptAction().showToast({
  140. message: '保存成功,当前COVER_API:' + this.coverApiUrl,
  141. duration: 2000,
  142. showMode: promptAction.ToastShowMode.TOP_MOST,
  143. bottom: 85
  144. })
  145. }
  146. this.apiDialogController.close();
  147. }
  148. }
  149. ]
  150. }),
  151. autoCancel: true,
  152. alignment: DialogAlignment.Center
  153. })
  154. @Builder
  155. buildApiDialogContent() {
  156. Column() {
  157. TextInput({
  158. text: this.tempApiUrl,
  159. placeholder: this.apiDialogType === 'lyric' ? '请输入歌词API地址' : '请输入封面API地址'
  160. })
  161. .onChange((val: string) => {
  162. this.tempApiUrl = val
  163. })
  164. .width('90%')
  165. .height(60)
  166. }
  167. .width('100%')
  168. }
  169. // 组件生命周期
  170. aboutToAppear() {
  171. this.isBgPlayOpen = PreferencesUtil.getBooleanSync(SettingPage.IS_BGPLAY_OPEN, true)
  172. this.isAutoRatate = PreferencesUtil.getBooleanSync(SettingPage.IS_AUTO_RATATE, true)
  173. this.isMemoryPlay = PreferencesUtil.getBooleanSync(SettingPage.iS_MEMORY_PLAY, true)
  174. this.isMediacodec = PreferencesUtil.getBooleanSync(SettingPage.IS_MIDIACODEC_OPEN, false)
  175. this.isMusicMemoryPlay = PreferencesUtil.getBooleanSync(SettingPage.iS_MUSIC_MEMORY_PLAY, false)
  176. this.isMusicBGCover = PreferencesUtil.getBooleanSync(SettingPage.iS_MUSIC_BG_COVER, true)
  177. this.sortType = PreferencesUtil.getNumberSync(SettingPage.SORT_TYPE, 4)
  178. this.isShowSimi = PreferencesUtil.getBooleanSync(SettingPage.IS_SHOW_SIMI, false)
  179. this.isShowFAV = PreferencesUtil.getBooleanSync(SettingPage.IS_SHOW_FAV, true)
  180. this.isShowHistory = PreferencesUtil.getBooleanSync(SettingPage.IS_SHOW_HISTORY, true)
  181. this.isCustomizeBg = PreferencesUtil.getBooleanSync(SettingPage.IS_CUSTOMIZE_BG, false)
  182. this.customizeBgPath = PreferencesUtil.getStringSync(SettingPage.IS_CUSTOMIZE_BG_PATH, '')
  183. this.isGridMusic = PreferencesUtil.getBooleanSync(SettingPage.IS_GRID_MUSIC, false)
  184. this.isScrollHide = PreferencesUtil.getBooleanSync(SettingPage.IS_SCROLL_HIDE, false)
  185. this.isSameTimePlay = PreferencesUtil.getBooleanSync(SettingPage.IS_SAMETIME_PLAY, false)
  186. this.isSavePlayMode = PreferencesUtil.getBooleanSync(SettingPage.iS_SAVE_PLAY_MODE, true)
  187. this.blurValue = PreferencesUtil.getNumberSync(SettingPage.CUSTOMIZE_BG_BLUR, 0)
  188. this.bgBrightness = PreferencesUtil.getNumberSync(SettingPage.BG_BRIGHTNESS, 0)
  189. this.isStartAutoPlay = PreferencesUtil.getBooleanSync(SettingPage.iS_START_AUTO_PLAY, false)
  190. this.isMemoryLastPlay = PreferencesUtil.getBooleanSync(SettingPage.iS_MEMORY_LAST_PLAY, false)
  191. // 只用 themeMode 控制主题
  192. this.themeMode = PreferencesUtil.getNumberSync(SettingPage.THEME_MODE, 0)
  193. this.applyThemeMode(this.themeMode)
  194. let themeColor = PreferencesUtil.getStringSync('THEME_COLOR', '#FF4081');
  195. AppStorage.setOrCreate('themeColor', themeColor);
  196. this.themeColor = themeColor;
  197. }
  198. // 监听颜色模式变化
  199. onColorModeChange(): void {
  200. this.isDarkMode = this.currentMode === ConfigurationConstant.ColorMode.COLOR_MODE_DARK;
  201. AppStorage.setOrCreate('isDarkMode', this.isDarkMode);
  202. }
  203. // 组件生命周期
  204. aboutToDisappear() {
  205. // 无需处理apiDialogController
  206. }
  207. applyThemeMode(mode: number) {
  208. let colorMode = ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET
  209. if (mode === 1) {
  210. colorMode = ConfigurationConstant.ColorMode.COLOR_MODE_LIGHT
  211. } else if (mode === 2) {
  212. colorMode = ConfigurationConstant.ColorMode.COLOR_MODE_DARK
  213. }
  214. AppStorage.setOrCreate('currentColorMode', colorMode)
  215. AppStorage.setOrCreate('isDarkMode', colorMode === ConfigurationConstant.ColorMode.COLOR_MODE_DARK)
  216. PreferencesUtil.putSync(SettingPage.THEME_MODE, mode)
  217. AppStorage.setOrCreate('themeMode', mode)
  218. // 只有强制浅色/深色时才主动设置
  219. const context = getContext(this) as common.UIAbilityContext
  220. context.getApplicationContext().setColorMode(colorMode)
  221. }
  222. //是不是手机横屏
  223. isPhoneLan() {
  224. if (DeviceUtil.getDeviceType() === resourceManager.DeviceType.DEVICE_TYPE_PHONE
  225. && this.currentBreakpoint !== BreakpointTypeEnum.SM) {
  226. if (DisplayUtil.getFoldStatus() === 0) {
  227. return true
  228. }
  229. }
  230. return false
  231. }
  232. @Builder
  233. pickerBuilder() {
  234. Column({ space: 20 }) {
  235. HSBColorPicker({
  236. color: this.customColor,
  237. radius: 8,
  238. onChange: (value: string) => {
  239. this.customColor = value
  240. }
  241. })
  242. .layoutWeight(1)
  243. .padding(15)
  244. Row({ space: 10 }) {
  245. Button('取消')
  246. .stateEffect(true)
  247. .backgroundColor(this.themeColor)
  248. .onClick(() => {
  249. this.showColorPicker = false
  250. })
  251. Button('确定')
  252. .stateEffect(true)
  253. .backgroundColor(this.themeColor)
  254. .onClick(() => {
  255. this.themeColor = this.customColor
  256. PreferencesUtil.putSync(SettingPage.THEME_COLOR_KEY, this.customColor)
  257. AppStorage.setOrCreate('themeColor', this.customColor)
  258. this.sendChangeEvent()
  259. this.showColorPicker = false
  260. })
  261. }
  262. }
  263. .padding(20)
  264. .width('80%')
  265. .height(300)
  266. }
  267. @Builder
  268. themeSheetBuilder() {
  269. Column() {
  270. // 颜色模式分组卡片
  271. Column() {
  272. Row() {
  273. Row() {
  274. Image($r('app.media.theme'))
  275. .width(20)
  276. .height(20)
  277. .fillColor(this.themeColor)
  278. Text('颜色模式')
  279. .fontSize(15)
  280. .margin({ left: 6 })
  281. .fontWeight(500)
  282. }
  283. .layoutWeight(1)
  284. Blank()
  285. Row() {
  286. ForEach(['自动', '日间', '夜间'], (item: string, idx: number) => {
  287. Column() {
  288. Radio({
  289. value: idx.toString(),
  290. group: this.colorGroup,
  291. })
  292. .checked(this.themeMode === idx)
  293. .radioStyle({
  294. checkedBackgroundColor: this.themeColor
  295. })
  296. .margin({ left: 3, right: 3 })
  297. .onClick(() => {
  298. this.themeMode = idx
  299. this.applyThemeMode(idx)
  300. this.sendChangeEvent()
  301. })
  302. Text(item)
  303. .fontSize(15)
  304. .fontColor($r('app.color.text_color'))
  305. .margin({ top: 6 })
  306. .onClick(() => {
  307. this.themeMode = idx
  308. this.applyThemeMode(idx)
  309. this.sendChangeEvent()
  310. })
  311. }
  312. .alignItems(HorizontalAlign.Center)
  313. .margin({ left: 12, right: 12 })
  314. })
  315. }
  316. .margin({ left: 12, right: 12 })
  317. }
  318. }
  319. .backgroundColor($r('app.color.settings_background_main'))
  320. .borderRadius(18)
  321. .border({ width: 1, color: '#F0F0F0' })
  322. .shadow({
  323. radius: 12,
  324. color: 0x11000000,
  325. offsetX: 0,
  326. offsetY: 2
  327. })
  328. .margin({
  329. left: 0,
  330. right: 0,
  331. bottom: 20
  332. })
  333. .padding({
  334. top: 18,
  335. bottom: 18,
  336. left: 20,
  337. right: 20
  338. })
  339. .width('90%')
  340. // 主题色分组卡片
  341. Column() {
  342. Row() {
  343. Image($r('app.media.theme'))
  344. .width(20)
  345. .height(20)
  346. .fillColor(this.themeColor)
  347. Text('主题色')
  348. .fontSize(15)
  349. .fontWeight(500)
  350. .margin({ left: 8 })
  351. .layoutWeight(1)
  352. }
  353. .margin({ left: 20, top: 12 })
  354. Row() {
  355. Column() {
  356. ForEach(this.colorRows, (row: Array<ThemeColorItem>, rowIdx: number) => {
  357. Row() {
  358. ForEach(row, (item: ThemeColorItem, colIdx: number) => {
  359. Button() {
  360. Row() {
  361. Blank()
  362. .width(22)
  363. .height(22)
  364. .backgroundColor(item.name === '自定义' && this.isCustomThemeColor() ? this.themeColor :
  365. item.color)
  366. .border({ width: 2, color: $r('app.color.text_color') })
  367. .borderRadius(11)
  368. Text(item.name)
  369. .fontSize(15)
  370. .fontColor($r('app.color.text_color'))
  371. .margin({ left: 10 })
  372. }
  373. .alignItems(VerticalAlign.Center)
  374. .justifyContent(FlexAlign.Start)
  375. .layoutWeight(1)
  376. }
  377. .height(40)
  378. .layoutWeight(1)
  379. .backgroundColor(
  380. (item.name === '自定义' && this.isCustomThemeColor()) || this.themeColor === item.color
  381. ? this.themeColor
  382. : $r('app.color.settings_background_main')
  383. )
  384. .borderRadius(20)
  385. .onClick(() => {
  386. if (item.name === '自定义') {
  387. this.showColorPicker = true
  388. } else {
  389. this.themeColor = item.color
  390. PreferencesUtil.putSync(SettingPage.THEME_COLOR_KEY, item.color)
  391. AppStorage.setOrCreate('themeColor', item.color)
  392. this.sendChangeEvent()
  393. }
  394. })
  395. .margin({ right: colIdx === 0 ? '4%' : 20, bottom: 10, left: 20 })
  396. })
  397. }
  398. .justifyContent(FlexAlign.Start)
  399. })
  400. }
  401. .margin({ left: 12, right: 12, top: 12 })
  402. }
  403. }
  404. .width('90%')
  405. .backgroundColor($r('app.color.settings_background_main'))
  406. .borderRadius(18)
  407. .border({ width: 1, color: '#F0F0F0' })
  408. .shadow({
  409. radius: 12,
  410. color: 0x11000000,
  411. offsetX: 0,
  412. offsetY: 2
  413. })
  414. .margin({
  415. left: 0,
  416. right: 0,
  417. bottom: 18
  418. })
  419. .padding({
  420. top: 18,
  421. bottom: 18,
  422. left: 0,
  423. right: 0
  424. })
  425. .bindPopup(this.showColorPicker, {
  426. builder: this.pickerBuilder(),
  427. placement: Placement.Top,
  428. mask: { color: '#33000000' },
  429. enableArrow: false, //是否显示箭头
  430. showInSubWindow: false,
  431. onStateChange: (e) => {
  432. if (!e.isVisible) {
  433. this.showColorPicker = false
  434. }
  435. }
  436. })
  437. // 主题色自定义弹窗
  438. }
  439. .padding({
  440. top: 8,
  441. bottom: 8,
  442. left: 15,
  443. right: 15
  444. })
  445. .width('100%')
  446. .backgroundColor(Color.Transparent)
  447. .borderRadius(24)
  448. }
  449. build() {
  450. Column() {
  451. Column() {
  452. Line().width('100%').height('100%')
  453. }
  454. .height(this.isPhoneLan() ? 0 : px2vp(AppUtil.getStatusBarHeight()))
  455. .backgroundColor(this.isDarkMode ? $r('app.color.title_bar_bg') : this.themeColor)
  456. .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP])
  457. // 自定义标题栏
  458. Stack() {
  459. // 居中标题
  460. Text('通用设置')
  461. .fontSize(20)
  462. .fontColor(Color.White)
  463. .align(Alignment.Center)
  464. // 左侧返回按钮
  465. Row() {
  466. Image($r('app.media.left_back_white'))
  467. .width(29)
  468. .height(29)
  469. .margin({ left: 12, right: 8 })
  470. .onClick(() => {
  471. router.back();
  472. })
  473. Blank().flexGrow(1)
  474. Blank().width(32)
  475. }
  476. .height(48)
  477. .width('100%')
  478. .alignItems(VerticalAlign.Center)
  479. }
  480. .height(48)
  481. .width('100%')
  482. .backgroundColor(this.isDarkMode ? $r('app.color.title_bar_bg') : this.themeColor)
  483. Scroll() {
  484. Column() {
  485. // 主题设置分组
  486. Column() {
  487. Row() {
  488. Text('个性化')
  489. .margin({ left: 18, right: 20 })
  490. .fontSize(16)
  491. .fontColor(Color.Gray)
  492. .fontWeight(480)
  493. .layoutWeight(1)
  494. }
  495. .height(48)
  496. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  497. // 主题设置弹框入口
  498. Button({ type: ButtonType.Normal, stateEffect: true }) {
  499. Row() {
  500. Text('主题设置')
  501. .margin({ left: 18 })
  502. .fontSize(15)
  503. .fontColor(Color.Gray)
  504. .fontWeight(480)
  505. .layoutWeight(1)
  506. Image($r('app.media.arrow_right'))
  507. .width(22)
  508. .height(22)
  509. .margin({ right: 18 })
  510. }
  511. }
  512. .backgroundColor(Color.Transparent)
  513. .height(55)
  514. .onClick(() => {
  515. this.showColorPicker = false;
  516. this.isThemeSheet = true;
  517. this.customColor = this.themeColor;
  518. })
  519. .bindSheet($$this.isThemeSheet, this.themeSheetBuilder(), {
  520. height: '95%',
  521. dragBar: true,
  522. preferType: this.currentBreakpoint !== BreakpointTypeEnum.SM ? SheetType.CENTER : SheetType.BOTTOM,
  523. showClose: true,
  524. blurStyle: BlurStyle.Thin,
  525. backgroundColor: Color.Transparent,
  526. title: { title: '主题设置' },
  527. shouldDismiss: (SheetDismiss: SheetDismiss) => {
  528. SheetDismiss.dismiss();
  529. this.showColorPicker = false;
  530. }
  531. })
  532. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  533. Button({ type: ButtonType.Normal, stateEffect: true }) {
  534. Row() {
  535. Text('自定义背景')
  536. .margin({ left: 18 })
  537. .fontSize(15)
  538. .fontColor(Color.Gray)
  539. .fontWeight(480)
  540. .layoutWeight(1)
  541. .bindSheet($$this.isCustomizeBgSheet, this.customizeBgSheet(), {
  542. height: '95%',
  543. dragBar: true,
  544. preferType: this.currentBreakpoint !== BreakpointTypeEnum.SM ? SheetType.CENTER : SheetType.BOTTOM,
  545. showClose: true,
  546. blurStyle: BlurStyle.Thin,
  547. backgroundColor: Color.Transparent,
  548. title: { title: '自定义背景' }
  549. })
  550. Blank()
  551. // 右侧箭头
  552. Image($r('app.media.arrow_right'))
  553. .width(22)
  554. .height(22)
  555. .margin({ left: 20, right: 20 })
  556. .align(Alignment.Center)
  557. }
  558. }
  559. .height(55)
  560. .onClick(() => {
  561. this.isCustomizeBgSheet = !this.isCustomizeBgSheet;
  562. })
  563. .backgroundColor(Color.Transparent)
  564. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  565. // 滚动隐藏'
  566. Row() {
  567. Text('滚动隐藏')
  568. .margin({ left: 18 })
  569. .fontSize(15)
  570. .fontColor(Color.Gray)
  571. .fontWeight(480)
  572. .layoutWeight(1)
  573. Toggle({ type: ToggleType.Switch, isOn: this.isScrollHide })
  574. .selectedColor(this.themeColor)
  575. .switchPointColor(Color.White)
  576. .margin({ right: 18 })
  577. .onChange((checked: boolean) => {
  578. this.isScrollHide = checked;
  579. PreferencesUtil.put(SettingPage.IS_SCROLL_HIDE, this.isScrollHide)
  580. this.sendChangeEvent()
  581. })
  582. .width(50)
  583. .height(30);
  584. }
  585. .height(55)
  586. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  587. // 显示私密音频
  588. Row() {
  589. Text('网格布局')
  590. .margin({ left: 18 })
  591. .fontSize(15)
  592. .fontColor(Color.Gray)
  593. .fontWeight(480)
  594. .layoutWeight(1)
  595. Toggle({ type: ToggleType.Switch, isOn: this.isGridMusic })
  596. .selectedColor(this.themeColor)
  597. .switchPointColor(Color.White)
  598. .margin({ right: 18 })
  599. .onChange((checked: boolean) => {
  600. this.isGridMusic = checked;
  601. PreferencesUtil.put(SettingPage.IS_GRID_MUSIC, this.isGridMusic)
  602. this.sendChangeEvent()
  603. })
  604. .width(50)
  605. .height(30);
  606. }
  607. .height(55)
  608. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  609. // 显示私密音频
  610. Row() {
  611. Text('显示私密音频')
  612. .margin({ left: 18 })
  613. .fontSize(15)
  614. .fontColor(Color.Gray)
  615. .fontWeight(480)
  616. .layoutWeight(1)
  617. Toggle({ type: ToggleType.Switch, isOn: this.isShowSimi })
  618. .selectedColor(this.themeColor)
  619. .switchPointColor(Color.White)
  620. .margin({ right: 18 })
  621. .onChange((checked: boolean) => {
  622. this.isShowSimi = checked;
  623. PreferencesUtil.put(SettingPage.IS_SHOW_SIMI, this.isShowSimi)
  624. this.sendChangeEvent()
  625. })
  626. .width(50)
  627. .height(30);
  628. }
  629. .height(55)
  630. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  631. // 显示我的收藏
  632. Row() {
  633. Text('显示我的收藏')
  634. .margin({ left: 18 })
  635. .fontSize(15)
  636. .fontColor(Color.Gray)
  637. .fontWeight(480)
  638. .layoutWeight(1)
  639. Toggle({ type: ToggleType.Switch, isOn: this.isShowFAV })
  640. .selectedColor(this.themeColor)
  641. .switchPointColor(Color.White)
  642. .margin({ right: 18 })
  643. .onChange((checked: boolean) => {
  644. this.isShowFAV = checked;
  645. PreferencesUtil.put(SettingPage.IS_SHOW_FAV, this.isShowFAV)
  646. this.sendChangeEvent()
  647. })
  648. .width(50)
  649. .height(30);
  650. }
  651. .height(55)
  652. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  653. // 显示最近播放
  654. Row() {
  655. Text('显示最近播放')
  656. .margin({ left: 18 })
  657. .fontSize(15)
  658. .fontColor(Color.Gray)
  659. .fontWeight(480)
  660. .layoutWeight(1)
  661. Toggle({ type: ToggleType.Switch, isOn: this.isShowHistory })
  662. .selectedColor(this.themeColor)
  663. .switchPointColor(Color.White)
  664. .margin({ right: 18 })
  665. .onChange((checked: boolean) => {
  666. this.isShowHistory = checked;
  667. PreferencesUtil.put(SettingPage.IS_SHOW_HISTORY, this.isShowHistory)
  668. this.sendChangeEvent()
  669. })
  670. .width(50)
  671. .height(30);
  672. }
  673. .height(55)
  674. }
  675. .backgroundColor($r('app.color.settings_background_main'))
  676. .borderRadius(20)
  677. .margin({
  678. left: 0,
  679. right: 0,
  680. top: 0,
  681. bottom: 10
  682. })
  683. .padding(0)
  684. // 音频设置分组
  685. Column() {
  686. Row() {
  687. Text('音频设置')
  688. .margin({ left: 18, right: 20 })
  689. .fontSize(16)
  690. .fontColor(Color.Gray)
  691. .fontWeight(480)
  692. .layoutWeight(1)
  693. }
  694. .height(48)
  695. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  696. // 启动时播放
  697. Row() {
  698. Text('启动时播放')
  699. .margin({ left: 18 })
  700. .fontSize(15)
  701. .fontColor(Color.Gray)
  702. .fontWeight(480)
  703. .layoutWeight(1)
  704. Toggle({ type: ToggleType.Switch, isOn: this.isStartAutoPlay })
  705. .selectedColor(this.themeColor)
  706. .switchPointColor(Color.White)
  707. .margin({ right: 18 })
  708. .onChange((checked: boolean) => {
  709. this.isStartAutoPlay = checked;
  710. PreferencesUtil.put(SettingPage.iS_START_AUTO_PLAY, this.isStartAutoPlay)
  711. })
  712. .width(50)
  713. .height(30);
  714. }
  715. .height(55)
  716. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  717. // 记住播放进度
  718. Row() {
  719. Text('记住最后一首进度')
  720. .margin({ left: 18 })
  721. .fontSize(15)
  722. .fontColor(Color.Gray)
  723. .fontWeight(480)
  724. .layoutWeight(1)
  725. Toggle({ type: ToggleType.Switch, isOn: this.isMemoryLastPlay })
  726. .selectedColor(this.themeColor)
  727. .switchPointColor(Color.White)
  728. .margin({ right: 18 })
  729. .onChange((checked: boolean) => {
  730. this.isMemoryLastPlay = checked;
  731. PreferencesUtil.put(SettingPage.iS_MEMORY_LAST_PLAY, this.isMemoryLastPlay)
  732. this.sendChangeEvent()
  733. })
  734. .width(50)
  735. .height(30);
  736. }
  737. .height(55)
  738. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  739. // 记忆播放
  740. Row() {
  741. Text('记忆播放')
  742. .margin({ left: 18 })
  743. .fontSize(15)
  744. .fontColor(Color.Gray)
  745. .fontWeight(480)
  746. .layoutWeight(1)
  747. Toggle({ type: ToggleType.Switch, isOn: this.isMusicMemoryPlay })
  748. .selectedColor(this.themeColor)
  749. .switchPointColor(Color.White)
  750. .margin({ right: 18 })
  751. .onChange((checked: boolean) => {
  752. this.isMusicMemoryPlay = checked;
  753. PreferencesUtil.put(SettingPage.iS_MUSIC_MEMORY_PLAY, this.isMusicMemoryPlay)
  754. this.sendChangeEvent()
  755. })
  756. .width(50)
  757. .height(30);
  758. }
  759. .height(55)
  760. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  761. // 默认排序模式
  762. Row() {
  763. Text('默认排序模式')
  764. .margin({ left: 18 })
  765. .fontSize(15)
  766. .fontColor(Color.Gray)
  767. .fontWeight(480)
  768. .layoutWeight(1)
  769. Select([
  770. { value: CommonConstants.SORT_ARRAY[0] },
  771. { value: CommonConstants.SORT_ARRAY[1] },
  772. { value: CommonConstants.SORT_ARRAY[2] },
  773. { value: CommonConstants.SORT_ARRAY[3] },
  774. { value: CommonConstants.SORT_ARRAY[4] },
  775. { value: CommonConstants.SORT_ARRAY[5] },
  776. { value: CommonConstants.SORT_ARRAY[6] },
  777. { value: CommonConstants.SORT_ARRAY[7] }])
  778. .font({ size: 15, weight: FontWeight.Medium })
  779. .fontColor(Color.Gray)
  780. .margin({ right: 18 })
  781. .selected(this.sortType)
  782. .value(CommonConstants.SORT_ARRAY[this.sortType])
  783. .onSelect(async (_index: number, text?: string | undefined) => {
  784. this.sortType = _index
  785. PreferencesUtil.put(SettingPage.SORT_TYPE, this.sortType)
  786. this.sendChangeEvent()
  787. })
  788. }
  789. .height(55)
  790. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  791. .visibility(Visibility.None)
  792. // 默认排序模式
  793. Row() {
  794. Text('保存播放模式')
  795. .margin({ left: 18 })
  796. .fontSize(15)
  797. .fontColor(Color.Gray)
  798. .fontWeight(480)
  799. .layoutWeight(1)
  800. Toggle({ type: ToggleType.Switch, isOn: this.isSavePlayMode })
  801. .selectedColor(this.themeColor)
  802. .switchPointColor(Color.White)
  803. .margin({ right: 18 })
  804. .onChange((checked: boolean) => {
  805. this.isSavePlayMode = checked;
  806. PreferencesUtil.put(SettingPage.iS_SAVE_PLAY_MODE, this.isSavePlayMode)
  807. })
  808. .width(50)
  809. .height(30);
  810. }
  811. .height(55)
  812. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  813. .visibility(Visibility.None)
  814. Row() {
  815. Text('与其他应用同时播放')
  816. .margin({ left: 18 })
  817. .fontSize(15)
  818. .fontColor(Color.Gray)
  819. .fontWeight(480)
  820. .layoutWeight(1)
  821. Toggle({ type: ToggleType.Switch, isOn: this.isSameTimePlay })
  822. .selectedColor(this.themeColor)
  823. .switchPointColor(Color.White)
  824. .margin({ right: 18 })
  825. .onChange((checked: boolean) => {
  826. this.isSameTimePlay = checked;
  827. PreferencesUtil.put(SettingPage.IS_SAMETIME_PLAY, this.isSameTimePlay)
  828. })
  829. .width(50)
  830. .height(30);
  831. }
  832. .height(55)
  833. .visibility(Visibility.None)
  834. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  835. // 播放背景随音乐封面
  836. Row() {
  837. Text('播放背景随音乐封面')
  838. .margin({ left: 18 })
  839. .fontSize(15)
  840. .fontColor(Color.Gray)
  841. .fontWeight(480)
  842. .layoutWeight(1)
  843. Toggle({ type: ToggleType.Switch, isOn: this.isMusicBGCover })
  844. .selectedColor(this.themeColor)
  845. .switchPointColor(Color.White)
  846. .margin({ right: 18 })
  847. .onChange((checked: boolean) => {
  848. this.isMusicBGCover = checked;
  849. PreferencesUtil.put(SettingPage.iS_MUSIC_BG_COVER, this.isMusicBGCover)
  850. })
  851. .width(50)
  852. .height(30);
  853. }
  854. .height(55)
  855. }
  856. .backgroundColor($r('app.color.settings_background_main'))
  857. .borderRadius(20)
  858. .margin({
  859. left: 0,
  860. right: 0,
  861. top: 10,
  862. bottom: 10
  863. })
  864. .padding(0)
  865. // API设置分组
  866. Column() {
  867. Row() {
  868. Text('API设置')
  869. .margin({ left: 18, right: 20 })
  870. .fontSize(16)
  871. .fontColor(Color.Gray)
  872. .fontWeight(480)
  873. .layoutWeight(1)
  874. }
  875. .height(48)
  876. Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
  877. // 歌词API
  878. Button({ type: ButtonType.Normal, stateEffect: true }) {
  879. Row() {
  880. Text('歌词:')
  881. .margin({ left: 18, right: 6 })
  882. .fontSize(15)
  883. .fontColor(Color.Gray)
  884. Text(this.lyricApiUrl)
  885. .margin({ right: 10 })
  886. .fontSize(15)
  887. .fontColor(Color.Gray)
  888. .layoutWeight(1)
  889. Image(this.isDarkMode ? $r('app.media.rename2') : $r('app.media.rename'))
  890. .width(20)
  891. .height(20)
  892. .margin({ right: 18 })
  893. }
  894. }
  895. .backgroundColor(Color.Transparent)
  896. .onClick(() => {
  897. this.apiDialogType = 'lyric'
  898. this.tempApiUrl = this.lyricApiUrl
  899. this.apiDialogController.open()
  900. })
  901. .height(55)
  902. // 封面API
  903. Button({ type: ButtonType.Normal, stateEffect: true }) {
  904. Row() {
  905. Text('封面:')
  906. .margin({ left: 18, right: 6 })
  907. .fontSize(15)
  908. .fontColor(Color.Gray)
  909. Text(this.coverApiUrl)
  910. .margin({ right: 10 })
  911. .fontSize(15)
  912. .fontColor(Color.Gray)
  913. .layoutWeight(1)
  914. Image(this.isDarkMode ? $r('app.media.rename2') : $r('app.media.rename'))
  915. .width(20)
  916. .height(20)
  917. .margin({ right: 18 })
  918. }
  919. }
  920. .backgroundColor(Color.Transparent)
  921. .onClick(() => {
  922. this.apiDialogType = 'cover'
  923. this.tempApiUrl = this.coverApiUrl
  924. this.apiDialogController.open()
  925. })
  926. .height(55)
  927. }
  928. .backgroundColor($r('app.color.settings_background_main'))
  929. .borderRadius(20)
  930. .margin({
  931. left: 0,
  932. right: 0,
  933. top: 10,
  934. bottom: 20
  935. })
  936. .padding(0)
  937. Button({ type: ButtonType.Capsule, stateEffect: true }) {
  938. Column() {
  939. Row() {
  940. Text('设置教程:')
  941. .margin({ left: 18 })
  942. .fontSize(15)
  943. .fontColor(Color.Gray)
  944. .fontWeight(480)
  945. Text('点击进Q群讨论')
  946. .margin({ right: 10 })
  947. .fontSize(15)
  948. .fontColor(Color.Gray)
  949. .layoutWeight(1)
  950. Blank()
  951. // 右侧箭头
  952. Image($r('app.media.arrow_right'))
  953. .width(22)
  954. .height(22)
  955. .margin({ left: 20, right: 20 })
  956. .align(Alignment.Center)
  957. }
  958. .height(55)
  959. }
  960. }
  961. .onClick(() => {
  962. const qqUrl =
  963. `mqqapi://card/show_pslcard?src_type=internal&version=1&uin=${CommonConstants.QQ_GROUP}&card_type=group&source=external`;
  964. let context = this.getUIContext().getHostContext() as common.UIAbilityContext;
  965. context.openLink(qqUrl, {})
  966. })
  967. .backgroundColor($r('app.color.settings_background_main'))
  968. .borderRadius(15)
  969. .margin({ top: 0, bottom: 20 })
  970. .padding(0)
  971. //空白
  972. Column() {
  973. Blank()
  974. .height(88)
  975. }.height(88)
  976. }
  977. .margin({
  978. left: this.currentBreakpoint !== BreakpointTypeEnum.SM ? 35 : 20,
  979. right: this.currentBreakpoint !== BreakpointTypeEnum.SM ? 35 : 20,
  980. top: 20,
  981. bottom: 20
  982. })
  983. .justifyContent(FlexAlign.Start)
  984. }
  985. .scrollBar(BarState.Auto)
  986. .height(px2vp(DisplayUtil.getHeight() - AppUtil.getStatusBarHeight() - AppUtil.getNavigationIndicatorHeight()))
  987. .width('100%')
  988. .margin({ bottom: 10 })
  989. .backgroundColor($r('app.color.settings_background'))
  990. }
  991. .height('100%')
  992. .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM])
  993. }
  994. //发送广播通知更新UI
  995. sendChangeEvent() {
  996. const eventData: emitter.EventData = {};
  997. emitter.emit({ eventId: 333 }, eventData); // 发送广播通知更新doSwipBack
  998. }
  999. goSelectImage() {
  1000. let selectUris: Array<string> = [];
  1001. let photoPicker = new photoAccessHelper.PhotoViewPicker();
  1002. let photoSelectOptions = new photoAccessHelper.PhotoSelectOptions();
  1003. photoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE; // 过滤选择媒体文件类型为IMAGE
  1004. photoSelectOptions.maxSelectNumber = 1; // 选择媒体文件的最大数目
  1005. photoPicker.select(photoSelectOptions).then(async (photoSelectResult: photoAccessHelper.PhotoSelectResult) => {
  1006. //用一个全局变量存储返回的uri
  1007. selectUris = photoSelectResult.photoUris;
  1008. console.info('photoViewPicker.select to file succeed and uris are:' + selectUris);
  1009. //使用fs.openSync接口,通过uri打开这个文件得到fd
  1010. let file = fileIo.openSync(selectUris[0], fileIo.OpenMode.READ_ONLY);
  1011. console.info('file fd: ' + file.fd);
  1012. const timestamp: number = Math.floor(Date.now() / 1000);
  1013. let name = timestamp + "_homebg"
  1014. let imagePath = this.context.filesDir + FileUtil.separator + name
  1015. imagePath = fileUri.getUriFromPath(imagePath)
  1016. let file2 = fileIo.openSync(imagePath, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE)
  1017. fileIo.copyFileSync(file.fd, file2.fd)
  1018. fileIo.closeSync(file);
  1019. fileIo.closeSync(file2);
  1020. this.customizeBgPath = imagePath
  1021. PreferencesUtil.put(SettingPage.IS_CUSTOMIZE_BG_PATH, this.customizeBgPath)
  1022. this.sendChangeEvent()
  1023. }).catch((err: BusinessError) => {
  1024. console.error(`Invoke photoViewPicker.select failed, code is ${err.code}, message is ${err.message}`);
  1025. })
  1026. }
  1027. @Builder
  1028. customizeBgSheet() {
  1029. Scroll() {
  1030. Column() {
  1031. this.CustomizeBg()
  1032. }
  1033. }
  1034. .width('100%')
  1035. .height('100%')
  1036. }
  1037. @Builder
  1038. CustomizeBg() {
  1039. Column() {
  1040. Image(this.customizeBgPath)
  1041. .height('42%')
  1042. .alt($r('app.color.white'))
  1043. .objectFit(ImageFit.Contain)
  1044. .borderRadius(20)
  1045. .clip(true)
  1046. .blur(this.blurValue)
  1047. .brightness(this.bgBrightness + 0.8)
  1048. .margin({ left: 30, right: 30, bottom: 20 })
  1049. Row() {
  1050. Row() {
  1051. Button('选择图片')
  1052. .fontColor(Color.White)
  1053. .fontSize(12)
  1054. .height(48)
  1055. .width(100)
  1056. .backgroundColor(this.themeColor)
  1057. .stateEffect(true)
  1058. .onClick(async () => {
  1059. this.goSelectImage()
  1060. })
  1061. }
  1062. .height('100%')
  1063. .justifyContent(FlexAlign.Center)
  1064. .layoutWeight(1)
  1065. }
  1066. .width('100%')
  1067. .height(58)
  1068. .margin({ bottom: 20 })
  1069. Column() {
  1070. Row() {
  1071. Text('自定义背景:')
  1072. .margin({ left: 18 })
  1073. .fontSize(15)
  1074. .fontColor($r('app.color.text_color'))
  1075. .fontWeight(480)
  1076. .layoutWeight(1)
  1077. Toggle({ type: ToggleType.Switch, isOn: this.isCustomizeBg })
  1078. .selectedColor(this.themeColor)
  1079. .switchPointColor(Color.White)
  1080. .margin({ right: 18 })
  1081. .onChange((checked: boolean) => {
  1082. this.isCustomizeBg = checked;
  1083. PreferencesUtil.put(SettingPage.IS_CUSTOMIZE_BG, this.isCustomizeBg)
  1084. this.sendChangeEvent()
  1085. })
  1086. .width(50)
  1087. .height(30);
  1088. }
  1089. .height(55)
  1090. }
  1091. .backgroundColor($r('app.color.settings_background_main'))
  1092. .borderRadius(15)
  1093. .margin({
  1094. left: 30,
  1095. right: 30,
  1096. top: 0,
  1097. bottom: 20
  1098. })
  1099. .padding(0)
  1100. Column() {
  1101. Row() {
  1102. Text('背景模糊:')
  1103. .margin({ left: 18 })
  1104. .fontSize(15)
  1105. .fontColor($r('app.color.text_color'))
  1106. .fontWeight(480)
  1107. Slider({
  1108. value: this.blurValue,
  1109. min: 0,
  1110. max: 100,
  1111. step: 1,
  1112. style: SliderStyle.OutSet
  1113. })
  1114. .blockColor(this.themeColor)
  1115. .trackColor($r('app.color.speed_text_color'))
  1116. .selectedColor($r('app.color.index_background'))
  1117. .trackThickness(8)
  1118. .onChange((value: number) => {
  1119. this.blurValue = value;
  1120. PreferencesUtil.put(SettingPage.CUSTOMIZE_BG_BLUR, this.blurValue)
  1121. this.sendChangeEvent()
  1122. })
  1123. .layoutWeight(1)
  1124. }
  1125. .height(55)
  1126. }
  1127. .backgroundColor($r('app.color.settings_background_main'))
  1128. .borderRadius(15)
  1129. .margin({
  1130. left: 30,
  1131. right: 30,
  1132. top: 0,
  1133. bottom: 20
  1134. })
  1135. .padding(0)
  1136. Column() {
  1137. Row() {
  1138. Text('背景亮度:')
  1139. .margin({ left: 18 })
  1140. .fontSize(15)
  1141. .fontColor($r('app.color.text_color'))
  1142. .fontWeight(480)
  1143. Slider({
  1144. value: this.bgBrightness,
  1145. min: -0.4,
  1146. max: 0.4,
  1147. step: 0.1,
  1148. style: SliderStyle.OutSet
  1149. })
  1150. .blockColor(this.themeColor)
  1151. .trackColor($r('app.color.speed_text_color'))
  1152. .selectedColor($r('app.color.index_background'))
  1153. .trackThickness(8)
  1154. .onChange((value: number) => {
  1155. this.bgBrightness = value;
  1156. PreferencesUtil.put(SettingPage.BG_BRIGHTNESS, this.bgBrightness)
  1157. this.sendChangeEvent()
  1158. })
  1159. .layoutWeight(1)
  1160. }
  1161. .height(55)
  1162. }
  1163. .backgroundColor($r('app.color.settings_background_main'))
  1164. .borderRadius(15)
  1165. .margin({
  1166. left: 30,
  1167. right: 30,
  1168. top: 0,
  1169. bottom: 20
  1170. })
  1171. .padding(0)
  1172. }
  1173. .margin({ bottom: 30 })
  1174. }
  1175. // 判断当前主题色是否为自定义色
  1176. isCustomThemeColor(): boolean {
  1177. for (let i = 0; i < SettingPage.THEME_COLOR_LIST.length - 1; i++) {
  1178. if (SettingPage.THEME_COLOR_LIST[i].color === this.themeColor) {
  1179. return false;
  1180. }
  1181. }
  1182. return true;
  1183. }
  1184. }
  1185. // 主题色类型声明
  1186. export interface ThemeColorItem {
  1187. name: string;
  1188. color: string;
  1189. }
  1190. // 工具函数:将一维数组分成每行2个的二维数组
  1191. function chunkArray<T>(arr: Array<T>, size: number): Array<Array<T>> {
  1192. const result: Array<Array<T>> = [];
  1193. for (let i = 0; i < arr.length; i += size) {
  1194. const row: Array<T> = [];
  1195. for (let j = 0; j < size; j++) {
  1196. if (i + j < arr.length) {
  1197. row.push(arr[i + j]);
  1198. }
  1199. }
  1200. result.push(row);
  1201. }
  1202. return result;
  1203. }