diff --git a/lib/base/base_state_widget.dart b/lib/base/base_state_widget.dart new file mode 100644 index 0000000..8e3f53c --- /dev/null +++ b/lib/base/base_state_widget.dart @@ -0,0 +1,84 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'base_viewmodel.dart'; + +class BaseStateWidget extends ConsumerStatefulWidget { + final Widget Function(BuildContext context, T value, Widget? child) builder; + final ProviderBase model; + final Widget? child; + final Function(T)? onReady; + + const BaseStateWidget({ + Key? key, + required this.builder, + required this.model, + this.child, + this.onReady, + }) : super(key: key); + + @override + _BaseStateWidgetState createState() => _BaseStateWidgetState(); +} + +class _BaseStateWidgetState extends ConsumerState> { + @override + void initState() { + super.initState(); + if (widget.onReady != null) { + widget.onReady!(ref.read(widget.model)); + } + } + + @override + Widget build(BuildContext context) { + var viewModel = ref.watch(widget.model); + if (viewModel.currentState == PageState.CONTENT) { + return widget.builder(context, viewModel, widget.child); + } + + if (viewModel.currentState == PageState.LOADING) { + return Container( + alignment: Alignment.center, + child: const CupertinoActivityIndicator(), + ); + } + + if (viewModel.currentState == PageState.FAILED) { + return Container( + alignment: Alignment.center, + child: Text("请求失败"), + ); + } + + if (viewModel.currentState == PageState.EMPTY) { + return Container( + alignment: Alignment.center, + child: Text("暂无数据"), + ); + } + + return Container(); + } +} + +abstract class BaseState extends State { + late T parent; + + @override + void initState() { + parent = widget as T; + super.initState(); + WidgetsBinding.instance?.endOfFrame.then((_) { + firstFrameCalled(); + }); + } + + void firstFrameCalled() {} + + @override + Widget build(BuildContext context) { + return buildWidgets(context); + } + + Widget buildWidgets(BuildContext context); +} diff --git a/lib/base/base_viewmodel.dart b/lib/base/base_viewmodel.dart new file mode 100644 index 0000000..94c861a --- /dev/null +++ b/lib/base/base_viewmodel.dart @@ -0,0 +1,41 @@ +import 'package:flutter/cupertino.dart'; + +class BaseViewModel extends ChangeNotifier { + PageState currentState = PageState.START; + + void loading({bool notify = false}) { + currentState = PageState.LOADING; + if (notify) { + notifyListeners(); + } + } + + void success({bool notify = true}) { + currentState = PageState.CONTENT; + if (notify) { + notifyListeners(); + } + } + + void failed({bool notify = false}) { + currentState = PageState.FAILED; + if (notify) { + notifyListeners(); + } + } + + void empty({bool notify = false}) { + currentState = PageState.EMPTY; + if (notify) { + notifyListeners(); + } + } +} + +enum PageState { + START, + LOADING, + EMPTY, + CONTENT, + FAILED, +} diff --git a/lib/base/ql_app_bar.dart b/lib/base/ql_app_bar.dart new file mode 100644 index 0000000..55fe1da --- /dev/null +++ b/lib/base/ql_app_bar.dart @@ -0,0 +1,48 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +class QlAppBar extends StatelessWidget with PreferredSizeWidget { + final String title; + final List? actions; + final VoidCallback? backCall; + final bool canBack; + final Widget? backWidget; + + QlAppBar({ + Key? key, + required this.title, + this.actions, + this.backCall, + this.canBack = true, + this.backWidget, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + Widget back = backWidget ?? + GestureDetector( + onTap: () { + if (backCall != null) { + backCall!(); + } + }, + child: const Center( + child: Icon( + CupertinoIcons.left_chevron, + size: 20, + ), + ), + ); + + return AppBar( + leading: canBack ? back : null, + automaticallyImplyLeading: canBack, + title: Text(title), + centerTitle: true, + actions: [...?actions], + ); + } + + @override + Size get preferredSize => const Size.fromHeight(kToolbarHeight); +} diff --git a/lib/base/theme.dart b/lib/base/theme.dart new file mode 100644 index 0000000..3847e56 --- /dev/null +++ b/lib/base/theme.dart @@ -0,0 +1,20 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; + +var themeProvider = ChangeNotifierProvider((ref) => ThemeViewModel()); + +class ThemeViewModel extends ChangeNotifier { + ThemeData currentTheme = lightTheme; + + void changeTheme() { + if (currentTheme == darkTheme) { + currentTheme = lightTheme; + } else { + currentTheme = darkTheme; + } + notifyListeners(); + } +} + +ThemeData darkTheme = ThemeData.dark().copyWith(); +ThemeData lightTheme = ThemeData.light().copyWith(); diff --git a/lib/main.dart b/lib/main.dart index 202509b..60448c8 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,115 +1,35 @@ +import 'dart:io'; + import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:qinglong_app/base/theme.dart'; + +import 'module/home/home_page.dart'; void main() { - runApp(const MyApp()); + runApp( + ProviderScope( + overrides: [ + themeProvider, + ], + child: const MyApp(), + ), + ); + if (Platform.isAndroid) { + SystemUiOverlayStyle style = const SystemUiOverlayStyle(statusBarColor: Colors.transparent); + SystemChrome.setSystemUIOverlayStyle(style); + } } -class MyApp extends StatelessWidget { +class MyApp extends ConsumerWidget { const MyApp({Key? key}) : super(key: key); - // This widget is the root of your application. @override - Widget build(BuildContext context) { + Widget build(BuildContext context, WidgetRef ref) { return MaterialApp( - title: 'Flutter Demo', - theme: ThemeData( - // This is the theme of your application. - // - // Try running your application with "flutter run". You'll see the - // application has a blue toolbar. Then, without quitting the app, try - // changing the primarySwatch below to Colors.green and then invoke - // "hot reload" (press "r" in the console where you ran "flutter run", - // or simply save your changes to "hot reload" in a Flutter IDE). - // Notice that the counter didn't reset back to zero; the application - // is not restarted. - primarySwatch: Colors.blue, - ), - home: const MyHomePage(title: 'Flutter Demo Home Page'), - ); - } -} - -class MyHomePage extends StatefulWidget { - const MyHomePage({Key? key, required this.title}) : super(key: key); - - // 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( - // 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. - // - // Invoke "debug painting" (press "p" in the console, choose the - // "Toggle Debug Paint" action from the Flutter Inspector in Android - // Studio, or the "Toggle Debug Paint" command in Visual Studio Code) - // to see the wireframe for each widget. - // - // 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). - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Text( - 'You have pushed the button this many times:', - ), - Text( - '$_counter', - style: Theme.of(context).textTheme.headline4, - ), - ], - ), - ), - floatingActionButton: FloatingActionButton( - onPressed: _incrementCounter, - tooltip: 'Increment', - child: const Icon(Icons.add), - ), // This trailing comma makes auto-formatting nicer for build methods. + theme: ref.watch(themeProvider).currentTheme, + home: HomePage(), ); } } diff --git a/lib/module/a.dart b/lib/module/a.dart new file mode 100644 index 0000000..e69de29 diff --git a/lib/module/config/config_page.dart b/lib/module/config/config_page.dart new file mode 100644 index 0000000..756ff7a --- /dev/null +++ b/lib/module/config/config_page.dart @@ -0,0 +1,15 @@ +import 'package:flutter/material.dart'; + +class ConfigPage extends StatefulWidget { + const ConfigPage({Key? key}) : super(key: key); + + @override + _ConfigPageState createState() => _ConfigPageState(); +} + +class _ConfigPageState extends State { + @override + Widget build(BuildContext context) { + return Scaffold(); + } +} diff --git a/lib/module/env/env_page.dart b/lib/module/env/env_page.dart new file mode 100644 index 0000000..f6e0592 --- /dev/null +++ b/lib/module/env/env_page.dart @@ -0,0 +1,16 @@ + +import 'package:flutter/material.dart'; + +class EnvPage extends StatefulWidget { + const EnvPage({Key? key}) : super(key: key); + + @override + _EnvPageState createState() => _EnvPageState(); +} + +class _EnvPageState extends State { + @override + Widget build(BuildContext context) { + return Scaffold(); + } +} diff --git a/lib/module/home/home_page.dart b/lib/module/home/home_page.dart new file mode 100644 index 0000000..c81dc21 --- /dev/null +++ b/lib/module/home/home_page.dart @@ -0,0 +1,117 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:qinglong_app/base/ql_app_bar.dart'; +import 'package:qinglong_app/base/theme.dart'; +import 'package:qinglong_app/module/config/config_page.dart'; +import 'package:qinglong_app/module/env/env_page.dart'; +import 'package:qinglong_app/module/others/other_page.dart'; +import 'package:qinglong_app/module/task/task_page.dart'; + +class HomePage extends StatefulWidget { + const HomePage({Key? key}) : super(key: key); + + @override + _HomePageState createState() => _HomePageState(); +} + +class _HomePageState extends State { + int _index = 0; + String _title = ""; + + List titles = []; + + @override + void initState() { + initTitles(); + _title = titles[0].title; + super.initState(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: QlAppBar( + canBack: false, + title: _title, + actions: [ + Consumer(builder: (context, ref, child) { + return InkWell( + onTap: () { + ref.read(themeProvider).changeTheme(); + }, + child: Center(child: Text("改变主题")), + ); + }), + ], + ), + body: IndexedStack( + index: _index, + children: const [ + TaskPage(), + EnvPage(), + ConfigPage(), + OtherPage(), + ], + ), + bottomNavigationBar: BottomNavigationBar( + items: titles + .map( + (e) => BottomNavigationBarItem( + icon: Icon(e.icon), + activeIcon: Icon(e.checkedIcon), + label: e.title, + ), + ) + .toList(), + currentIndex: _index, + onTap: (index) { + _index = index; + _title = titles[index].title; + setState(() {}); + }, + type: BottomNavigationBarType.fixed, + ), + ); + } + + void initTitles() { + titles.clear(); + titles.add( + IndexBean( + CupertinoIcons.timer, + CupertinoIcons.timer_fill, + "定时任务", + ), + ); + titles.add( + IndexBean( + CupertinoIcons.hammer, + CupertinoIcons.hammer_fill, + "环境变量", + ), + ); + titles.add( + IndexBean( + CupertinoIcons.settings, + CupertinoIcons.settings_solid, + "配置文件", + ), + ); + titles.add( + IndexBean( + CupertinoIcons.cube, + CupertinoIcons.cube_fill, + "其他", + ), + ); + } +} + +class IndexBean { + IconData icon; + IconData checkedIcon; + String title; + + IndexBean(this.icon, this.checkedIcon, this.title); +} diff --git a/lib/module/others/other_page.dart b/lib/module/others/other_page.dart new file mode 100644 index 0000000..eaceb0a --- /dev/null +++ b/lib/module/others/other_page.dart @@ -0,0 +1,15 @@ +import 'package:flutter/material.dart'; + +class OtherPage extends StatefulWidget { + const OtherPage({Key? key}) : super(key: key); + + @override + _OtherPageState createState() => _OtherPageState(); +} + +class _OtherPageState extends State { + @override + Widget build(BuildContext context) { + return Scaffold(); + } +} diff --git a/lib/module/task/task_page.dart b/lib/module/task/task_page.dart new file mode 100644 index 0000000..7db28a6 --- /dev/null +++ b/lib/module/task/task_page.dart @@ -0,0 +1,33 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:qinglong_app/base/base_state_widget.dart'; +import 'package:qinglong_app/module/task/task_viewmodel.dart'; + +class TaskPage extends StatefulWidget { + const TaskPage({Key? key}) : super(key: key); + + @override + _TaskPageState createState() => _TaskPageState(); +} + +class _TaskPageState extends State { + @override + Widget build(BuildContext context) { + return BaseStateWidget( + builder: (context, model, child) { + return ListView.builder( + itemBuilder: (context, index) { + return ListTile( + title: Text(model.list[index]), + ); + }, + itemCount: model.list.length, + ); + }, + model: taskProvider, + onReady: (viewModel) { + viewModel.loadData(); + }, + ); + } +} diff --git a/lib/module/task/task_viewmodel.dart b/lib/module/task/task_viewmodel.dart new file mode 100644 index 0000000..3f63da5 --- /dev/null +++ b/lib/module/task/task_viewmodel.dart @@ -0,0 +1,31 @@ +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:qinglong_app/base/base_viewmodel.dart'; + +var taskProvider = ChangeNotifierProvider((ref) => TaskViewModel()); + +class TaskViewModel extends BaseViewModel { + List list = []; + + void loadData() { + loading(notify: true); + + Future.delayed(Duration(seconds: 2), () { + list.add("sdfsf"); + list.add("sdfsf"); + list.add("sdfsf"); + list.add("sdfsf"); + list.add("sdfsf"); + list.add("sdfsf"); + list.add("sdfsf"); + list.add("sdfsf"); + list.add("sdfsf"); + list.add("sdfsf"); + list.add("sdfsf"); + list.add("sdfsf"); + list.add("sdfsf"); + list.add("sdfsf"); + list.add("sdfsf"); + success(); + }); + } +} diff --git a/lib/utils/sp_utils.dart b/lib/utils/sp_utils.dart new file mode 100644 index 0000000..4cd854f --- /dev/null +++ b/lib/utils/sp_utils.dart @@ -0,0 +1,171 @@ +import 'package:shared_preferences/shared_preferences.dart'; +import 'dart:async'; +import 'dart:convert'; +import 'package:synchronized/synchronized.dart'; + +class SpUtil { + static SpUtil? _singleton; + static SharedPreferences? _prefs; + static Lock _lock = Lock(); + + static Future getInstance() async { + if (_singleton == null) { + await _lock.synchronized(() async { + if (_singleton == null) { + var singleton = SpUtil._(); + await singleton._init(); + _singleton = singleton; + } + }); + } + return _singleton!; + } + + SpUtil._(); + + Future _init() async { + _prefs = await SharedPreferences.getInstance(); + } + + /// put object. + static Future? putObject(String key, Object value) { + if (_prefs == null) return null; + return _prefs!.setString(key, json.encode(value)); + } + + /// get obj. + static T? getObj(String key, T f(Map v), {T? defValue}) { + Map? map = getObject(key); + return map == null ? defValue : f(map); + } + + /// get object. + static Map? getObject(String key) { + if (_prefs == null) return null; + String? _data = _prefs!.getString(key); + return (_data == null || _data.isEmpty) ? null : json.decode(_data); + } + + /// put object list. + static Future? putObjectList(String key, List list) { + if (_prefs == null) return null; + List _dataList = list.map((value) { + return json.encode(value); + }).toList(); + return _prefs!.setStringList(key, _dataList); + } + + /// get obj list. + static List? getObjList(String key, T f(Map v), {List defValue = const []}) { + List? dataList = getObjectList(key); + List? list = dataList?.map((value) { + return f(value); + }).toList(); + return list ?? defValue; + } + + /// get object list. + static List? getObjectList(String key) { + if (_prefs == null) return null; + List? dataLis = _prefs!.getStringList(key); + return dataLis?.map((value) { + Map _dataMap = json.decode(value); + return _dataMap; + }).toList(); + } + + /// get string. + static String getString(String key, {String defValue = ''}) { + if (_prefs == null) return defValue; + return _prefs!.getString(key) ?? defValue; + } + + /// put string. + static Future? putString(String key, String value) { + if (_prefs == null) return null; + return _prefs!.setString(key, value); + } + + /// get bool. + static bool getBool(String key, {bool defValue = false}) { + if (_prefs == null) return defValue; + return _prefs!.getBool(key) ?? defValue; + } + + /// put bool. + static Future? putBool(String key, bool value) { + if (_prefs == null) return null; + return _prefs!.setBool(key, value); + } + + /// get int. + static int getInt(String key, {int defValue = 0}) { + if (_prefs == null) return defValue; + return _prefs!.getInt(key) ?? defValue; + } + + /// put int. + static Future? putInt(String key, int value) { + if (_prefs == null) return null; + return _prefs!.setInt(key, value); + } + + /// get double. + static double getDouble(String key, {double defValue = 0.0}) { + if (_prefs == null) return defValue; + return _prefs!.getDouble(key) ?? defValue; + } + + /// put double. + static Future? putDouble(String key, double value) { + if (_prefs == null) return null; + return _prefs!.setDouble(key, value); + } + + /// get string list. + static List getStringList(String key, {List defValue = const []}) { + if (_prefs == null) return defValue; + return _prefs!.getStringList(key) ?? defValue; + } + + /// put string list. + static Future? putStringList(String key, List value) { + if (_prefs == null) return null; + return _prefs!.setStringList(key, value); + } + + /// get dynamic. + static dynamic getDynamic(String key, {Object? defValue}) { + if (_prefs == null) return defValue; + return _prefs!.get(key) ?? defValue; + } + + /// have key. + static bool haveKey(String key) { + if (_prefs == null) return false; + return _prefs!.getKeys().contains(key); + } + + /// get keys. + static Set? getKeys() { + if (_prefs == null) return null; + return _prefs!.getKeys(); + } + + /// remove. + static Future? remove(String key) { + if (_prefs == null) return null; + return _prefs!.remove(key); + } + + /// clear. + static Future? clear() { + if (_prefs == null) return null; + return _prefs!.clear(); + } + + ///Sp is initialized. + static bool isInitialized() { + return _prefs != null; + } +} \ No newline at end of file diff --git a/pubspec.lock b/pubspec.lock index df800d5..ba7941b 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -57,6 +57,20 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "1.2.0" + ffi: + dependency: transitive + description: + name: ffi + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.1.2" + file: + dependency: transitive + description: + name: file + url: "https://pub.flutter-io.cn" + source: hosted + version: "6.1.2" flutter: dependency: "direct main" description: flutter @@ -69,11 +83,30 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "1.0.4" + flutter_riverpod: + dependency: "direct main" + description: + name: flutter_riverpod + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.0.3" flutter_test: dependency: "direct dev" description: flutter source: sdk version: "0.0.0" + flutter_web_plugins: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + js: + dependency: transitive + description: + name: js + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.6.3" lints: dependency: transitive description: @@ -102,6 +135,111 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "1.8.0" + path_provider_linux: + dependency: transitive + description: + name: path_provider_linux + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.1.5" + path_provider_platform_interface: + dependency: transitive + description: + name: path_provider_platform_interface + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.0.3" + path_provider_windows: + dependency: transitive + description: + name: path_provider_windows + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.0.5" + platform: + dependency: transitive + description: + name: platform + url: "https://pub.flutter-io.cn" + source: hosted + version: "3.1.0" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.1.2" + process: + dependency: transitive + description: + name: process + url: "https://pub.flutter-io.cn" + source: hosted + version: "4.2.4" + riverpod: + dependency: transitive + description: + name: riverpod + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.0.3" + shared_preferences: + dependency: "direct main" + description: + name: shared_preferences + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.0.12" + shared_preferences_android: + dependency: transitive + description: + name: shared_preferences_android + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.0.10" + shared_preferences_ios: + dependency: transitive + description: + name: shared_preferences_ios + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.0.9" + shared_preferences_linux: + dependency: transitive + description: + name: shared_preferences_linux + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.0.4" + shared_preferences_macos: + dependency: transitive + description: + name: shared_preferences_macos + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.0.2" + shared_preferences_platform_interface: + dependency: transitive + description: + name: shared_preferences_platform_interface + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.0.0" + shared_preferences_web: + dependency: transitive + description: + name: shared_preferences_web + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.0.3" + shared_preferences_windows: + dependency: transitive + description: + name: shared_preferences_windows + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.0.4" sky_engine: dependency: transitive description: flutter @@ -121,6 +259,13 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "1.10.0" + state_notifier: + dependency: transitive + description: + name: state_notifier + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.7.1" stream_channel: dependency: transitive description: @@ -135,6 +280,13 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "1.1.0" + synchronized: + dependency: "direct main" + description: + name: synchronized + url: "https://pub.flutter-io.cn" + source: hosted + version: "3.0.0" term_glyph: dependency: transitive description: @@ -163,5 +315,20 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "2.1.1" + win32: + dependency: transitive + description: + name: win32 + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.3.3" + xdg_directories: + dependency: transitive + description: + name: xdg_directories + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.2.0" sdks: dart: ">=2.15.1 <3.0.0" + flutter: ">=2.5.0" diff --git a/pubspec.yaml b/pubspec.yaml index ef4bb91..2cca50a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,55 +1,28 @@ name: qinglong_app description: A new Flutter project. - -# The following line prevents the package from being accidentally published to -# pub.dev using `flutter pub publish`. This is preferred for private packages. publish_to: 'none' # Remove this line if you wish to publish to pub.dev - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html version: 1.0.0+1 environment: sdk: ">=2.15.1 <3.0.0" -# Dependencies specify other packages that your package needs in order to work. -# To automatically upgrade your package dependencies to the latest versions -# consider running `flutter pub upgrade --major-versions`. Alternatively, -# dependencies can be manually updated by changing the version numbers below to -# the latest version available on pub.dev. To see which dependencies have newer -# versions available, run `flutter pub outdated`. + dependencies: flutter: sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.2 + flutter_riverpod: ^1.0.3 + shared_preferences: ^2.0.12 + synchronized: ^3.0.0 dev_dependencies: flutter_test: sdk: flutter - # The "flutter_lints" package below contains a set of recommended lints to - # encourage good coding practices. The lint set provided by the package is - # activated in the `analysis_options.yaml` file located at the root of your - # package. See that file for information about deactivating specific lint - # rules and activating additional ones. + flutter_lints: ^1.0.0 -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter. flutter: # The following line ensures that the Material Icons font is