为什么必须执行热重启才能在Flutter中查看数据库中的更改?

问题描述

我正在学习Flutter,并且尝试使用SQFLite包将数据持久存储在设备上。一切正常,但是有一个问题,每次添加新元素或升级它时,我都需要重新启动应用程序才能看到所做的更改,但我不知道为什么,没有错误或任何问题。 我将其上传到github,以便您可以尝试,也许是模拟器中的某个东西或我不知道的东西。 https://github.com/Rodrigogzmn6/sql_demo

或者您可以在此处查看完整项目的一部分

主页

std::move(a)

创建项目页面

import 'package:Flutter/material.dart';
import 'package:sql_demo/models/product.dart';
import 'package:sql_demo/pages/add_product_page.dart';
import 'package:sql_demo/pages/update_product_page.dart';
import 'package:sql_demo/pages/view_product_page.dart';
import 'package:sql_demo/services/dbhelper.dart';

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  DbHelper helper;

  @override
  void initState() {
    super.initState();
    helper = DbHelper();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Home Page'),),body: FutureBuilder(
        future: helper.getProducts(),builder: (BuildContext context,AsyncSnapshot snapshot) {
          if (snapshot.hasData) {
            return ListView.builder(
                itemCount: snapshot.data.length,itemBuilder: (BuildContext context,int index) {
                  Product product = Product.fromMap(snapshot.data[index]);
                  return ListTile(
                    contentPadding: const EdgeInsets.all(16.0),title: Text(
                        '${product.name} - \$${(product.price).toString()}'),subtitle: Text(product.description),trailing: Column(
                      children: [
                        Expanded(
                          child: IconButton(
                              icon: Icon(
                                Icons.delete,color: Colors.red,onpressed: () {
                                setState(() {
                                  helper.deleteProduct(product.id);
                                });
                              }),SizedBox(
                          height: 20.0,Expanded(
                          child: IconButton(
                              icon: Icon(
                                Icons.edit,color: Colors.blue,onpressed: () {
                                Navigator.push(
                                  context,MaterialPageRoute(
                                      builder: (context) => UpdateProductPage(
                                            product: product,)),);
                              }),],onTap: () {
                      Navigator.push(
                          context,MaterialPageRoute(
                              builder: (context) => ProductDetailsPage(
                                    product: product,)));
                    },);
                });
          } else {
            return Center(
              child: CircularProgressIndicator(),);
          }
        },floatingActionButton: FloatingActionButton(
          child: Icon(
            Icons.add,color: Colors.white,onpressed: () {
            Navigator.push(context,MaterialPageRoute(builder: (context) => AddProductPage()));
          }),);
  }
}

数据库操作

import 'package:Flutter/material.dart';
import 'package:sql_demo/models/product.dart';
import 'package:sql_demo/services/dbhelper.dart';

class AddProductPage extends StatefulWidget {
  @override
  _AddProductPageState createState() => _AddProductPageState();
}

class _AddProductPageState extends State<AddProductPage> {
  String name,description;
  num price;
  DbHelper helper;

  //Instantiate Helper
  @override
  void initState() {
    super.initState();
    helper = DbHelper();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Add new product"),body: ListView(
        padding: const EdgeInsets.all(16),children: [
          TextFormField(
            decoration: Inputdecoration(
              hintText: 'Enter product name',labelText: 'Product name',onChanged: (value) {
              setState(() {
                name = value;
              });
            },SizedBox(height: 16),TextFormField(
            decoration: Inputdecoration(
              hintText: 'Enter product description',labelText: 'Product description',onChanged: (value) {
              setState(() {
                description = value;
              });
            },TextFormField(
            keyboardType: TextInputType.number,decoration: Inputdecoration(
              hintText: 'Enter product price',labelText: 'Product price',onChanged: (value) {
              setState(() {
                price = double.parse(value);
              });
            },RaisedButton(
            child: Text('Save'),onpressed: () {
              Product product = Product({
                'name': name,'description': description,'price': price,});
              setState(() {
                helper.createProduct(product);
                Navigator.pop(context);
              });
            },);
  }
}

解决方法

您可以在下面复制粘贴运行完整代码
您可以import UIKit class TableViewController: UITableViewController { var items: [String] = ["1st","2nd","3rd","4th","5th"] override func viewDidLoad() { super.viewDidLoad() tableView.allowsMultipleSelection = true } override func tableView(_ tableView: UITableView,didDeselectRowAt indexPath: IndexPath) { tableView.deselectRow(at: indexPath,animated: true) if let cell = tableView.cellForRow(at: indexPath) { cell.accessoryType = .none } } override func tableView(_ tableView: UITableView,didSelectRowAt indexPath: IndexPath) { tableView.selectRow(at: indexPath,animated: true,scrollPosition: .none) if let cell = tableView.cellForRow(at: indexPath) { cell.accessoryType = .checkmark } } func done() { if let indexPaths = tableView.indexPathsForSelectedRows { // note that this will preserve the order that the rows where selected. Just sort the indexPaths if you need it sorted. let string = indexPaths.map { items[$0.row] }.joined(separator: ",") print(string) // your code } } // MARK: - Table view data source override func numberOfSections(in tableView: UITableView) -> Int { return 1 } override func tableView(_ tableView: UITableView,numberOfRowsInSection section: Int) -> Int { return items.count } override func tableView(_ tableView: UITableView,cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "TableViewCellID",for: indexPath) as! TableViewCell cell.textLabel?.text = items[indexPath.row] cell.accessoryType = cell.isSelected ? .checkmark : .none return cell } } await Navigator.push,然后致电AddProductPage
代码段

setState(() {});

工作演示

enter image description here

完整代码

onPressed: () async {
        await Navigator.push(context,MaterialPageRoute(builder: (context) => AddProductPage()));

        setState(() {});
      }),
,

热重装:热重装功能可以快速编译文件中新添加的代码,并将其发送到Dart虚拟机。如果您在应用程序中使用状态,则热加载会保留状态,这样它们就不会在热加载时更新为默认值。

而且,initState()在热重装后不会重建,因为它的状态得以保留。因此,您必须执行热重启才能查看数据库更改:

  @override
  void initState() {
    super.initState();
    helper = DbHelper();
  }

在构建有状态的窗口小部件时,您拥有helper,但是在热重载之后,该帮助程序将与initState相同,仅称为热重启,或者您启动了该窗口小部件。因此,helper变量被保留。因此,您必须热重启。

可能会帮助您的链接:Understanding Flutter hot reload and hot restart the simplest way | Refs