Future<File>getFile(Stringname)async{finaldirectory=awaitgetApplicationDocumentsDirectory();finalpath=directory.path;returnFile("$path/$name");}Future<File>writeFile(Stringname,Stringcontents)async{finalfile=awaitgetFile(name);returnfile.writeAsString(contents);}Future<String>readFile(Stringname)async{try{finalfile=awaitgetFile(name);finalcontents=awaitfile.readAsString();returncontents;}catch(e){// If encountering an error, return ""return"";}}voidmain()async{// Avoid errors caused by flutter upgrade.// Importing 'package:flutter/widgets.dart' is required.WidgetsFlutterBinding.ensureInitialized();awaitwriteFile("a.txt","Hello, world!");debugPrint(awaitreadFile("a.txt"));runApp(constMyApp());}
// Obtain shared preferences.finalprefs=awaitSharedPreferences.getInstance();// Save an integer value to 'counter' key.awaitprefs.setInt('counter',10);// Save an boolean value to 'repeat' key.awaitprefs.setBool('repeat',true);// Save an double value to 'decimal' key.awaitprefs.setDouble('decimal',1.5);// Save an String value to 'action' key.awaitprefs.setString('action','Start');// Save an list of strings to 'items' key.awaitprefs.setStringList('items',<String>['Earth','Moon','Sun']);
// Try reading data from the 'counter' key. If it doesn't exist, returns null.finalint?counter=prefs.getInt('counter');// Try reading data from the 'repeat' key. If it doesn't exist, returns null.finalbool?repeat=prefs.getBool('repeat');// Try reading data from the 'decimal' key. If it doesn't exist, returns null.finaldouble?decimal=prefs.getDouble('decimal');// Try reading data from the 'action' key. If it doesn't exist, returns null.finalString?action=prefs.getString('action');// Try reading data from the 'items' key. If it doesn't exist, returns null.finalList<String>?items=prefs.getStringList('items');
import'dart:math';import'package:flutter/material.dart';import'package:sqflite/sqflite.dart';constStringdatabaseName="todo_db";constStringtableName="todos";finalList<Todo>debugTodos=List.generate(16,(i)=>Todo(i,"Todo $i"));classTodo{intid=0;Stringcontent="";Todo(this.id,this.content);// Convert a Todo into a Map. The keys must correspond to the names of the// columns in the database.Map<String,dynamic>toMap(){return{'id':id,'content':content,};}}classTodoListModelextendsChangeNotifier{// source of statesList<Todo>todos;intcount=0;Future<Database>?database;TodoListModel({requiredthis.todos,requiredthis.database}){if(todos.isNotEmpty){count=todos.map((e)=>e.id).toList().reduce(max)+1;}}Future<void>insert(Stringcontent)async{finaltodo=Todo(count,content);todos.add(todo);count+=1;notifyListeners();// re-build widgetsif(database!=null){finaldb=awaitdatabase!;awaitdb.insert(tableName,todo.toMap(),conflictAlgorithm:ConflictAlgorithm.replace,);}}Future<void>delete(intid)async{todos.removeWhere((todo){returntodo.id==id;});notifyListeners();// re-build widgetsif(database!=null){finaldb=awaitdatabase!;// Remove the Todo from the database.awaitdb.delete(tableName,// Use a `where` clause to delete a specific todo.where:'id = ?',// Pass the Todo's id as a whereArg to prevent SQL injection.whereArgs:[id],);}}}
import'dart:io';import'package:flutter/material.dart';import'package:provider/provider.dart';import'package:flutter/foundation.dart'showkDebugMode;import'package:sqflite/sqflite.dart';import'package:path/path.dart';import'model.dart';voidmain()async{if(kDebugMode){runApp(MyApp(defaultTodos:debugTodos,database:null));}else{if(Platform.isAndroid||Platform.isIOS||Platform.isMacOS){// Avoid errors caused by flutter upgrade.// Importing 'package:flutter/widgets.dart' is required.WidgetsFlutterBinding.ensureInitialized();// 创建并连接数据库// Open the database and store the reference.finaldatabase=openDatabase(// Set the path to the database. Note: Using the `join` function from the// `path` package is best practice to ensure the path is correctly// constructed for each platform.join(awaitgetDatabasesPath(),databaseName),// When the database is first created, create a table to store todos.onCreate:(db,version){// Run the CREATE TABLE statement on the database.returndb.execute("CREATE TABLE $tableName(id INTEGER PRIMARY KEY, content TEXT)",);},// Set the version. This executes the onCreate function and provides a// path to perform database upgrades and downgrades.version:1,);// 读取用户上次使用存储的数据// Get a reference to the database.finaldb=awaitdatabase;// Query the table for all The Todos.finalList<Map<String,dynamic>>maps=awaitdb.query(tableName);// Convert the List<Map<String, dynamic> into a List<Todo>.vardefaultTodos=List.generate(maps.length,(i){returnTodo(maps[i]['id'],maps[i]['content']);});runApp(MyApp(defaultTodos:defaultTodos,database:database));}else{runApp(MyApp(defaultTodos:[],database:null));}}}classMyAppextendsStatelessWidget{finalList<Todo>defaultTodos;finalFuture<Database>?database;MyApp({super.key,requiredthis.defaultTodos,requiredthis.database});@overrideWidgetbuild(BuildContextcontext){returnMaterialApp(title:"TodoApp",home:Scaffold(body:ChangeNotifierProvider(create:(context)=>TodoListModel(todos:defaultTodos,database:database),child:ContentWidget(),)),debugShowCheckedModeBanner:false,);}}classContentWidgetextendsStatelessWidget{ContentWidget({super.key});@overrideWidgetbuild(BuildContextcontext){returnColumn(children:[Expanded(child:Consumer<TodoListModel>(builder:(context,model,child){if(model.todos.isNotEmpty){returnListView(children:model.todos.map((todo)=>TodoWidget(todo:todo)).toList(),);}else{returnCenter(child:Text("欢迎使用 TodoApp\n你可以在下方输入新的 Todo",style:TextStyle(fontSize:36),textAlign:TextAlign.center,));}}),),AddTodoWidget()],);}}classTodoWidgetextendsStatelessWidget{finalTodotodo;TodoWidget({super.key,requiredthis.todo});@overrideWidgetbuild(BuildContextcontext){returnRow(children:[Consumer<TodoListModel>(builder:(context,model,child){returnTextButton(onPressed:(){model.delete(todo.id);},child:Icon(Icons.circle_outlined,size:36,));}),Text(todo.content,style:TextStyle(fontSize:36),),],);}}classAddTodoWidgetextendsStatefulWidget{AddTodoWidget({super.key});@overrideState<AddTodoWidget>createState()=>_AddTodoWidgetState();}class_AddTodoWidgetStateextendsState<AddTodoWidget>{finaltextFieldController=TextEditingController();@overridevoiddispose(){// Clean up the controller when the widget is disposed.textFieldController.dispose();super.dispose();}@overrideWidgetbuild(BuildContextcontext){returnRow(children:[Expanded(child:TextField(controller:textFieldController,decoration:InputDecoration(border:OutlineInputBorder(),labelText:'新 Todo 的内容',),),),Consumer<TodoListModel>(builder:(context,model,child){returnTextButton(onPressed:(){debugPrint("添加按钮按下 内容为${textFieldController.text}");model.insert(textFieldController.text);textFieldController.text="";},child:Text("添加",style:TextStyle(fontSize:24),));})],);}}