首页 > 解决方案 > 如何显示 sqflite 表中的项目

问题描述

我正在努力创建一个带有类别的笔记应用程序。但我被困了 3 天来解决这个问题。

我的问题是,如何将 SQLite 表中的“类别”显示到 DropdownButtonFormField。

这是我的 database_helper

class DatabaseHelper {
  DatabaseHelper.privateConstructor();
  static final DatabaseHelper instance = DatabaseHelper.privateConstructor();

  static Database? _database;
  Future<Database> get database async => _database ??= await _initDatabase();

  Future<Database> _initDatabase() async {
    Directory documentDirectory = await getApplicationDocumentsDirectory();
    String path = join(documentDirectory.path, 'note.db');
    return await openDatabase(
      path,
      version: 1,
      onCreate: _onCreate,
    );
  }

  Future _onCreate(Database db, int version) async {
    await db.execute('''
    CREATE TABLE categories(
    id INTEGER PRIMARY KEY,
    title TEXT)
    ''');
  }
  

  Future<List<Category>> getCategories() async {
    Database db = await instance.database;
    var categories = await db.query('categories');
    List<Category> categoryList = categories.isNotEmpty? categories.map((c) => Category.fromMap(c)).toList() : [];
    return categoryList;
  }

  Future<int> add(Category category) async {
    Database db = await instance.database;
    return await db.insert('categories', category.toMap());
  }

  Future<int> remove(int id) async {
    Database db = await instance.database;
    return await db.delete('categories', where: 'id = ?', whereArgs: [id]);
  }

  Future<int> update(Category category) async {
    Database db = await instance.database;
    return await db.update('categories', category.toMap(), where: 'id = ?', whereArgs: [category.id]);
  }
}

这是 category_model

class Category {
  final int? id;
  final String title;

  Category({this.id, required this.title});

  factory Category.fromMap(Map<String, dynamic> json) => new Category(
    id: json['id'],
    title: json['title'],
  );
  Map<String, dynamic> toMap() {
    return {
      'id': id,
      'title': title,
    };
  }
}

这是CategoryScreen,在这里用户可以进行分类。

class CategoryScreen extends StatefulWidget {
  const CategoryScreen({Key? key}) : super(key: key);

  @override
  _CategoryScreenState createState() => _CategoryScreenState();
}

class _CategoryScreenState extends State<CategoryScreen> {
  var _categoryNameController = TextEditingController();
  int? selectedId;

  _showFormDialog(BuildContext context) {
    return showDialog(
        context: context,
        barrierDismissible: true,
        builder: (param) {
          return AlertDialog(
            actions: [
              TextButton(
                onPressed: () => Navigator.pop(context),
                style: TextButton.styleFrom(
                  primary: Colors.white,
                  backgroundColor: Colors.blueGrey,
                  onSurface: Colors.grey,
                ),
                child: Text(
                  'Cancel',
                ),
              ),

              TextButton(
                onPressed: () async {
                  print('category: ${_categoryNameController.text}');
                  await DatabaseHelper.instance.add(
                    Category(title: _categoryNameController.text),
                  );
                  setState(() {
                    _categoryNameController.clear();
                  });
                  Navigator.of(context).pop(CategoryScreen());
                },
                style: TextButton.styleFrom(
                  primary: Colors.white,
                  backgroundColor: Colors.redAccent,
                  onSurface: Colors.grey,
                ),
                child: Text(
                  'Save',
                ),
              ),
            ],
            title: Text('Categories Form'),
            content: SingleChildScrollView(
              child: Column(
                children: [
                  TextField(
                    controller: _categoryNameController,
                    decoration: InputDecoration(
                        hintText: 'Write a category', labelText: 'Category'),
                  ),
                ],
              ),
            ),
          );
        });
  }
  _showEditFormDialog(BuildContext context) {
    return showDialog(
        context: context,
        barrierDismissible: true,
        builder: (param) {
          return AlertDialog(
            actions: [
              TextButton(
                onPressed: () => Navigator.pop(context),
                style: TextButton.styleFrom(
                  primary: Colors.white,
                  backgroundColor: Colors.blueGrey,
                  onSurface: Colors.grey,
                ),
                child: Text(
                  'Cancel',
                ),
              ),
              TextButton(
                onPressed: () async {
                  print('category: ${_categoryNameController.text}');
                  selectedId != null
                      ? await DatabaseHelper.instance.update(
                          Category(
                              id: selectedId,
                              title: _categoryNameController.text),
                        )
                      : await DatabaseHelper.instance.add(
                          Category(title: _categoryNameController.text),
                        );
                  setState(() {
                    _categoryNameController.clear();
                  });
                  Navigator.of(context).pop(CategoryScreen());
                },
                style: TextButton.styleFrom(
                  primary: Colors.white,
                  backgroundColor: Colors.redAccent,
                  onSurface: Colors.grey,
                ),
                child: Text(
                  'Save',
                ),
              ),
            ],
            title: Text('Categories Form'),
            content: SingleChildScrollView(
              child: Column(
                children: [
                  TextField(
                    controller: _categoryNameController,
                    decoration: InputDecoration(
                        hintText: 'Write a category', labelText: 'Category'),
                  ),
                ],
              ),
            ),
          );
        });
  }

  final GlobalKey<ScaffoldState> _globalKey = GlobalKey<ScaffoldState>();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: _globalKey,
      appBar: AppBar(
        title: Text("Categories"),
      ),
      body: Center(
        child: FutureBuilder<List<Category>>(
          future: DatabaseHelper.instance.getCategories(),
          builder:
              (BuildContext context, AsyncSnapshot<List<Category>> snapshot) {
            if (!snapshot.hasData) {
              return Center(
                child: Text("Loading..."),
              );
            }
            return snapshot.data!.isEmpty
                ? Center(
                    child: Text(
                      "No Categories!",
                      style:
                          TextStyle(fontSize: 25, fontWeight: FontWeight.bold),
                    ),
                  )
                : ListView(
                    physics: BouncingScrollPhysics(),
                    children: snapshot.data!.map((category) {
                      return Padding(
                        padding: EdgeInsets.only(top: 10, right: 16, left: 16),
                        child: Card(
                          elevation: 8.0,
                          child: ListTile(
                            onTap: () {
                              setState(() {
                                _categoryNameController.text = category.title;
                                selectedId = category.id;
                              });
                              _showEditFormDialog(context);
                            },
                            title: Row(
                              mainAxisAlignment: MainAxisAlignment.spaceBetween,
                              children: [
                                Text(
                                  category.title,
                                  style: TextStyle(
                                      fontSize: 23,
                                      fontWeight: FontWeight.bold),
                                ),
                                IconButton(
                                    onPressed: () async {
                                      Category result = await showDialog(
                                          context: context,
                                          builder: (BuildContext context) {
                                            return AlertDialog(

                                              title: Text(
                                                  '${category.id}: ${category.title}'),
                                              content: Text(
                                                  'Delete ${category.title} ?'),
                                              actions: [
                                                TextButton(
                                                  onPressed: () async {
                                                    DatabaseHelper.instance
                                                        .remove(category.id!);

                                                    setState(() {
                                                      _categoryNameController.clear();
                                                    });
                                                    Navigator.of(context).pop(CategoryScreen());
                                                  },
                                                  style: TextButton.styleFrom(
                                                    primary: Colors.white,
                                                    backgroundColor: Colors.blueGrey,
                                                    onSurface: Colors.grey,
                                                  ),
                                                  child: Text("Yes"),
                                                ),

                                                TextButton(onPressed: (){
                                                  Navigator.of(context).pop();
                                                },
                                                  child: Text("No"),
                                                  style: TextButton.styleFrom(
                                                    primary: Colors.white,
                                                    backgroundColor: Colors.blueGrey,
                                                    onSurface: Colors.grey,
                                                  ),
                                                ),
                                              ],
                                            );
                                          });
                                    },
                                    icon: Icon(
                                      Icons.delete,
                                      color: Colors.blueGrey,
                                    ))
                              ],
                            ),
                          ),
                        ),
                      );
                    }).toList(),
                  );
          },
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          _showFormDialog(context);
        },
        child: Icon(Icons.add),
      ),
    );
  }
}

这是我的noteScreen 页面。在此页面中,用户可以使用类别屏幕中的类别做笔记。

class NoteScreen extends StatefulWidget {
  const NoteScreen({Key? key}) : super(key: key);

  @override
  _NoteScreenState createState() => _NoteScreenState();
}

class _NoteScreenState extends State<NoteScreen> {

  @override
  Widget build(BuildContext context) {
    var noteTitleController = TextEditingController();
    var noteContentController = TextEditingController();

    return Scaffold(
      appBar: AppBar(
        title: Text("Create Note"),
      ),
      body: Padding(
        padding: const EdgeInsets.all(15.0),
        child: Column(
          children: [
            TextField(
              controller: noteTitleController = TextEditingController(),
              decoration: InputDecoration(
                labelText: "Title",
                hintText: "Write title",
              ),
            ),
            TextField(
              controller: noteContentController = TextEditingController(),
              decoration: InputDecoration(
                labelText: "Contents",
                hintText: "Write Contents",
              ),
            ),
            DropdownButtonFormField(
              value:,
              items:,
              hint: Text('Category'),
              onChanged: (value) {
                setState(() {


                });
              },
            ),
            SizedBox(
              height: 20,
            ),
            TextButton(onPressed: () {},
              child: Text("Save",
                style: TextStyle(fontSize: 20),),
              style: TextButton.styleFrom(
                minimumSize: Size(120, 40),
                primary: Colors.white,
                backgroundColor: Colors.blueGrey,
                onSurface: Colors.grey,
              ),
            ),
          ],
        ),
      ),
    );
  }
}

你们能帮帮我吗?这是我在这里的第一篇文章,所以如果我做错了什么,请告诉我。

标签: fluttersqflite

解决方案


像这样试试

List<Map<String, dynamic>>? categoryList;
String? selectedCategory;
int? selectedCatId;


@override
  void initState() {
    // TODO: implement initState

    categoryList = [
      {"id": 0, "title": "ABC"},
      {"id": 1, "title": "DEF"},
      {"id": 2, "title": "JKL"},
      {"id": 3, "title": "XYZ"}
    ];
    super.initState();
  }


DropdownButtonFormField(
          value: selectedCategory,
          items: categoryList!
              .map((label) => DropdownMenuItem(
                    child: Text(label['title']),
                    value: label["title"],
                  ))
              .toList(),
          hint: Text('Category'),
          onChanged: (dynamic value) {
            setState(() {
              selectedCategory = value;
            });
            var data = categoryList
                ?.where((element) => element["title"] == selectedCategory)
                .toList();
            selectedCatId = data![0]['id'];
          },
        ),

它看起来像这样


推荐阅读