diff --git a/lib/pages/home_page.dart b/lib/pages/home_page.dart index 5e1584b..66bd148 100644 --- a/lib/pages/home_page.dart +++ b/lib/pages/home_page.dart @@ -208,7 +208,7 @@ class _HomePageState extends BaseState { if (renderBox != null) { final height = renderBox.size.height; if (height > 0 && height != _mediaLibraryHeight) { - setState(() { + safeSetState(() { _mediaLibraryHeight = height; _heightMeasureRetryCount = 0; }); @@ -221,7 +221,7 @@ class _HomePageState extends BaseState { const Duration(milliseconds: 200), _measureMediaLibraryHeight); } else { print('⚠️ 媒体库高度测量失败,使用默认值 280px'); - setState(() { + safeSetState(() { _mediaLibraryHeight = 280.0; }); } @@ -229,18 +229,18 @@ class _HomePageState extends BaseState { } void _onScroll() { - if (mounted) setState(() {}); + if (mounted) safeSetState(() {}); } Future _initWebDAV() async { - setState(() => _isLoading = true); + safeSetState(() => _isLoading = true); try { await WebDAVService.instance.loadCredentials(); _favorites = []; } catch (e) { _favorites = []; } finally { - if (mounted) setState(() => _isLoading = false); + if (mounted) safeSetState(() => _isLoading = false); } } @@ -306,12 +306,13 @@ class _HomePageState extends BaseState { onPressed: () async { Navigator.pop(context); await WebDAVService.instance.clearCredentials(); - setState(() { + safeSetState(() { _favorites = []; _isLoading = false; }); if (mounted) { - Navigator.pushReplacement( + // ⭐ 修复:用 push 保留 HomePage 在栈底 + Navigator.push( context, MaterialPageRoute( builder: (_) => const WebDAVSetupPage(), @@ -333,7 +334,7 @@ class _HomePageState extends BaseState { if (_scrollController.hasClients) { _scrollController.jumpTo(0.0); } - setState(() {}); + safeSetState(() {}); } @override @@ -406,7 +407,7 @@ class _HomePageState extends BaseState { ), ); _resetSnapState(); - setState(() {}); + safeSetState(() {}); } else { final result = await Navigator.push( context, @@ -414,17 +415,18 @@ class _HomePageState extends BaseState { builder: (_) => const WebDAVSetupPage(), ), ); - setState(() {}); + safeSetState(() {}); if (result == true) { await WebDAVService.instance .loadCredentials(); - setState(() {}); + safeSetState(() {}); } } }, child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ + // 左侧云朵图标(固定 56px) const Padding( padding: EdgeInsets.only(left: 8.0), child: Icon( @@ -434,11 +436,14 @@ class _HomePageState extends BaseState { ), ), const SizedBox(width: 16), + // 右侧所有内容 Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, children: [ + // 第一行:WebDAV + 状态 + 退出按钮 Row( children: [ const Text( @@ -460,28 +465,24 @@ class _HomePageState extends BaseState { fontWeight: FontWeight.w400, ), ), - // ⭐ 退出按钮(已连接时显示) - if (isConnected) ...[ - const Spacer(), - IconButton( - icon: const Icon( - Icons.logout, - color: Colors.grey, - size: 18, - ), - tooltip: '重新登录', - onPressed: _showReauthDialog, - padding: EdgeInsets.zero, - constraints: const BoxConstraints( - minWidth: 32, - minHeight: 32, + const Spacer(), + if (isConnected) + Padding( + padding: + const EdgeInsets.only(top: 2), + child: GestureDetector( + onTap: _showReauthDialog, + child: const Icon( + Icons.logout, + color: Colors.grey, + size: 18, + ), ), ), - const SizedBox(width: 4), - ], ], ), const SizedBox(height: 4), + // 第二行:用户名 Text( isConnected ? username : '点击连接', style: TextStyle( @@ -706,7 +707,7 @@ class _HomePageState extends BaseState { size: 20, ), onPressed: () { - setState(() { + safeSetState(() { _favorites.removeAt(index); }); }, diff --git a/lib/pages/webdav_setup_page.dart b/lib/pages/webdav_setup_page.dart index bd14ae5..8c1d29d 100644 --- a/lib/pages/webdav_setup_page.dart +++ b/lib/pages/webdav_setup_page.dart @@ -35,7 +35,7 @@ class _WebDAVSetupPageState extends BaseState { Future _loadSavedCredentials() async { final hasCred = await WebDAVService.instance.loadCredentials(); - setState(() { + safeSetState(() { _isConnected = hasCred; _statusText = hasCred ? '已连接' : '未连接'; if (hasCred) { @@ -47,7 +47,7 @@ class _WebDAVSetupPageState extends BaseState { Future _connect() async { if (!_formKey.currentState!.validate()) return; - setState(() => _isLoading = true); + safeSetState(() => _isLoading = true); try { await WebDAVService.instance.saveCredentials( @@ -59,7 +59,7 @@ class _WebDAVSetupPageState extends BaseState { // 验证连接 await WebDAVService.instance.getMusicFiles(); - setState(() { + safeSetState(() { _isConnected = true; _statusText = '已连接'; _isLoading = false; @@ -72,7 +72,8 @@ class _WebDAVSetupPageState extends BaseState { backgroundColor: Color(0xFF4CAF50), ), ); - // ✅ 登录成功 → 直接跳转到文件列表页 + // ⭐ 用 pushReplacement 替换当前页面(WebDAVSetupPage) + // 此时栈底是 HomePage,替换后栈变为 [HomePage, WebDAVFileListPage] Navigator.pushReplacement( context, MaterialPageRoute( @@ -81,7 +82,7 @@ class _WebDAVSetupPageState extends BaseState { ); } } catch (e) { - setState(() { + safeSetState(() { _isConnected = false; _statusText = '连接失败'; _isLoading = false; @@ -99,7 +100,7 @@ class _WebDAVSetupPageState extends BaseState { Future _disconnect() async { await WebDAVService.instance.clearCredentials(); - setState(() { + safeSetState(() { _isConnected = false; _statusText = '未连接'; });