首次提交:关于页、夜间模式选项

This commit is contained in:
2026-07-30 22:24:59 +08:00
parent dac9529f96
commit b6d623a1eb
10 changed files with 430 additions and 94 deletions
+58 -45
View File
@@ -1,12 +1,11 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'pages/battery_health_page.dart'; import 'pages/battery_health_page.dart';
import 'services/saf_storage_service.dart'; import 'services/saf_storage_service.dart';
void main() async { void main() async {
WidgetsFlutterBinding.ensureInitialized(); WidgetsFlutterBinding.ensureInitialized();
await SafStorageService().init(); await SafStorageService().init();
runApp(const MyApp()); runApp(const MyApp());
} }
@@ -17,51 +16,65 @@ class MyApp extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MaterialApp( return MaterialApp(
title: '电池健康度', title: '电池健康度',
theme: ThemeData( theme: _lightTheme(),
// 🟢 中文用 HarmonyOS Sans SC darkTheme: _darkTheme(),
fontFamily: 'HarmonyOS_Sans_SC', themeMode: ThemeMode.system, // 默认跟随系统
// 🟢 数字回退到 FlymeFont
fontFamilyFallback: const ['Flyme'],
// 🟢 统一文字颜色为黑色
colorScheme: ColorScheme.fromSeed(
seedColor: const Color(0xFFFFFFFF),
).copyWith(onSurface: Colors.black),
textTheme: const TextTheme(
// 大标题/数字(健康度、容量等)
displayMedium: TextStyle(
fontFamily: 'HarmonyOS_Sans_SC',
fontFamilyFallback: ['Flyme'],
color: Colors.black,
),
// 标题(如“容量百分比变动趋势”)
headlineMedium: TextStyle(
fontFamily: 'HarmonyOS_Sans_SC',
fontFamilyFallback: ['Flyme'],
color: Colors.black,
),
// 正文(电压、温度、循环次数等)
bodyMedium: TextStyle(
fontFamily: 'HarmonyOS_Sans_SC',
fontFamilyFallback: ['Flyme'],
color: Colors.black,
),
// 小字(日期、辅助信息)
bodySmall: TextStyle(
fontFamily: 'HarmonyOS_Sans_SC',
fontFamilyFallback: ['Flyme'],
color: Colors.black87,
),
// 数字专用(大号数字,如健康度百分比)
displayLarge: TextStyle(
fontFamily: 'HarmonyOS_Sans_SC',
fontFamilyFallback: ['Flyme'],
color: Colors.black,
),
),
useMaterial3: true,
),
home: const BatteryHealthPage(), home: const BatteryHealthPage(),
debugShowCheckedModeBanner: false, debugShowCheckedModeBanner: false,
); );
} }
ThemeData _lightTheme() {
return ThemeData(
fontFamily: 'HarmonyOS_Sans_SC',
fontFamilyFallback: const ['Flyme'],
useMaterial3: true,
brightness: Brightness.light,
scaffoldBackgroundColor: Colors.white,
appBarTheme: const AppBarTheme(
backgroundColor: Colors.white,
foregroundColor: Colors.black,
elevation: 0,
centerTitle: false,
),
iconTheme: const IconThemeData(color: Colors.black),
colorScheme: const ColorScheme.light(
primary: Color(0xFF1A73E8),
secondary: Color(0xFF1A73E8),
),
textTheme: const TextTheme(
bodyLarge: TextStyle(color: Colors.black),
bodyMedium: TextStyle(color: Colors.black87),
labelLarge: TextStyle(color: Colors.black),
),
dividerColor: Colors.grey.shade200,
);
}
ThemeData _darkTheme() {
return ThemeData(
fontFamily: 'HarmonyOS_Sans_SC',
fontFamilyFallback: const ['Flyme'],
useMaterial3: true,
brightness: Brightness.dark,
scaffoldBackgroundColor: const Color(0xFF121212),
appBarTheme: const AppBarTheme(
backgroundColor: Color(0xFF1E1E1E),
foregroundColor: Colors.white,
elevation: 0,
centerTitle: false,
),
iconTheme: const IconThemeData(color: Colors.white),
colorScheme: const ColorScheme.dark(
primary: Color(0xFF4FC3F7),
secondary: Color(0xFF4FC3F7),
),
textTheme: const TextTheme(
bodyLarge: TextStyle(color: Colors.white),
bodyMedium: TextStyle(color: Colors.white70),
labelLarge: TextStyle(color: Colors.white),
),
dividerColor: Colors.grey.shade800,
);
}
} }
+173
View File
@@ -0,0 +1,173 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:url_launcher/url_launcher.dart';
class AboutPage extends StatelessWidget {
const AboutPage({super.key});
@override
Widget build(BuildContext context) {
final isDark = Theme.of(context).brightness == Brightness.dark;
return Scaffold(
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
appBar: AppBar(
title: const Text(
'关于',
style: TextStyle(
fontFamily: 'HarmonyOS_Sans_SC',
fontWeight: FontWeight.w500,
),
),
backgroundColor: Colors.transparent,
elevation: 0,
foregroundColor: Theme.of(context).iconTheme.color,
iconTheme: IconThemeData(color: Theme.of(context).iconTheme.color),
),
body: Center(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 40.0),
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),
),
child: const Icon(
Icons.battery_charging_full,
size: 64,
color: Color(0xFF00B140),
),
),
const SizedBox(height: 24),
// APP 名称
const Text(
'MEIZU Battery Healthy',
style: TextStyle(
fontFamily: 'HarmonyOS_Sans_SC',
fontSize: 24,
fontWeight: FontWeight.w600,
),
),
const SizedBox(height: 8),
// 版本号
Text(
'版本 1.7.0',
style: TextStyle(
fontFamily: 'HarmonyOS_Sans_SC',
fontSize: 14,
color: Colors.grey.shade500,
fontWeight: FontWeight.w400,
),
),
const SizedBox(height: 16),
// 分隔线
Divider(
color: Colors.grey.shade300,
thickness: 0.5,
indent: 40,
endIndent: 40,
),
const SizedBox(height: 16),
// 作者信息
const Text(
'专机专配 · 仅针对魅族独家开发',
style: TextStyle(
fontFamily: 'HarmonyOS_Sans_SC',
fontSize: 14,
color: Colors.grey,
),
),
const SizedBox(height: 8),
Text(
'通过读取 BMS 日志直接获取电池真实数据',
style: TextStyle(
fontFamily: 'HarmonyOS_Sans_SC',
fontSize: 13,
color: Colors.grey.shade400,
),
),
const SizedBox(height: 24),
// Gitea 链接
InkWell(
onTap: _launchUrl,
borderRadius: BorderRadius.circular(12),
child: Container(
padding: const EdgeInsets.symmetric(
horizontal: 20,
vertical: 12,
),
decoration: BoxDecoration(
color: isDark
? Colors.grey.shade800
: const Color(0xFFF0F4F8),
borderRadius: BorderRadius.circular(12),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(
Icons.code,
size: 18,
color: Theme.of(context).iconTheme.color,
),
const SizedBox(width: 8),
Text(
'查看源码 / 反馈',
style: TextStyle(
fontFamily: 'HarmonyOS_Sans_SC',
fontSize: 14,
color: Theme.of(context).iconTheme.color,
),
),
const SizedBox(width: 4),
Icon(
Icons.open_in_new,
size: 14,
color: Colors.grey.shade500,
),
],
),
),
),
const SizedBox(height: 40),
// 底部版本信息
Text(
'Made with ❤️ in Flyme · 2026',
style: TextStyle(
fontFamily: 'HarmonyOS_Sans_SC',
fontSize: 12,
color: Colors.grey.shade400,
),
),
],
),
),
),
);
}
/// 🟢 修复:url_launcher 的正确调用方式
Future<void> _launchUrl() async {
const url = 'https://git.whitetop.xyz/lxh2875931338/MEIZU-Battery-Healthy';
final uri = Uri.parse(url);
try {
if (await canLaunchUrl(uri)) {
await launchUrl(uri, mode: LaunchMode.externalApplication);
} else {
// 降级方案:无法打开链接时的处理
debugPrint('无法打开链接: $url');
}
} catch (e) {
debugPrint('打开链接失败: $e');
}
}
}
+123 -49
View File
@@ -7,7 +7,7 @@ import 'package:device_info_plus/device_info_plus.dart';
// --- 本地导入 --- // --- 本地导入 ---
import '../models/device_matching.dart'; import '../models/device_matching.dart';
import '../models/saf_permission_state.dart'; import '../models/saf_permission_state.dart';
import '../models/data_abnormal_type.dart'; // 🆕 1.7.0 import '../models/data_abnormal_type.dart';
import '../services/database_service.dart'; import '../services/database_service.dart';
import '../services/battery_data_service.dart'; import '../services/battery_data_service.dart';
import '../services/saf_storage_service.dart'; import '../services/saf_storage_service.dart';
@@ -21,6 +21,7 @@ import '../widgets/charge_entry.dart';
import '../widgets/charge_detail_page.dart'; import '../widgets/charge_detail_page.dart';
import '../widgets/trend_chart.dart'; import '../widgets/trend_chart.dart';
import '../pages/changelog_page.dart'; import '../pages/changelog_page.dart';
import '../pages/about_page.dart';
// --- 潘通色定义 --- // --- 潘通色定义 ---
const Color kHealthGreen = Color(0xFF00B140); const Color kHealthGreen = Color(0xFF00B140);
@@ -48,6 +49,9 @@ class _BatteryHealthPageState extends State<BatteryHealthPage> {
double _minVolt = 0; double _minVolt = 0;
bool _hasData = false; bool _hasData = false;
// ---------- 🆕 1.7.0 异常状态标记 ----------
bool _hasAbnormalDataToday = false;
// ---------- 趋势图数据 ---------- // ---------- 趋势图数据 ----------
List<Map<String, dynamic>> _trendData = []; List<Map<String, dynamic>> _trendData = [];
@@ -293,6 +297,9 @@ class _BatteryHealthPageState extends State<BatteryHealthPage> {
Future<void> readBatteryCapacity() async { Future<void> readBatteryCapacity() async {
dev.log('🔴🔴🔴 readBatteryCapacity 被调用了 🔴🔴🔴', name: 'BatteryHealth'); dev.log('🔴🔴🔴 readBatteryCapacity 被调用了 🔴🔴🔴', name: 'BatteryHealth');
// 🟢 每次读取时重置异常标记
_hasAbnormalDataToday = false;
_safState = await _safService.getPermissionState(); _safState = await _safService.getPermissionState();
dev.log('🔵 SAF状态: $_safState', name: 'BatteryHealth'); dev.log('🔵 SAF状态: $_safState', name: 'BatteryHealth');
@@ -364,29 +371,54 @@ class _BatteryHealthPageState extends State<BatteryHealthPage> {
name: 'BatteryHealth', name: 'BatteryHealth',
); );
// 🆕 1.7.0 计算异常比例
final abnormalRatio = _calculateAbnormalRatio(lines, _designCap);
dev.log(
'🔵 异常比例: ${(abnormalRatio * 100).toStringAsFixed(1)}%',
name: 'BatteryHealth',
);
final cap = CapacityExtractor.extractCapacity(lines); final cap = CapacityExtractor.extractCapacity(lines);
int? finalCap; int? finalCap;
if (cap != null) { // 🆕 1.7.0 异常处理逻辑
if (cap != null && abnormalRatio < 0.5) {
// 短时尖刺:走校验
final validatedCap = _validateCapacity(cap, _designCap);
if (validatedCap != null) {
finalCap = validatedCap;
_hasAbnormalDataToday = false;
dev.log('🔵 短时尖刺校验通过: $cap', name: 'BatteryHealth');
} else {
finalCap = null;
_hasAbnormalDataToday = true;
dev.log('⚠️ 短时尖刺,已丢弃: $cap', name: 'BatteryHealth');
}
} else if (cap != null && abnormalRatio >= 0.5) {
// 长期偏离:放行(疑似扩容)
finalCap = cap; finalCap = cap;
dev.log('🔵 从日志提取容量: $cap', name: 'BatteryHealth'); _hasAbnormalDataToday = false;
dev.log(
'🔵 长期偏离(${(abnormalRatio * 100).toStringAsFixed(0)}% 记录 > 115%),疑似扩容电池,已放行: $cap',
name: 'BatteryHealth',
);
} else { } else {
// cap == null,尝试复制前一天
dev.log('🔵 今日无充满记录,尝试复制前一天容量', name: 'BatteryHealth'); dev.log('🔵 今日无充满记录,尝试复制前一天容量', name: 'BatteryHealth');
final recent = await _dbService.queryRecentData(1); final recent = await _dbService.queryRecentData(1);
if (recent.isNotEmpty) { if (recent.isNotEmpty) {
finalCap = recent.first['capacity'] as int; finalCap = recent.first['capacity'] as int;
_hasAbnormalDataToday = false;
dev.log('🔵 复制前一天容量: $finalCap', name: 'BatteryHealth'); dev.log('🔵 复制前一天容量: $finalCap', name: 'BatteryHealth');
} else { } else {
finalCap = null; finalCap = null;
_hasAbnormalDataToday = false;
dev.log('🔵 无历史数据可复制', name: 'BatteryHealth'); dev.log('🔵 无历史数据可复制', name: 'BatteryHealth');
} }
} }
// 🟢 1.7.0 容量有效性校验
final validatedCap = _validateCapacity(finalCap, _designCap);
setState(() { setState(() {
_currentCap = (validatedCap ?? _currentCap).toDouble(); _currentCap = (finalCap ?? _currentCap).toDouble();
_cycleCount = cycle; _cycleCount = cycle;
_batteryTemp = temp; _batteryTemp = temp;
_batteryVolt = volt; _batteryVolt = volt;
@@ -413,17 +445,40 @@ class _BatteryHealthPageState extends State<BatteryHealthPage> {
} }
} }
// ---------- 🆕 1.7.0 统计当天超过 115% 的容量记录占比 ----------
double _calculateAbnormalRatio(List<String> lines, int designCap) {
final capReg = RegExp(r'(?:learned_cap|remaining_cap)=(\d+)');
int totalCount = 0;
int abnormalCount = 0;
for (String line in lines) {
if (!line.contains('tbat=')) continue;
final match = capReg.firstMatch(line);
if (match == null) continue;
final value = int.parse(match.group(1)!);
final capInMah = value > 100000 ? value ~/ 1000 : value;
totalCount++;
if (capInMah > designCap * 1.15) {
abnormalCount++;
}
}
if (totalCount == 0) return 0.0;
return abnormalCount / totalCount;
}
// ---------- 🆕 1.7.0 容量有效性校验 ---------- // ---------- 🆕 1.7.0 容量有效性校验 ----------
int? _validateCapacity(int? capacity, int designCap) { int? _validateCapacity(int? capacity, int designCap) {
if (capacity == null) return null; if (capacity == null) return null;
// 容量必须大于 0
if (capacity <= 0) { if (capacity <= 0) {
dev.log('⚠️ 容量异常:<= 0,已忽略', name: 'BatteryHealth'); dev.log('⚠️ 容量异常:<= 0,已忽略', name: 'BatteryHealth');
return null; return null;
} }
// 容量不能低于设计容量的 60%
if (capacity < designCap * 0.6) { if (capacity < designCap * 0.6) {
dev.log( dev.log(
'⚠️ 容量异常:低于设计容量 60%$capacity < ${designCap * 0.6}),已忽略', '⚠️ 容量异常:低于设计容量 60%$capacity < ${designCap * 0.6}),已忽略',
@@ -432,7 +487,6 @@ class _BatteryHealthPageState extends State<BatteryHealthPage> {
return null; return null;
} }
// 容量不能超过设计容量的 115%
if (capacity > designCap * 1.15) { if (capacity > designCap * 1.15) {
dev.log( dev.log(
'⚠️ 容量异常:高于设计容量 115%($capacity > ${designCap * 1.15}),已忽略', '⚠️ 容量异常:高于设计容量 115%($capacity > ${designCap * 1.15}),已忽略',
@@ -449,12 +503,14 @@ class _BatteryHealthPageState extends State<BatteryHealthPage> {
double currentCap, double currentCap,
int designCap, int designCap,
double voltage, double voltage,
bool hasAbnormalDataToday,
) { ) {
// 容量异常:高于 115% 或低于 60% // 🟢 优先:今天有异常数据被丢弃 → 强制显示红色
if (hasAbnormalDataToday) return DataAbnormalType.capacityTooHigh;
// 其次:当前值异常
if (currentCap > designCap * 1.15) return DataAbnormalType.capacityTooHigh; if (currentCap > designCap * 1.15) return DataAbnormalType.capacityTooHigh;
if (currentCap < designCap * 0.6) return DataAbnormalType.capacityTooLow; if (currentCap < designCap * 0.6) return DataAbnormalType.capacityTooLow;
// 电压异常:低于 3.0V 或高于 5.0V
if (voltage < 3.0 || voltage > 5.0) return DataAbnormalType.voltageAbnormal; if (voltage < 3.0 || voltage > 5.0) return DataAbnormalType.voltageAbnormal;
return DataAbnormalType.none; return DataAbnormalType.none;
@@ -611,6 +667,8 @@ class _BatteryHealthPageState extends State<BatteryHealthPage> {
// ---------- Build ---------- // ---------- Build ----------
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final isDark = Theme.of(context).brightness == Brightness.dark;
final double healthPercent = (_designCap > 0) final double healthPercent = (_designCap > 0)
? (_currentCap / _designCap) * 100 ? (_currentCap / _designCap) * 100
: 0.0; : 0.0;
@@ -619,45 +677,52 @@ class _BatteryHealthPageState extends State<BatteryHealthPage> {
? '充电中 · ${_getChargeTypeLabel()} · ${_getDisplayPower()}' ? '充电中 · ${_getChargeTypeLabel()} · ${_getDisplayPower()}'
: ''; : '';
// 🆕 1.7.0 异常检测
final abnormalType = _checkAbnormalType( final abnormalType = _checkAbnormalType(
_currentCap, _currentCap,
_designCap, _designCap,
_batteryVolt, _batteryVolt,
_hasAbnormalDataToday,
); );
return AnnotatedRegion<SystemUiOverlayStyle>( return AnnotatedRegion<SystemUiOverlayStyle>(
value: const SystemUiOverlayStyle( value: SystemUiOverlayStyle(
statusBarColor: Color.fromRGBO(157, 212, 237, 0.1), statusBarColor: isDark
statusBarIconBrightness: Brightness.dark, ? const Color(0xFF1E1E1E)
statusBarBrightness: Brightness.dark, : const Color.fromRGBO(157, 212, 237, 0.1),
statusBarIconBrightness: isDark ? Brightness.light : Brightness.dark,
statusBarBrightness: isDark ? Brightness.light : Brightness.dark,
), ),
child: Scaffold( child: Scaffold(
backgroundColor: Colors.white, backgroundColor: Theme.of(context).scaffoldBackgroundColor,
appBar: AppBar( appBar: AppBar(
backgroundColor: Colors.white, backgroundColor: Theme.of(context).appBarTheme.backgroundColor,
elevation: 0, elevation: 0,
scrolledUnderElevation: 0, scrolledUnderElevation: 0,
shadowColor: Colors.transparent, shadowColor: Colors.transparent,
surfaceTintColor: Colors.transparent, surfaceTintColor: Colors.transparent,
title: const Text( title: Text(
'电池健康度', '电池健康度',
style: TextStyle( style: TextStyle(
fontSize: 24, fontSize: 24,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
color: Colors.black, color: isDark ? Colors.white : Colors.black,
), ),
), ),
actions: [ actions: [
IconButton( IconButton(
icon: const Icon(Icons.refresh), icon: Icon(
Icons.refresh,
color: isDark ? Colors.white : Colors.black,
),
onPressed: readBatteryCapacity, onPressed: readBatteryCapacity,
tooltip: '刷新数据', tooltip: '刷新数据',
color: Colors.black,
), ),
PopupMenuButton<String>( PopupMenuButton<String>(
icon: const Icon(Icons.more_vert), icon: Icon(
color: Colors.white, Icons.more_vert,
color: isDark ? Colors.white : Colors.black,
),
color: isDark ? const Color(0xFF2C2C2C) : Colors.white,
onSelected: (value) { onSelected: (value) {
switch (value) { switch (value) {
case 'changelog': case 'changelog':
@@ -668,24 +733,23 @@ class _BatteryHealthPageState extends State<BatteryHealthPage> {
), ),
); );
break; break;
case 'dark_mode':
break;
case 'about': case 'about':
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const AboutPage(),
),
);
break;
case 'dark_mode':
// 夜间模式切换逻辑(需要全局状态管理)
break; break;
} }
}, },
itemBuilder: (context) => [ itemBuilder: (context) => [
const PopupMenuItem(value: 'changelog', child: Text('更新日志')), const PopupMenuItem(value: 'changelog', child: Text('更新日志')),
const PopupMenuItem( const PopupMenuItem(value: 'dark_mode', child: Text('夜间模式')),
value: 'dark_mode', const PopupMenuItem(value: 'about', child: Text('关于')),
enabled: false,
child: Text('深色模式(开发中)'),
),
const PopupMenuItem(
value: 'about',
enabled: false,
child: Text('关于(开发中)'),
),
], ],
), ),
], ],
@@ -701,22 +765,23 @@ class _BatteryHealthPageState extends State<BatteryHealthPage> {
children: [ children: [
Text( Text(
_deviceModel, _deviceModel,
style: const TextStyle( style: TextStyle(
fontSize: 14, fontSize: 14,
color: Colors.grey, color: isDark
? Colors.grey.shade400
: Colors.grey,
fontWeight: FontWeight.w400, fontWeight: FontWeight.w400,
), ),
), ),
const SizedBox(height: 4), const SizedBox(height: 4),
// 🟢 BatterySummary(带异常检测)
RepaintBoundary( RepaintBoundary(
child: BatterySummary( child: BatterySummary(
healthPercent: healthPercent, healthPercent: healthPercent,
cycleCount: _cycleCount, cycleCount: _cycleCount,
currentCap: _currentCap, currentCap: _currentCap,
designCap: _designCap, designCap: _designCap,
abnormalType: abnormalType, // 🆕 1.7.0 abnormalType: abnormalType,
), ),
), ),
@@ -761,7 +826,6 @@ class _BatteryHealthPageState extends State<BatteryHealthPage> {
const SizedBox(height: 4), const SizedBox(height: 4),
// 🟢 BatteryInfoPanel(带异常检测)
RepaintBoundary( RepaintBoundary(
child: BatteryInfoPanel( child: BatteryInfoPanel(
batteryVolt: _batteryVolt, batteryVolt: _batteryVolt,
@@ -770,7 +834,7 @@ class _BatteryHealthPageState extends State<BatteryHealthPage> {
minVolt: _minVolt, minVolt: _minVolt,
maxTemp: _maxTemp, maxTemp: _maxTemp,
minTemp: _minTemp, minTemp: _minTemp,
abnormalType: abnormalType, // 🆕 1.7.0 abnormalType: abnormalType,
), ),
), ),
], ],
@@ -779,19 +843,29 @@ class _BatteryHealthPageState extends State<BatteryHealthPage> {
), ),
], ],
) )
: const Center( : Center(
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Icon(Icons.battery_unknown, size: 64, color: Colors.grey), Icon(
SizedBox(height: 16), Icons.battery_unknown,
size: 64,
color: isDark ? Colors.grey.shade600 : Colors.grey,
),
const SizedBox(height: 16),
Text( Text(
'暂无数据', '暂无数据',
style: TextStyle(fontSize: 18, color: Colors.grey), style: TextStyle(
fontSize: 18,
color: isDark ? Colors.grey.shade400 : Colors.grey,
),
), ),
Text( Text(
'点击右上角刷新尝试', '点击右上角刷新尝试',
style: TextStyle(fontSize: 14, color: Colors.grey), style: TextStyle(
fontSize: 14,
color: isDark ? Colors.grey.shade500 : Colors.grey,
),
), ),
], ],
), ),
@@ -6,6 +6,10 @@
#include "generated_plugin_registrant.h" #include "generated_plugin_registrant.h"
#include <url_launcher_linux/url_launcher_plugin.h>
void fl_register_plugins(FlPluginRegistry* registry) { void fl_register_plugins(FlPluginRegistry* registry) {
g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);
} }
+1
View File
@@ -3,6 +3,7 @@
# #
list(APPEND FLUTTER_PLUGIN_LIST list(APPEND FLUTTER_PLUGIN_LIST
url_launcher_linux
) )
list(APPEND FLUTTER_FFI_PLUGIN_LIST list(APPEND FLUTTER_FFI_PLUGIN_LIST
@@ -8,9 +8,11 @@ import Foundation
import device_info_plus import device_info_plus
import shared_preferences_foundation import shared_preferences_foundation
import sqflite_darwin import sqflite_darwin
import url_launcher_macos
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin")) DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin")) SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
} }
+64
View File
@@ -597,6 +597,70 @@ packages:
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.4.0" version: "1.4.0"
url_launcher:
dependency: "direct main"
description:
name: url_launcher
sha256: f6a7e5c4835bb4e3026a04793a4199ca2d14c739ec378fdfe23fc8075d0439f8
url: "https://pub.flutter-io.cn"
source: hosted
version: "6.3.2"
url_launcher_android:
dependency: transitive
description:
name: url_launcher_android
sha256: b413d49b73867ac08dd2f9890efd3cc11f2a0e577618d50843440a1fb3776c32
url: "https://pub.flutter-io.cn"
source: hosted
version: "6.3.32"
url_launcher_ios:
dependency: transitive
description:
name: url_launcher_ios
sha256: "580fe5dfb51671ae38191d316e027f6b76272b026370708c2d898799750a02b0"
url: "https://pub.flutter-io.cn"
source: hosted
version: "6.4.1"
url_launcher_linux:
dependency: transitive
description:
name: url_launcher_linux
sha256: d5e14138b3bc193a0f63c10a53c94b91d399df0512b1f29b94a043db7482384a
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.2.2"
url_launcher_macos:
dependency: transitive
description:
name: url_launcher_macos
sha256: "368adf46f71ad3c21b8f06614adb38346f193f3a59ba8fe9a2fd74133070ba18"
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.2.5"
url_launcher_platform_interface:
dependency: transitive
description:
name: url_launcher_platform_interface
sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.3.2"
url_launcher_web:
dependency: transitive
description:
name: url_launcher_web
sha256: "85c81589622fbc87c1c683aaea164d3604a7777495a79d91e39ffcdec39ddb34"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.4.3"
url_launcher_windows:
dependency: transitive
description:
name: url_launcher_windows
sha256: "712c70ab1b99744ff066053cbe3e80c73332b38d46e5e945c98689b2e66fc15f"
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.1.5"
vector_graphics: vector_graphics:
dependency: transitive dependency: transitive
description: description:
+1
View File
@@ -39,6 +39,7 @@ dependencies:
flutter_svg: ^2.0.10+1 flutter_svg: ^2.0.10+1
shared_preferences: ^2.2.0 shared_preferences: ^2.2.0
flutter_markdown: ^0.7.0 flutter_markdown: ^0.7.0
url_launcher: ^6.3.0
# The following adds the Cupertino Icons font to your application. # The following adds the Cupertino Icons font to your application.
@@ -7,8 +7,11 @@
#include "generated_plugin_registrant.h" #include "generated_plugin_registrant.h"
#include <permission_handler_windows/permission_handler_windows_plugin.h> #include <permission_handler_windows/permission_handler_windows_plugin.h>
#include <url_launcher_windows/url_launcher_windows.h>
void RegisterPlugins(flutter::PluginRegistry* registry) { void RegisterPlugins(flutter::PluginRegistry* registry) {
PermissionHandlerWindowsPluginRegisterWithRegistrar( PermissionHandlerWindowsPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin")); registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin"));
UrlLauncherWindowsRegisterWithRegistrar(
registry->GetRegistrarForPlugin("UrlLauncherWindows"));
} }
+1
View File
@@ -4,6 +4,7 @@
list(APPEND FLUTTER_PLUGIN_LIST list(APPEND FLUTTER_PLUGIN_LIST
permission_handler_windows permission_handler_windows
url_launcher_windows
) )
list(APPEND FLUTTER_FFI_PLUGIN_LIST list(APPEND FLUTTER_FFI_PLUGIN_LIST