From 2bf0d8e22b83ee589f29f26a0781837f16b014c7 Mon Sep 17 00:00:00 2001 From: ddshi <8811906+ddshi@user.noreply.gitee.com> Date: Mon, 9 Dec 2024 14:40:18 +0800 Subject: [PATCH] =?UTF-8?q?=E9=A6=96=E9=A1=B5+=E8=AE=B0=E5=BD=95=E9=A1=B5?= =?UTF-8?q?=E9=9D=A2=E8=B7=B3=E8=BD=AC=20=E6=91=87=E6=99=83=E5=BE=85?= =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/launch.json | 25 +++++ android/app/src/main/AndroidManifest.xml | 1 + android/build.gradle | 15 ++- lib/main.dart | 116 ++--------------------- lib/pages/home_page.dart | 116 +++++++++++++++++++++++ lib/pages/record_page.dart | 32 +++++++ pubspec.lock | 110 +++++++++++++++++++++ pubspec.yaml | 2 + 8 files changed, 304 insertions(+), 113 deletions(-) create mode 100644 .vscode/launch.json create mode 100644 lib/pages/home_page.dart create mode 100644 lib/pages/record_page.dart diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..edba205 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,25 @@ +{ + // 使用 IntelliSense 了解相关属性。 + // 悬停以查看现有属性的描述。 + // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "swing_account", + "request": "launch", + "type": "dart" + }, + { + "name": "swing_account (profile mode)", + "request": "launch", + "type": "dart", + "flutterMode": "profile" + }, + { + "name": "swing_account (release mode)", + "request": "launch", + "type": "dart", + "flutterMode": "release" + } + ] +} \ No newline at end of file diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 1f0db9a..22a2868 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -1,4 +1,5 @@ + 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: 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), - ), // This trailing comma makes auto-formatting nicer for build methods. + home: const HomePage(), ); } } diff --git a/lib/pages/home_page.dart b/lib/pages/home_page.dart new file mode 100644 index 0000000..5bcd5bf --- /dev/null +++ b/lib/pages/home_page.dart @@ -0,0 +1,116 @@ +import 'package:flutter/material.dart'; +import 'package:sensors_plus/sensors_plus.dart'; +import 'package:vibration/vibration.dart'; +import 'dart:async'; +import './record_page.dart'; + +class HomePage extends StatefulWidget { + const HomePage({Key? key}) : super(key: key); + + @override + State createState() => _HomePageState(); +} + +class _HomePageState extends State { + StreamSubscription? _accelerometerSubscription; + DateTime? _lastShakeTime; + int _shakeCount = 0; + bool _isNavigating = false; + + @override + void initState() { + super.initState(); + _initShakeDetection(); + } + + /// 初始化摇晃检测 + void _initShakeDetection() { + _accelerometerSubscription = accelerometerEvents.listen((event) { + // 主要检测左右摇晃(x轴) + if (event.x.abs() > 25) { + final now = DateTime.now(); + if (_lastShakeTime == null) { + _lastShakeTime = now; + _shakeCount = 1; + } else { + // 缩短有效时间窗口,要求更快的摇晃 + if (now.difference(_lastShakeTime!) < const Duration(milliseconds: 500)) { + _shakeCount++; + if (_shakeCount >= 2) { + _navigateToRecordPageWithVibration(); + _shakeCount = 0; + _lastShakeTime = null; + } + } else { + // 重置计数 + _shakeCount = 1; + } + _lastShakeTime = now; + } + } + }); + } + + /// 通过摇晃触发的导航(带震动) + void _navigateToRecordPageWithVibration() async { + if (_isNavigating) return; + + _isNavigating = true; + // 添加震动反馈 + if (await Vibration.hasVibrator() ?? false) { + Vibration.vibrate(duration: 200); + } + + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const RecordPage(), + maintainState: false, + ), + ).then((_) { + _isNavigating = false; + }); + } + + /// 通过按钮触发的导航(无震动) + void _navigateToRecordPage() { + if (_isNavigating) return; + + _isNavigating = true; + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const RecordPage(), + maintainState: false, + ), + ).then((_) { + _isNavigating = false; + }); + } + + @override + void dispose() { + _accelerometerSubscription?.cancel(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('记账本'), + ), + body: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + ElevatedButton( + onPressed: _navigateToRecordPage, + child: const Text('记账'), + ), + ], + ), + ), + ); + } +} \ No newline at end of file diff --git a/lib/pages/record_page.dart b/lib/pages/record_page.dart new file mode 100644 index 0000000..1679626 --- /dev/null +++ b/lib/pages/record_page.dart @@ -0,0 +1,32 @@ +import 'package:flutter/material.dart'; + +class RecordPage extends StatefulWidget { + const RecordPage({Key? key}) : super(key: key); + + @override + State createState() => _RecordPageState(); +} + +class _RecordPageState extends State { + @override + Widget build(BuildContext context) { + return WillPopScope( + onWillPop: () async { + Navigator.of(context).pop(); + return false; + }, + child: Scaffold( + appBar: AppBar( + title: const Text('记账'), + leading: IconButton( + icon: const Icon(Icons.arrow_back), + onPressed: () => Navigator.of(context).pop(), + ), + ), + body: const Center( + child: Text('记账页面'), + ), + ), + ); + } +} \ No newline at end of file diff --git a/pubspec.lock b/pubspec.lock index 5098ddf..dfeac06 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -49,6 +49,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.8" + device_info_plus: + dependency: transitive + description: + name: device_info_plus + sha256: "77f757b789ff68e4eaf9c56d1752309bd9f7ad557cb105b938a7f8eb89e59110" + url: "https://pub.dev" + source: hosted + version: "9.1.2" + device_info_plus_platform_interface: + dependency: transitive + description: + name: device_info_plus_platform_interface + sha256: "282d3cf731045a2feb66abfe61bbc40870ae50a3ed10a4d3d217556c35c8c2ba" + url: "https://pub.dev" + source: hosted + version: "7.0.1" fake_async: dependency: transitive description: @@ -57,6 +73,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.1" + ffi: + dependency: transitive + description: + name: ffi + sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878" + url: "https://pub.dev" + source: hosted + version: "2.1.0" + file: + dependency: transitive + description: + name: file + sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 + url: "https://pub.dev" + source: hosted + version: "7.0.1" flutter: dependency: "direct main" description: flutter @@ -75,6 +107,11 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_web_plugins: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" lints: dependency: transitive description: @@ -83,6 +120,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.1" + logging: + dependency: transitive + description: + name: logging + sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340" + url: "https://pub.dev" + source: hosted + version: "1.2.0" matcher: dependency: transitive description: @@ -115,6 +160,38 @@ packages: url: "https://pub.dev" source: hosted version: "1.8.3" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" + url: "https://pub.dev" + source: hosted + version: "2.1.8" + sensors_plus: + dependency: "direct main" + description: + name: sensors_plus + sha256: "362c8f4f001838b90dd5206b898bbad941bc0142479eab9a3415f0f79e622908" + url: "https://pub.dev" + source: hosted + version: "1.4.1" + sensors_plus_platform_interface: + dependency: transitive + description: + name: sensors_plus_platform_interface + sha256: bc472d6cfd622acb4f020e726433ee31788b038056691ba433fec80e448a094f + url: "https://pub.dev" + source: hosted + version: "1.2.0" + sensors_plus_web: + dependency: transitive + description: + name: sensors_plus_web + sha256: fca8d7d9ab6233b2a059952666415508e252420be1ef54f092d07884da53ec5e + url: "https://pub.dev" + source: hosted + version: "1.1.2" sky_engine: dependency: transitive description: flutter @@ -176,6 +253,22 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.4" + vibration: + dependency: "direct main" + description: + name: vibration + sha256: "06588a845a4ebc73ab7ff7da555c2b3dbcd9676164b5856a38bf0b2287f1045d" + url: "https://pub.dev" + source: hosted + version: "1.9.0" + vibration_platform_interface: + dependency: transitive + description: + name: vibration_platform_interface + sha256: f66b39aab2447038978c16f3d6f77228e49ef5717556e3da02313e044e4a7600 + url: "https://pub.dev" + source: hosted + version: "0.0.2" web: dependency: transitive description: @@ -184,5 +277,22 @@ packages: url: "https://pub.dev" source: hosted version: "0.3.0" + win32: + dependency: transitive + description: + name: win32 + sha256: "464f5674532865248444b4c3daca12bd9bf2d7c47f759ce2617986e7229494a8" + url: "https://pub.dev" + source: hosted + version: "5.2.0" + win32_registry: + dependency: transitive + description: + name: win32_registry + sha256: "41fd8a189940d8696b1b810efb9abcf60827b6cbfab90b0c43e8439e3a39d85a" + url: "https://pub.dev" + source: hosted + version: "1.1.2" sdks: dart: ">=3.2.5 <4.0.0" + flutter: ">=3.3.0" diff --git a/pubspec.yaml b/pubspec.yaml index 5dd76c6..bdc2383 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -30,6 +30,8 @@ environment: dependencies: flutter: sdk: flutter + sensors_plus: ^1.4.1 # 用于检测手机摇晃 + vibration: ^1.8.4 # 添加震动支持 # The following adds the Cupertino Icons font to your application.