深色模式代码第二轮补充
This commit is contained in:
+21
-37
@@ -1,16 +1,16 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
import '../theme/app_colors.dart';
|
||||
|
||||
class AboutPage extends StatelessWidget {
|
||||
const AboutPage({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||
final c = context.colors;
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
|
||||
appBar: AppBar(
|
||||
title: const Text(
|
||||
'关于',
|
||||
@@ -19,10 +19,10 @@ class AboutPage extends StatelessWidget {
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
backgroundColor: Colors.transparent,
|
||||
backgroundColor: c.background,
|
||||
elevation: 0,
|
||||
foregroundColor: Theme.of(context).iconTheme.color,
|
||||
iconTheme: IconThemeData(color: Theme.of(context).iconTheme.color),
|
||||
foregroundColor: c.textPrimary,
|
||||
iconTheme: IconThemeData(color: c.textPrimary),
|
||||
),
|
||||
body: Center(
|
||||
child: Padding(
|
||||
@@ -30,15 +30,12 @@ class AboutPage extends StatelessWidget {
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
// Logo
|
||||
Container(
|
||||
width: 120,
|
||||
height: 120,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: isDark
|
||||
? Colors.grey.shade800
|
||||
: const Color(0xFFF0F4F8),
|
||||
color: c.surface,
|
||||
),
|
||||
child: ClipOval(
|
||||
child: Image.asset(
|
||||
@@ -50,38 +47,39 @@ class AboutPage extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
const Text(
|
||||
Text(
|
||||
'MEIZU Battery Healthy',
|
||||
style: TextStyle(
|
||||
fontFamily: 'HarmonyOS_Sans_SC',
|
||||
fontSize: 24,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: c.textPrimary,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
'版本 1.7.0',
|
||||
'版本 1.8.0',
|
||||
style: TextStyle(
|
||||
fontFamily: 'HarmonyOS_Sans_SC',
|
||||
fontSize: 14,
|
||||
color: Colors.grey.shade500,
|
||||
color: c.textTertiary,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Divider(
|
||||
color: Colors.grey.shade300,
|
||||
color: c.divider,
|
||||
thickness: 0.5,
|
||||
indent: 40,
|
||||
endIndent: 40,
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
const Text(
|
||||
Text(
|
||||
'专机专配 · 仅针对魅族独家开发',
|
||||
style: TextStyle(
|
||||
fontFamily: 'HarmonyOS_Sans_SC',
|
||||
fontSize: 14,
|
||||
color: Colors.grey,
|
||||
color: c.textSecondary,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
@@ -90,13 +88,12 @@ class AboutPage extends StatelessWidget {
|
||||
style: TextStyle(
|
||||
fontFamily: 'HarmonyOS_Sans_SC',
|
||||
fontSize: 13,
|
||||
color: Colors.grey.shade400,
|
||||
color: c.textTertiary,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
// 源码链接按钮
|
||||
InkWell(
|
||||
onTap: () => _launchUrl(context), // 注意这里传入了 context
|
||||
onTap: () => _launchUrl(context),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
@@ -104,34 +101,24 @@ class AboutPage extends StatelessWidget {
|
||||
vertical: 12,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: isDark
|
||||
? Colors.grey.shade800
|
||||
: const Color(0xFFF0F4F8),
|
||||
color: c.surface,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.code,
|
||||
size: 18,
|
||||
color: Theme.of(context).iconTheme.color,
|
||||
),
|
||||
Icon(Icons.code, size: 18, color: c.textPrimary),
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
'查看源码 / 反馈',
|
||||
style: TextStyle(
|
||||
fontFamily: 'HarmonyOS_Sans_SC',
|
||||
fontSize: 14,
|
||||
color: Theme.of(context).iconTheme.color,
|
||||
color: c.textPrimary,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
Icon(
|
||||
Icons.open_in_new,
|
||||
size: 14,
|
||||
color: Colors.grey.shade500,
|
||||
),
|
||||
Icon(Icons.open_in_new, size: 14, color: c.textTertiary),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -142,7 +129,7 @@ class AboutPage extends StatelessWidget {
|
||||
style: TextStyle(
|
||||
fontFamily: 'HarmonyOS_Sans_SC',
|
||||
fontSize: 12,
|
||||
color: Colors.grey.shade400,
|
||||
color: c.textTertiary,
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -155,14 +142,11 @@ class AboutPage extends StatelessWidget {
|
||||
Future<void> _launchUrl(BuildContext context) async {
|
||||
const url = 'https://git.whitetop.xyz/lxh2875931338/MEIZU-Battery-Healthy';
|
||||
final uri = Uri.parse(url);
|
||||
|
||||
try {
|
||||
// ✅ 直接尝试打开,不再检查 canLaunchUrl
|
||||
await launchUrl(uri, mode: LaunchMode.externalApplication);
|
||||
} catch (e) {
|
||||
// 如果打开失败,复制链接并提示
|
||||
debugPrint('打开链接失败: $e');
|
||||
await Clipboard.setData(ClipboardData(text: url));
|
||||
await Clipboard.setData(const ClipboardData(text: url));
|
||||
if (context.mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
|
||||
@@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:device_info_plus/device_info_plus.dart';
|
||||
import '../theme/theme_service.dart';
|
||||
import '../theme/app_colors.dart';
|
||||
|
||||
// --- 本地导入 ---
|
||||
import '../models/device_matching.dart';
|
||||
@@ -696,25 +697,25 @@ class _BatteryHealthPageState extends State<BatteryHealthPage> {
|
||||
);
|
||||
|
||||
return AnnotatedRegion<SystemUiOverlayStyle>(
|
||||
value: const SystemUiOverlayStyle(
|
||||
statusBarColor: Color.fromRGBO(157, 212, 237, 0.1),
|
||||
value: SystemUiOverlayStyle(
|
||||
statusBarColor: context.colors.statusBarTint,
|
||||
statusBarIconBrightness: Brightness.dark,
|
||||
statusBarBrightness: Brightness.dark,
|
||||
),
|
||||
child: Scaffold(
|
||||
backgroundColor: Colors.white,
|
||||
// backgroundColor: Colors.white,
|
||||
appBar: AppBar(
|
||||
backgroundColor: Colors.white,
|
||||
// backgroundColor: Colors.white,
|
||||
elevation: 0,
|
||||
scrolledUnderElevation: 0,
|
||||
shadowColor: Colors.transparent,
|
||||
surfaceTintColor: Colors.transparent,
|
||||
title: const Text(
|
||||
title: Text(
|
||||
'电池健康度',
|
||||
style: TextStyle(
|
||||
fontSize: 24,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.black,
|
||||
color: context.colors.textPrimary,
|
||||
),
|
||||
),
|
||||
actions: [
|
||||
@@ -722,11 +723,11 @@ class _BatteryHealthPageState extends State<BatteryHealthPage> {
|
||||
icon: const Icon(Icons.refresh),
|
||||
onPressed: readBatteryCapacity,
|
||||
tooltip: '刷新数据',
|
||||
color: Colors.black,
|
||||
color: context.colors.icon,
|
||||
),
|
||||
PopupMenuButton<String>(
|
||||
icon: const Icon(Icons.more_vert),
|
||||
color: Colors.white,
|
||||
color: context.colors.surface,
|
||||
onSelected: (value) {
|
||||
switch (value) {
|
||||
case 'changelog':
|
||||
@@ -772,9 +773,9 @@ class _BatteryHealthPageState extends State<BatteryHealthPage> {
|
||||
children: [
|
||||
Text(
|
||||
_deviceModel,
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Colors.grey,
|
||||
color: context.colors.textTertiary,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart'; // 🟢 添加这一行
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_markdown/flutter_markdown.dart';
|
||||
import '../theme/app_colors.dart';
|
||||
|
||||
class ChangelogPage extends StatefulWidget {
|
||||
const ChangelogPage({super.key});
|
||||
@@ -15,33 +16,27 @@ class _ChangelogPageState extends State<ChangelogPage>
|
||||
String _markdownContent = '';
|
||||
bool _isLoading = true;
|
||||
String? _error;
|
||||
Widget? _cachedMarkdown;
|
||||
|
||||
// ---------- 滚动 ----------
|
||||
final ScrollController _scrollController = ScrollController();
|
||||
double _scrollProgress = 0.0;
|
||||
bool _isScrolling = false;
|
||||
|
||||
// ---------- 呼吸动画(维持高刷感知) ----------
|
||||
// ---------- 呼吸动画 ----------
|
||||
late AnimationController _breathController;
|
||||
late Animation<double> _breathAnimation;
|
||||
|
||||
// ---------- 原生刷新率控制 ----------
|
||||
// 🟢 改用 static final(不是 const)
|
||||
static final _frameRateChannel = MethodChannel(
|
||||
'com.lxh.battery_health/frame_rate',
|
||||
);
|
||||
|
||||
// ---------- 生命周期 ----------
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_loadChangelog();
|
||||
|
||||
// 进入页面时申请高刷(原生层)
|
||||
_frameRateChannel.invokeMethod('setHighRefreshRate');
|
||||
|
||||
// 呼吸动画:让进度条在滚动时轻微抖动,维持高刷感知
|
||||
_breathController = AnimationController(
|
||||
vsync: this,
|
||||
duration: const Duration(milliseconds: 500),
|
||||
@@ -70,16 +65,13 @@ class _ChangelogPageState extends State<ChangelogPage>
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
// 离开页面时恢复默认刷新率
|
||||
_frameRateChannel.invokeMethod('clearRefreshRate');
|
||||
|
||||
_scrollController.removeListener(_updateProgress);
|
||||
_scrollController.dispose();
|
||||
_breathController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
// ---------- 方法 ----------
|
||||
void _updateProgress() {
|
||||
if (!_scrollController.hasClients) return;
|
||||
final maxScroll = _scrollController.position.maxScrollExtent;
|
||||
@@ -96,7 +88,6 @@ class _ChangelogPageState extends State<ChangelogPage>
|
||||
setState(() {
|
||||
_markdownContent = content;
|
||||
_isLoading = false;
|
||||
_cachedMarkdown = _buildMarkdown(content);
|
||||
});
|
||||
} catch (e) {
|
||||
setState(() {
|
||||
@@ -106,78 +97,75 @@ class _ChangelogPageState extends State<ChangelogPage>
|
||||
}
|
||||
}
|
||||
|
||||
Widget _buildMarkdown(String content) {
|
||||
Widget _buildMarkdown(BuildContext context, String content) {
|
||||
final c = context.colors;
|
||||
return Markdown(
|
||||
data: content,
|
||||
shrinkWrap: true,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
styleSheet: MarkdownStyleSheet(
|
||||
h1: const TextStyle(
|
||||
h1: TextStyle(
|
||||
fontFamily: 'HarmonyOS_Sans_SC',
|
||||
fontSize: 24,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: Colors.black,
|
||||
color: c.textPrimary,
|
||||
),
|
||||
h2: const TextStyle(
|
||||
h2: TextStyle(
|
||||
fontFamily: 'HarmonyOS_Sans_SC',
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.black87,
|
||||
color: c.textPrimary,
|
||||
),
|
||||
h3: const TextStyle(
|
||||
h3: TextStyle(
|
||||
fontFamily: 'HarmonyOS_Sans_SC',
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.black87,
|
||||
color: c.textSecondary,
|
||||
),
|
||||
p: const TextStyle(
|
||||
p: TextStyle(
|
||||
fontFamily: 'HarmonyOS_Sans_SC',
|
||||
fontSize: 16,
|
||||
color: Colors.black87,
|
||||
color: c.textSecondary,
|
||||
),
|
||||
listBullet: const TextStyle(
|
||||
listBullet: TextStyle(
|
||||
fontFamily: 'HarmonyOS_Sans_SC',
|
||||
fontSize: 16,
|
||||
color: Colors.black87,
|
||||
color: c.textSecondary,
|
||||
),
|
||||
code: const TextStyle(
|
||||
code: TextStyle(
|
||||
fontFamily: 'HarmonyOS_Sans_SC',
|
||||
fontSize: 14,
|
||||
color: Colors.black87,
|
||||
backgroundColor: Color(0xFFF5F5F5),
|
||||
color: c.textSecondary,
|
||||
backgroundColor: c.surface,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// ---------- Build ----------
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final c = context.colors;
|
||||
final breathOffset = _isScrolling ? _breathAnimation.value : 0.0;
|
||||
final displayProgress = (_scrollProgress + breathOffset).clamp(0.0, 1.0);
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.white,
|
||||
appBar: AppBar(
|
||||
title: const Text(
|
||||
title: Text(
|
||||
'更新日志',
|
||||
style: TextStyle(
|
||||
fontFamily: 'HarmonyOS_Sans_SC',
|
||||
color: Colors.black,
|
||||
color: c.textPrimary,
|
||||
),
|
||||
),
|
||||
backgroundColor: Colors.white,
|
||||
elevation: 0,
|
||||
foregroundColor: Colors.black,
|
||||
iconTheme: const IconThemeData(color: Colors.black),
|
||||
foregroundColor: c.textPrimary,
|
||||
iconTheme: IconThemeData(color: c.textPrimary),
|
||||
bottom: PreferredSize(
|
||||
preferredSize: const Size.fromHeight(2.0),
|
||||
child: LinearProgressIndicator(
|
||||
value: displayProgress,
|
||||
backgroundColor: Colors.grey.shade200,
|
||||
valueColor: const AlwaysStoppedAnimation<Color>(
|
||||
Color.fromRGBO(157, 212, 237, 1.0),
|
||||
),
|
||||
backgroundColor: c.divider,
|
||||
valueColor: AlwaysStoppedAnimation<Color>(c.progressBar),
|
||||
minHeight: 2.0,
|
||||
),
|
||||
),
|
||||
@@ -188,16 +176,16 @@ class _ChangelogPageState extends State<ChangelogPage>
|
||||
? Center(
|
||||
child: Text(
|
||||
_error!,
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontFamily: 'HarmonyOS_Sans_SC',
|
||||
color: Colors.grey,
|
||||
color: c.textTertiary,
|
||||
),
|
||||
),
|
||||
)
|
||||
: SingleChildScrollView(
|
||||
controller: _scrollController,
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: _cachedMarkdown ?? const SizedBox.shrink(),
|
||||
child: _buildMarkdown(context, _markdownContent),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user