108 lines
3.1 KiB
Dart
Executable File
108 lines
3.1 KiB
Dart
Executable File
import 'package:flutter/material.dart';
|
|
import 'package:flutter_sdk/starcloud_flutter_sdk.dart';
|
|
|
|
import 'l10n.dart';
|
|
import 'tabs/auth_tab.dart';
|
|
import 'tabs/device_scan_tab.dart';
|
|
import 'tabs/lock_control_tab.dart';
|
|
import 'tabs/video_talk_tab.dart';
|
|
import 'tabs/wifi_config_tab.dart';
|
|
|
|
Future<void> main() async {
|
|
WidgetsFlutterBinding.ensureInitialized();
|
|
await S.loadLanguagePreference();
|
|
StarCloudClient.bootstrap();
|
|
runApp(const MyApp());
|
|
}
|
|
|
|
class MyApp extends StatefulWidget {
|
|
const MyApp({super.key});
|
|
|
|
@override
|
|
State<MyApp> createState() => _MyAppState();
|
|
}
|
|
|
|
class _MyAppState extends State<MyApp> {
|
|
Future<void> _toggleLanguage() async {
|
|
// 切换 ValueNotifier 的值,这会触发下方的 ValueListenableBuilder
|
|
await S.setLanguagePreference(!S.isEn);
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return ValueListenableBuilder<bool>(
|
|
valueListenable: S.langNotifier,
|
|
builder: (context, isEn, _) {
|
|
return MaterialApp(
|
|
// 关键:使用 ValueKey 强制整个 App 在语言切换时重新构建,确保所有 S.xxx 文字刷新
|
|
key: ValueKey(isEn),
|
|
title: S.title,
|
|
debugShowCheckedModeBanner: false,
|
|
theme: ThemeData(
|
|
colorScheme:
|
|
ColorScheme.fromSeed(seedColor: const Color(0xFF0066CC)),
|
|
useMaterial3: true,
|
|
),
|
|
home: MainScreen(onToggleLang: _toggleLanguage),
|
|
);
|
|
},
|
|
);
|
|
}
|
|
}
|
|
|
|
class MainScreen extends StatefulWidget {
|
|
final VoidCallback onToggleLang;
|
|
const MainScreen({super.key, required this.onToggleLang});
|
|
|
|
@override
|
|
State<MainScreen> createState() => _MainScreenState();
|
|
}
|
|
|
|
class _MainScreenState extends State<MainScreen> {
|
|
int _currentIndex = 0;
|
|
|
|
final _tabs = [
|
|
const AuthTab(),
|
|
const DeviceScanTab(),
|
|
const LockControlTab(),
|
|
const WifiConfigTab(),
|
|
const VideoTalkTab(),
|
|
];
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
appBar: AppBar(
|
|
title: Text(S.title),
|
|
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
|
|
actions: [
|
|
TextButton.icon(
|
|
onPressed: widget.onToggleLang,
|
|
icon: const Icon(Icons.language),
|
|
label: Text(S.isEn ? '中文' : 'EN'),
|
|
)
|
|
],
|
|
),
|
|
body: IndexedStack(
|
|
index: _currentIndex,
|
|
children: _tabs,
|
|
),
|
|
bottomNavigationBar: NavigationBar(
|
|
selectedIndex: _currentIndex,
|
|
onDestinationSelected: (index) => setState(() => _currentIndex = index),
|
|
destinations: [
|
|
NavigationDestination(
|
|
icon: const Icon(Icons.settings), label: S.tabInit),
|
|
NavigationDestination(
|
|
icon: const Icon(Icons.bluetooth_searching), label: S.tabScan),
|
|
NavigationDestination(
|
|
icon: const Icon(Icons.lock_outline), label: S.tabLock),
|
|
NavigationDestination(icon: const Icon(Icons.wifi), label: S.tabWifi),
|
|
NavigationDestination(
|
|
icon: const Icon(Icons.videocam), label: S.tabTalk),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|