diff --git a/lib/main.dart b/lib/main.dart index 244a702..93b2c19 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,4 +1,12 @@ -import 'package:flutter/material.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/scheduler.dart'; +import 'package:get/get.dart'; + +import 'page/home_page.dart'; +import 'page/login_page.dart'; +import 'page/register_page.dart'; +import 'page/splash_page.dart'; + void main() { runApp(const MyApp()); @@ -7,116 +15,21 @@ void main() { class MyApp extends StatelessWidget { const MyApp({super.key}); - // This widget is the root of your application. @override Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - theme: ThemeData( - // This is the theme of your application. - // - // TRY THIS: Try running your application with "flutter run". You'll see - // the application has a purple toolbar. Then, without quitting the app, - // try changing the seedColor in the colorScheme below to Colors.green - // and then invoke "hot reload" (save your changes or press the "hot - // reload" button in a Flutter-supported IDE, or press "r" if you used - // the command line to start the app). - // - // Notice that the counter didn't reset back to zero; the application - // state is not lost during the reload. To reset the state, use hot - // restart instead. - // - // This works for code too, not just values: Most code changes can be - // tested with just a hot reload. - colorScheme: .fromSeed(seedColor: Colors.deepPurple), - ), - home: const MyHomePage(title: 'Flutter Demo Home Page'), - ); - } -} - -class MyHomePage extends StatefulWidget { - const MyHomePage({super.key, required this.title}); - - // This widget is the home page of your application. It is stateful, meaning - // that it has a State object (defined below) that contains fields that affect - // how it looks. - - // This class is the configuration for the state. It holds the values (in this - // case the title) provided by the parent (in this case the App widget) and - // used by the build method of the State. Fields in a Widget subclass are - // always marked "final". - - final String title; - - @override - State createState() => _MyHomePageState(); -} - -class _MyHomePageState extends State { - int _counter = 0; - - void _incrementCounter() { - setState(() { - // This call to setState tells the Flutter framework that something has - // changed in this State, which causes it to rerun the build method below - // so that the display can reflect the updated values. If we changed - // _counter without calling setState(), then the build method would not be - // called again, and so nothing would appear to happen. - _counter++; - }); - } - - @override - Widget build(BuildContext context) { - // This method is rerun every time setState is called, for instance as done - // by the _incrementCounter method above. - // - // The Flutter framework has been optimized to make rerunning build methods - // fast, so that you can just rebuild anything that needs updating rather - // than having to individually change instances of widgets. - return Scaffold( - appBar: AppBar( - // TRY THIS: Try changing the color here to a specific color (to - // Colors.amber, perhaps?) and trigger a hot reload to see the AppBar - // change color while the other colors stay the same. - backgroundColor: Theme.of(context).colorScheme.inversePrimary, - // Here we take the value from the MyHomePage object that was created by - // the App.build method, and use it to set our appbar title. - title: Text(widget.title), - ), - body: Center( - // Center is a layout widget. It takes a single child and positions it - // in the middle of the parent. - child: Column( - // Column is also a layout widget. It takes a list of children and - // arranges them vertically. By default, it sizes itself to fit its - // children horizontally, and tries to be as tall as its parent. - // - // Column has various properties to control how it sizes itself and - // how it positions its children. Here we use mainAxisAlignment to - // center the children vertically; the main axis here is the vertical - // axis because Columns are vertical (the cross axis would be - // horizontal). - // - // TRY THIS: Invoke "debug painting" (choose the "Toggle Debug Paint" - // action in the IDE, or press "p" in the console), to see the - // wireframe for each widget. - mainAxisAlignment: .center, - children: [ - const Text('You have pushed the button this many times:'), - Text( - '$_counter', - style: Theme.of(context).textTheme.headlineMedium, - ), - ], - ), - ), - floatingActionButton: FloatingActionButton( - onPressed: _incrementCounter, - tooltip: 'Increment', - child: const Icon(Icons.add), + return GetCupertinoApp( + title: 'Family Care', + theme: CupertinoThemeData( + primaryColor: CupertinoColors.systemBlue, + scaffoldBackgroundColor: CupertinoColors.systemGroupedBackground, ), + home: const SplashScreen(), + getPages: [ + GetPage(name: '/splash', page: () => const SplashScreen()), + GetPage(name: '/login', page: () => const LoginPage()), + GetPage(name: '/home', page: () => const MyHomePage()), + GetPage(name: '/register', page: () => const RegisterPage()), + ], ); } } diff --git a/lib/page/home_page.dart b/lib/page/home_page.dart new file mode 100644 index 0000000..8a4aef7 --- /dev/null +++ b/lib/page/home_page.dart @@ -0,0 +1,147 @@ +import 'package:flutter/cupertino.dart'; + +class MyHomePage extends StatefulWidget { + const MyHomePage({super.key}); + + @override + State createState() => _MyHomePageState(); + +} + +class _MyHomePageState extends State { + int _currentIndex = 0; + late PageController _pageController; + + @override + void initState() { + super.initState(); + _pageController = PageController(initialPage: _currentIndex); + } + + @override + void dispose() { + _pageController.dispose(); + super.dispose(); + } + + void _onTabTapped(int index) { + setState(() { + _currentIndex = index; + }); + _pageController.animateToPage( + index, + duration: const Duration(milliseconds: 300), + curve: Curves.easeInOut, + ); + } + + void _onPageChanged(int index) { + setState(() { + _currentIndex = index; + }); + } + + @override + Widget build(BuildContext context) { + return CupertinoPageScaffold( + child: Column( + children: [ + Expanded( + child: PageView( + controller: _pageController, + onPageChanged: _onPageChanged, + children: [ + _buildFirstPage(), + _buildSecondPage(), + _buildThirdPage(), + ], + ), + ), + _buildBottomNavigationBar(), + ], + ), + ); + } + + Widget _buildFirstPage() { + return Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon(CupertinoIcons.home, size: 64, color: CupertinoColors.activeBlue), + const SizedBox(height: 16), + const Text( + '首页', + style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold), + ), + const SizedBox(height: 8), + const Text('这是第一个页面'), + ], + ), + ); + } + + Widget _buildSecondPage() { + return Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon(CupertinoIcons.chat_bubble_2, size: 64, color: CupertinoColors.activeGreen), + const SizedBox(height: 16), + const Text( + '消息', + style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold), + ), + const SizedBox(height: 8), + const Text('这是第二个页面'), + ], + ), + ); + } + + Widget _buildThirdPage() { + return Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon(CupertinoIcons.person, size: 64, color: CupertinoColors.systemPurple), + const SizedBox(height: 16), + const Text( + '我的', + style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold), + ), + const SizedBox(height: 8), + const Text('这是第三个页面'), + ], + ), + ); + } + + Widget _buildBottomNavigationBar() { + return Container( + decoration: BoxDecoration( + border: Border( + top: BorderSide(color: CupertinoColors.separator, width: 0.5), + ), + ), + child: CupertinoTabBar( + currentIndex: _currentIndex, + onTap: _onTabTapped, + items: const [ + BottomNavigationBarItem( + icon: Icon(CupertinoIcons.home), + label: '首页', + ), + BottomNavigationBarItem( + icon: Icon(CupertinoIcons.chat_bubble_2), + label: '消息', + ), + BottomNavigationBarItem( + icon: Icon(CupertinoIcons.person), + label: '我的', + ), + ], + ), + ); + } +} diff --git a/lib/page/login_page.dart b/lib/page/login_page.dart new file mode 100644 index 0000000..94c8e80 --- /dev/null +++ b/lib/page/login_page.dart @@ -0,0 +1,291 @@ +import 'package:flutter/cupertino.dart'; +import 'package:get/get.dart'; + +class LoginPage extends StatefulWidget { + const LoginPage({super.key}); + + @override + State createState() => _LoginPageState(); +} + +class _LoginPageState extends State { + final _formKey = GlobalKey(); + final _usernameController = TextEditingController(); + final _passwordController = TextEditingController(); + final _phoneController = TextEditingController(); + final _smsCodeController = TextEditingController(); + bool _isLoading = false; + bool _isSmsLogin = false; + bool _isCountdownRunning = false; + int _countdownSeconds = 0; + + @override + void dispose() { + _usernameController.dispose(); + _passwordController.dispose(); + _phoneController.dispose(); + _smsCodeController.dispose(); + super.dispose(); + } + + Future _handleLogin() async { + if (!_formKey.currentState!.validate()) { + return; + } + + setState(() { + _isLoading = true; + }); + + await Future.delayed(const Duration(seconds: 1)); + + setState(() { + _isLoading = false; + }); + + if (mounted) { + Get.offAllNamed('/home'); + } + } + + Future _sendSmsCode() async { + if (_phoneController.text.isEmpty) { + showCupertinoDialog( + context: context, + builder: (context) => CupertinoAlertDialog( + title: const Text('提示'), + content: const Text('请先输入手机号'), + actions: [ + CupertinoDialogAction( + child: const Text('确定'), + onPressed: () => Navigator.pop(context), + ), + ], + ), + ); + return; + } + + setState(() { + _isCountdownRunning = true; + _countdownSeconds = 60; + }); + + await Future.delayed(const Duration(seconds: 1)); + + while (_countdownSeconds > 0 && mounted) { + await Future.delayed(const Duration(seconds: 1)); + setState(() { + _countdownSeconds--; + }); + } + + if (mounted) { + setState(() { + _isCountdownRunning = false; + }); + } + } + + @override + Widget build(BuildContext context) { + return CupertinoPageScaffold( + navigationBar: const CupertinoNavigationBar( + middle: Text('登录'), + ), + child: SafeArea( + child: Padding( + padding: const EdgeInsets.all(24.0), + child: Form( + key: _formKey, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + const Icon( + CupertinoIcons.person_3, + size: 80, + color: CupertinoColors.activeBlue, + ), + const SizedBox(height: 32), + const Text( + '欢迎回来', + style: TextStyle( + fontSize: 28, + fontWeight: FontWeight.bold, + ), + textAlign: TextAlign.center, + ), + const SizedBox(height: 8), + Text( + _isSmsLogin ? '使用手机号验证码登录' : '请登录您的账户', + style: TextStyle( + fontSize: 16, + color: CupertinoColors.inactiveGray, + ), + textAlign: TextAlign.center, + ), + const SizedBox(height: 48), + CupertinoSlidingSegmentedControl( + groupValue: _isSmsLogin, + onValueChanged: (value) { + if (value != null) { + setState(() { + _isSmsLogin = value; + }); + } + }, + children: const { + false: Padding( + padding: EdgeInsets.symmetric(horizontal: 16), + child: Text('密码登录'), + ), + true: Padding( + padding: EdgeInsets.symmetric(horizontal: 16), + child: Text('短信登录'), + ), + }, + ), + const SizedBox(height: 24), + if (!_isSmsLogin) ...[ + CupertinoFormSection.insetGrouped( + children: [ + CupertinoTextFormFieldRow( + controller: _usernameController, + prefix: const Padding( + padding: EdgeInsets.only(left: 8), + child: Icon(CupertinoIcons.person, size: 20), + ), + placeholder: '请输入用户名', + validator: (value) { + if (value == null || value.isEmpty) { + return '请输入用户名'; + } + return null; + }, + ), + ], + ), + const SizedBox(height: 16), + CupertinoFormSection.insetGrouped( + children: [ + CupertinoTextFormFieldRow( + controller: _passwordController, + obscureText: true, + prefix: const Padding( + padding: EdgeInsets.only(left: 8), + child: Icon(CupertinoIcons.lock, size: 20), + ), + placeholder: '请输入密码', + validator: (value) { + if (value == null || value.isEmpty) { + return '请输入密码'; + } + if (value.length < 6) { + return '密码至少6位'; + } + return null; + }, + ), + ], + ), + ] else ...[ + CupertinoFormSection.insetGrouped( + children: [ + CupertinoTextFormFieldRow( + controller: _phoneController, + keyboardType: TextInputType.phone, + prefix: const Padding( + padding: EdgeInsets.only(left: 8), + child: Icon(CupertinoIcons.phone, size: 20), + ), + placeholder: '请输入手机号', + validator: (value) { + if (value == null || value.isEmpty) { + return '请输入手机号'; + } + if (value.length != 11) { + return '请输入有效的手机号'; + } + return null; + }, + ), + ], + ), + const SizedBox(height: 16), + Row( + children: [ + Expanded( + child: CupertinoFormSection.insetGrouped( + children: [ + CupertinoTextFormFieldRow( + controller: _smsCodeController, + keyboardType: TextInputType.number, + prefix: const Padding( + padding: EdgeInsets.only(left: 8), + child: Icon(CupertinoIcons.shield, size: 20), + ), + placeholder: '请输入验证码', + validator: (value) { + if (value == null || value.isEmpty) { + return '请输入验证码'; + } + if (value.length != 6) { + return '验证码为6位'; + } + return null; + }, + ), + ], + ), + ), + const SizedBox(width: 12), + SizedBox( + width: 120, + height: 50, + child: CupertinoButton.filled( + onPressed: _isCountdownRunning ? null : _sendSmsCode, + borderRadius: BorderRadius.circular(12), + padding: EdgeInsets.zero, + child: Text( + _isCountdownRunning ? '${_countdownSeconds}s' : '获取验证码', + style: const TextStyle(fontSize: 14), + ), + ), + ), + ], + ), + ], + const SizedBox(height: 32), + CupertinoButton.filled( + onPressed: _isLoading ? null : _handleLogin, + padding: const EdgeInsets.symmetric(vertical: 14), + borderRadius: BorderRadius.circular(12), + child: _isLoading + ? const SizedBox( + height: 20, + width: 20, + child: CupertinoActivityIndicator( + radius: 10, + ), + ) + : Text( + _isSmsLogin ? '验证码登录' : '登录', + style: const TextStyle(fontSize: 17), + ), + ), + const SizedBox(height: 16), + CupertinoButton( + onPressed: () { + Get.offAndToNamed('/register'); + }, + child: const Text('还没有账户?立即注册'), + ), + ], + ), + ), + ), + ), + ); + } +} diff --git a/lib/page/register_page.dart b/lib/page/register_page.dart new file mode 100644 index 0000000..fb7daf1 --- /dev/null +++ b/lib/page/register_page.dart @@ -0,0 +1,388 @@ +import 'package:flutter/cupertino.dart'; +import 'package:get/get.dart'; + +class RegisterPage extends StatefulWidget { + const RegisterPage({super.key}); + + @override + State createState() => _RegisterPageState(); +} + +class _RegisterPageState extends State { + final _formKey = GlobalKey(); + final _phoneController = TextEditingController(); + final _smsCodeController = TextEditingController(); + final _passwordController = TextEditingController(); + final _confirmPasswordController = TextEditingController(); + bool _isLoading = false; + bool _isCountdownRunning = false; + int _countdownSeconds = 0; + bool _obscurePassword = true; + bool _obscureConfirmPassword = true; + + @override + void dispose() { + _phoneController.dispose(); + _smsCodeController.dispose(); + _passwordController.dispose(); + _confirmPasswordController.dispose(); + super.dispose(); + } + + Future _sendSmsCode() async { + if (_phoneController.text.isEmpty) { + showCupertinoDialog( + context: context, + builder: (context) => CupertinoAlertDialog( + title: const Text('提示'), + content: const Text('请先输入手机号'), + actions: [ + CupertinoDialogAction( + child: const Text('确定'), + onPressed: () => Navigator.pop(context), + ), + ], + ), + ); + return; + } + + setState(() { + _isCountdownRunning = true; + _countdownSeconds = 60; + }); + + await Future.delayed(const Duration(seconds: 1)); + + while (_countdownSeconds > 0 && mounted) { + await Future.delayed(const Duration(seconds: 1)); + setState(() { + _countdownSeconds--; + }); + } + + if (mounted) { + setState(() { + _isCountdownRunning = false; + }); + } + + if (mounted) { + showCupertinoDialog( + context: context, + builder: (context) => CupertinoAlertDialog( + title: const Text('验证码已发送'), + content: const Text('请输入收到的6位验证码'), + actions: [ + CupertinoDialogAction( + child: const Text('确定'), + onPressed: () => Navigator.pop(context), + ), + ], + ), + ); + } + } + + Future _handleRegister() async { + if (!_formKey.currentState!.validate()) { + return; + } + + setState(() { + _isLoading = true; + }); + + await Future.delayed(const Duration(seconds: 1)); + + setState(() { + _isLoading = false; + }); + + if (mounted) { + showCupertinoDialog( + context: context, + builder: (context) => CupertinoAlertDialog( + title: const Text('注册成功'), + content: const Text('欢迎加入!'), + actions: [ + CupertinoDialogAction( + isDefaultAction: true, + child: const Text('确定'), + onPressed: () { + Navigator.pop(context); + Navigator.pop(context); + }, + ), + ], + ), + ); + } + } + + @override + Widget build(BuildContext context) { + return CupertinoPageScaffold( + navigationBar: CupertinoNavigationBar( + middle: const Text('注册'), + trailing: CupertinoButton( + padding: EdgeInsets.zero, + onPressed: () { + Get.offAndToNamed('/login'); + }, + child: const Text('取消'), + ), + ), + child: SafeArea( + child: SingleChildScrollView( + padding: const EdgeInsets.all(24.0), + child: Form( + key: _formKey, + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + const SizedBox(height: 32), + const Icon( + CupertinoIcons.person_2_fill, + size: 80, + color: CupertinoColors.activeGreen, + ), + const SizedBox(height: 24), + const Text( + '创建新账户', + style: TextStyle( + fontSize: 28, + fontWeight: FontWeight.bold, + ), + textAlign: TextAlign.center, + ), + const SizedBox(height: 8), + Text( + '使用手机号快速注册', + style: TextStyle( + fontSize: 16, + color: CupertinoColors.inactiveGray, + ), + textAlign: TextAlign.center, + ), + const SizedBox(height: 40), + CupertinoFormSection.insetGrouped( + header: const Text('手机号'), + children: [ + CupertinoTextFormFieldRow( + controller: _phoneController, + keyboardType: TextInputType.phone, + prefix: const Padding( + padding: EdgeInsets.only(left: 8), + child: Icon(CupertinoIcons.phone, size: 20), + ), + placeholder: '请输入11位手机号', + validator: (value) { + if (value == null || value.isEmpty) { + return '请输入手机号'; + } + if (value.length != 11) { + return '请输入有效的手机号'; + } + return null; + }, + ), + ], + ), + const SizedBox(height: 16), + Row( + children: [ + Expanded( + child: CupertinoFormSection.insetGrouped( + header: const Text('验证码'), + children: [ + CupertinoTextFormFieldRow( + controller: _smsCodeController, + keyboardType: TextInputType.number, + prefix: const Padding( + padding: EdgeInsets.only(left: 8), + child: Icon(CupertinoIcons.shield, size: 20), + ), + placeholder: '6位验证码', + validator: (value) { + if (value == null || value.isEmpty) { + return '请输入验证码'; + } + if (value.length != 6) { + return '验证码为6位'; + } + return null; + }, + ), + ], + ), + ), + const SizedBox(width: 12), + Padding( + padding: const EdgeInsets.only(top: 30), + child: SizedBox( + width: 120, + height: 50, + child: CupertinoButton.filled( + onPressed: _isCountdownRunning ? null : _sendSmsCode, + borderRadius: BorderRadius.circular(12), + padding: EdgeInsets.zero, + child: Text( + _isCountdownRunning ? '${_countdownSeconds}s' : '获取验证码', + style: const TextStyle(fontSize: 14), + ), + ), + ), + ), + ], + ), + const SizedBox(height: 16), + CupertinoFormSection.insetGrouped( + header: const Text('设置密码'), + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Row( + children: [ + Expanded( + child: CupertinoTextFormFieldRow( + controller: _passwordController, + obscureText: _obscurePassword, + prefix: const Padding( + padding: EdgeInsets.only(left: 8), + child: Icon(CupertinoIcons.lock, size: 20), + ), + placeholder: '请设置密码(至少6位)', + validator: (value) { + if (value == null || value.isEmpty) { + return '请输入密码'; + } + if (value.length < 6) { + return '密码至少6位'; + } + return null; + }, + ), + ), + CupertinoButton( + padding: const EdgeInsets.only(left: 8), + onPressed: () { + setState(() { + _obscurePassword = !_obscurePassword; + }); + }, + child: Icon( + _obscurePassword + ? CupertinoIcons.eye_slash + : CupertinoIcons.eye, + size: 20, + color: CupertinoColors.inactiveGray, + ), + ), + ], + ), + ), + ], + ), + const SizedBox(height: 16), + CupertinoFormSection.insetGrouped( + header: const Text('确认密码'), + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Row( + children: [ + Expanded( + child: CupertinoTextFormFieldRow( + controller: _confirmPasswordController, + obscureText: _obscureConfirmPassword, + prefix: const Padding( + padding: EdgeInsets.only(left: 8), + child: Icon(CupertinoIcons.lock_shield, size: 20), + ), + placeholder: '请再次输入密码', + validator: (value) { + if (value == null || value.isEmpty) { + return '请确认密码'; + } + if (value != _passwordController.text) { + return '两次输入的密码不一致'; + } + return null; + }, + ), + ), + CupertinoButton( + padding: const EdgeInsets.only(left: 8), + onPressed: () { + setState(() { + _obscureConfirmPassword = !_obscureConfirmPassword; + }); + }, + child: Icon( + _obscureConfirmPassword + ? CupertinoIcons.eye_slash + : CupertinoIcons.eye, + size: 20, + color: CupertinoColors.inactiveGray, + ), + ), + ], + ), + ), + ], + ), + const SizedBox(height: 32), + CupertinoButton.filled( + onPressed: _isLoading ? null : _handleRegister, + padding: const EdgeInsets.symmetric(vertical: 16), + borderRadius: BorderRadius.circular(12), + child: _isLoading + ? const SizedBox( + height: 20, + width: 20, + child: CupertinoActivityIndicator( + radius: 10, + ), + ) + : const Text( + '立即注册', + style: TextStyle(fontSize: 17), + ), + ), + const SizedBox(height: 24), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + '已有账户?', + style: TextStyle( + color: CupertinoColors.inactiveGray, + ), + ), + CupertinoButton( + padding: EdgeInsets.zero, + onPressed: () { + Get.offAndToNamed('/login'); + }, + child: const Text('立即登录'), + ), + ], + ), + const SizedBox(height: 16), + Text( + '注册即表示您同意我们的服务条款和隐私政策', + style: TextStyle( + fontSize: 12, + color: CupertinoColors.inactiveGray, + ), + textAlign: TextAlign.center, + ), + ], + ), + ), + ), + ), + ); + } +} diff --git a/lib/page/splash_page.dart b/lib/page/splash_page.dart new file mode 100644 index 0000000..9be26a7 --- /dev/null +++ b/lib/page/splash_page.dart @@ -0,0 +1,86 @@ +import 'package:flutter/cupertino.dart'; +import 'package:get/get.dart'; + +class SplashScreen extends StatefulWidget { + const SplashScreen({super.key}); + + @override + State createState() => _SplashScreenState(); +} + +class _SplashScreenState extends State with WidgetsBindingObserver { + bool _hasNavigated = false; + + @override + void initState() { + super.initState(); + WidgetsBinding.instance.addObserver(this); + _navigateToNextPage(); + } + + @override + void dispose() { + WidgetsBinding.instance.removeObserver(this); + super.dispose(); + } + + @override + void didChangeAppLifecycleState(AppLifecycleState state) { + super.didChangeAppLifecycleState(state); + if (state == AppLifecycleState.resumed) { + if (!_hasNavigated && mounted) { + _navigateToNextPage(); + } + } + } + + Future _navigateToNextPage() async { + if (_hasNavigated) return; + + await Future.delayed(const Duration(seconds: 2)); + + if (mounted && !_hasNavigated) { + _hasNavigated = true; + final bool isLoggedIn = false; + + if (isLoggedIn) { + Get.offAllNamed('/home'); + } else { + Get.offAllNamed('/login'); + } + } + } + + @override + Widget build(BuildContext context) { + return CupertinoPageScaffold( + backgroundColor: CupertinoColors.systemBlue, + child: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Icon( + CupertinoIcons.person_3, + size: 100, + color: CupertinoColors.white, + ), + const SizedBox(height: 24), + const Text( + 'Family Care', + style: TextStyle( + fontSize: 32, + color: CupertinoColors.white, + fontWeight: FontWeight.bold, + ), + ), + const SizedBox(height: 16), + const CupertinoActivityIndicator( + radius: 12, + color: CupertinoColors.white, + ), + ], + ), + ), + ); + } +} diff --git a/pubspec.lock b/pubspec.lock index ef796b4..a55ea42 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -75,6 +75,14 @@ packages: description: flutter source: sdk version: "0.0.0" + get: + dependency: "direct main" + description: + name: get + sha256: "5ed34a7925b85336e15d472cc4cfe7d9ebf4ab8e8b9f688585bf6b50f4c3d79a" + url: "https://pub.flutter-io.cn" + source: hosted + version: "4.7.3" leak_tracker: dependency: transitive description: @@ -208,6 +216,14 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "15.2.0" + web: + dependency: transitive + description: + name: web + sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a" + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.1.1" sdks: dart: ">=3.11.5 <4.0.0" flutter: ">=3.18.0-18.0.pre.54" diff --git a/pubspec.yaml b/pubspec.yaml index 41b2cfb..61b1381 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -30,6 +30,7 @@ environment: dependencies: flutter: sdk: flutter + get: # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons.