如何在颤振中将选定的复选框值保存在数据库中?

时间:2021-05-19 10:34:52

标签: sqlite flutter

我正在使用颤振和 sqlite。 我有一个表格,客户可以在其中选择他知道的语言。到目前为止,我已经使用复选框给出了选项。但我不明白如何在表格中保存选定的选项。 这是我创建的两个表:

await db.execute(
        'CREATE TABLE customerDetails (custId INTEGER PRIMARY KEY AUTOINCREMENT, '
            'custName STRING, '
            'mobileNum STRING, company STRING, custPhoto STRING, showOnCall bool,'
            'remindOn STRING,location STRING)');
   
 await db.execute(
      'CREATE TABLE languagesKnown(custId INTEGER, FOREIGN KEY (custId)REFERENCES customerDetails custId'
          'language STRING,PRIMARY KEY(custId))'
    );

database_helper.dart

import 'dart:async';
import 'package:customer/models/model.dart';
import 'package:path/path.dart' as p;
import 'package:sqflite/sqflite.dart';

abstract class DB {
  static Database _db;

  static int get _version => 1;

  static Future<Database> init() async {
    if (_db != null) {
      return _db;
    }

    try {
      var databasesPath = await getDatabasesPath();
      String _path = p.join(databasesPath, 'Customer.db');
      _db = await openDatabase(_path, version: _version, onCreate: onCreate);
      print('db location:'+_path);

    } catch (ex) {
      print(ex);
    }
  }

  static void onCreate(Database db, int version) async {
    await db.execute(
        'CREATE TABLE userDetails (id INTEGER PRIMARY KEY AUTOINCREMENT, '
            'firstName STRING, '
            'lastName STRING, mobileNum STRING, emailId STRING, address String,'
            'userType STRING,password STRING)');
    await db.execute(
        'CREATE TABLE customerDetails (custId INTEGER PRIMARY KEY AUTOINCREMENT, '
            'custName STRING, '
            'mobileNum STRING, company STRING, custPhoto STRING, showOnCall bool,'
            'remindOn STRING,location STRING)');
    await db.execute(
        'CREATE TABLE noteDetails (noteId INTEGER PRIMARY KEY AUTOINCREMENT, '
            'custId STRING, '
            'custName STRING, date STRING, note STRING, remindOn STRING,'
            'priority STRING,status STRING,attachment STRING)');
    await db.execute(
      'CREATE TABLE languagesKnown(custId INTEGER, FOREIGN KEY (custId)REFERENCES customerDetails, language STRING,PRIMARY KEY(custId))'
    );

  }

  static Future<List<Map<String, dynamic>>> query(String table) async =>
      _db.query(table);

  static Future<int> insert(String table, Model model) async =>
      await _db.insert(table, model.toMap());

  static Future<int> update(String table, Model model) async => await _db
      .update(table, model.toMap(), where: 'id = ?', whereArgs: [model.id]);

  static Future<int> delete(String table, Model model) async =>
      await _db.delete(table, where: 'id = ?', whereArgs: [model.id]);

  static Future<int> deleteCustomer(String table, Model model) async =>
      await _db.delete(table, where: 'custId = ?', whereArgs: [model.custId]);

  static Future<Batch> batch() async => _db.batch();

  static Future<List<Map<String, dynamic>>> rawQuery(String table) async =>
      _db.query(table);


}

当我点击保存按钮时,客户详细信息成功保存在 customerDetails 表中。 同样,我想将语言保存在 languagesKnown table. 中。我该怎么做?当我单击保存按钮时,在 customerDetails 表中添加了一行。我希望在具有相同 custId 和选择不同语言的 languageKnown 表中添加多行。

这是用于实现复选框的最少代码:

add_person.dart

 class AddPerson extends StatefulWidget {
      final String appBarTitle;
      final AddCustomer customer;
    
      AddPerson(this. customer, this.appBarTitle);
    
      @override
      State<StatefulWidget> createState() {
        return AddPersonState(this.customer, this.appBarTitle);
      }
    }
    class AddPersonState extends State<AddPerson> {

    List<Language> languages = [
        Language("English", false),
        Language("Hindi", false),
        Language("Arabic", false),
    
      ];
    @override
      Widget build(BuildContext context){
    var selectedLanguages = languages.where((element) => element.selected);
        return WillPopScope(
 onWillPop: () {
      moveToLastScreen();
    },

    child: Scaffold(
      appBar: AppBar(
        title: Text(appBarTitle),
        
        elevation: 1,
        
        actions: [
          IconButton(
            icon: Icon(
              Icons.search,

            ),
            onPressed: () {
              Navigator.of(context).push(MaterialPageRoute(
                  builder: (BuildContext context) => SearchContacts()));
            },
          ),
        ],
      ),
      body: Container(

        padding: EdgeInsets.only(left: 16, top: 25, right: 16),
        child:
      GestureDetector(
          onTap: () {
            FocusScope.of(context).unfocus();
          },
          child: ListView(
            children: [
          

Text("Languages Known",
                style: textStyle,
                //style: TextStyle(fontSize: 20,
                //fontWeight: FontWeight.bold,
              ),
              Divider(),
               ...languages
                          .map(
                            (language) => LanguagesWidget(
                          language: language,
                          onChanged: (value) {
                            setState(() {
                              language.selected = value;
                              if(language.selected==true)
                                lang.languages=language.name;
                            });
                          },
                        ),
                      )
                          .toList(),
    
    void _saveCustomer() async {
        moveToLastScreen();
        var result;
        if (addCustomer.custId != null) {  // Case 1: Update operation
          result = await dbService.updateCustomer(addCustomer);
        } else { // Case 2: Insert Operation
          result = await dbService.insertCustomer(addCustomer);
        }
    
        if (result != 0) {  // Success
          FormHelper.showAlertDialog(context,'Status', 'Customer Saved Successfully');
        } else {  // Failure
          FormHelper.showAlertDialog(context,'Status', 'Problem Saving Customer');
        }
    
        result=await dbService.insertLanguages(lang);
      }
language.dart

    class Language {
      String name;
      bool selected;
    
      Language(this.name, this.selected);
    }

language_widget.dart

    import 'package:flutter/material.dart';
    import 'package:customer/models/language.dart';
    
    class LanguagesWidget extends StatelessWidget {
      final Language language;
      final Function onChanged;
    
      const LanguagesWidget({Key key, this.language, this.onChanged}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Row(
          children: [
            Checkbox(
              value: language.selected,
              onChanged: onChanged,
            ),
            Text(language.name)
          ],
        );
      }
    }
 

db_service.dart

Future<bool> insertCustomer(AddCustomer model) async {
      await DB.init();
      bool isSaved = false;
      if (model != null) {
        int inserted = await DB.insert(AddCustomer.table, model);

        isSaved = inserted == 1 ? true : false;
      }

      return isSaved;
  }

 
  Future<int> updateCustomer(AddCustomer addCustomer) async {
    await DB.init();
    var result = await DB.update(AddCustomer.table, addCustomer);
    return result;
  }


    Future<bool> insertLanguages(Languages model) async {
    await DB.init();
    bool isSaved = false;
    if (model != null) {
      int inserted = await DB.insert(Languages.table, model);

      isSaved = inserted == 1 ? true : false;
    }

    return isSaved;
  }
        

add_person.dart // 完整文件

import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';
import 'package:customer/models/addCustomer.dart';
import 'package:customer/models/language.dart';
import 'package:customer/models/languages_widget.dart';
import 'package:customer/models/LanguagesModel.dart';
import 'people_list.dart';
import 'package:customer/services/db_service.dart';
import 'package:customer/utils/form_helper.dart';
import 'search_contacts.dart';
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:intl/intl.dart';

import 'package:image_picker/image_picker.dart';



class AddPerson extends StatefulWidget {
  final String appBarTitle;
  final AddCustomer customer;

  AddPerson(this. customer, this.appBarTitle);

  @override
  State<StatefulWidget> createState() {
    return AddPersonState(this.customer, this.appBarTitle);
  }
}




//class EditProfilePage extends StatefulWidget {
//@override
// _EditProfilePageState createState() => _EditProfilePageState();
//}

class AddPersonState extends State<AddPerson> {

  List<Language> languages = [
    Language("English", false),
    Language("Hindi", false),
    Language("Arabic", false),

  ];

  bool engcheckbox=false;
  String appBarTitle;
  AddCustomer customer;
  LanguagesModel lang=new LanguagesModel();
  AddPersonState(this.customer, this.appBarTitle);
  AddCustomer addCustomer=new AddCustomer();
  DBService dbService=new DBService();
  bool showPassword = false;
  DateTime _date=DateTime.now();
  TextEditingController datefield=TextEditingController();

  PickedFile _imageFile;
  final ImagePicker _picker=ImagePicker();

  TextEditingController custNameController = TextEditingController();
  TextEditingController custMobileNoController = TextEditingController();
  TextEditingController custCompanyController = TextEditingController();



  void getImage(ImageSource source) async{
    final pickedFile=await _picker.getImage(
        source:source);
    setState(() {
      _imageFile=pickedFile;
      addCustomer.custPhoto = _imageFile.path;
    });
  }

  CameraPosition cameraPosition=CameraPosition(
      target: LatLng(-33,150)
  );
  GoogleMapController _controller;



  Future<Null> _selectDate(BuildContext context)async {
    DateTime _datePicker = await showDatePicker(
      context: context,
      initialDate: _date,
      firstDate: DateTime(1947),
      lastDate: DateTime(2030),);
    if (_datePicker != null && _datePicker != _date) {
      setState(() {
        _date = _datePicker;

        String formattedDate = DateFormat('dd-MM-yyyy').format(_date);
        datefield.text=formattedDate.toString();
        print(datefield.text);
        addCustomer.remindOn=datefield.text;
      });
    }
  }
  bool isSwitched = false;
  var textValue = 'Switch is OFF';

  void toggleSwitch(bool value) {

    if(isSwitched == false)
    {
      setState(() {
        isSwitched = true;
        textValue = 'Switch Button is ON';
        addCustomer.showOnCall=isSwitched.toString();
      });
      print('Switch Button is ON');
    }
    else
    {
      setState(() {
        isSwitched = false;
        textValue = 'Switch Button is OFF';
        addCustomer.showOnCall=isSwitched.toString();
      });
      print('Switch Button is OFF');
    }
  }

  @override
  Widget build(BuildContext context){
    var selectedLanguages = languages.where((element) => element.selected);
    //var selectedDrinks = languages.where((element) => element.selected);

    TextStyle textStyle=Theme.of(context).textTheme.title;
    var height = MediaQuery.of(context).size.height;
    var width = MediaQuery.of(context).size.width;
    var _minimumPadding = 5.0;
    return WillPopScope(

        onWillPop: () {
          // Write some code to control things, when user press Back navigation button in device navigationBar
          moveToLastScreen();
        },

        child: Scaffold(
          appBar: AppBar(
            title: Text(appBarTitle),
            //backgroundColor: Theme.of(context).scaffoldBackgroundColor,
            elevation: 1,
            //  leading: IconButton(
            // icon: Icon(
            // Icons.arrow_back,

            //),
            //onPressed: () {},
            //),
            actions: [
              IconButton(
                icon: Icon(
                  Icons.search,

                ),
                onPressed: () {
                  Navigator.of(context).push(MaterialPageRoute(
                      builder: (BuildContext context) => SearchContacts()));
                },
              ),
            ],
          ),
          body: Container(

            padding: EdgeInsets.only(left: 16, top: 25, right: 16),
            child:
          GestureDetector(
              onTap: () {
                FocusScope.of(context).unfocus();
              },
              child: ListView(
                children: [
                  Text(
                    "Add People",
                    style: TextStyle(fontSize: 25, fontWeight: FontWeight.w500),
                  ),
                  SizedBox(
                    height: 15,
                  ),

                  ImageProfile(),
                  SizedBox(
                    height: 35,
                  ),

                  buildTextField("Name", custNameController,(value) => {
                    updateName(value)
                  },),
                  buildTextField("Mobile",custMobileNoController,
                          (value) => {updateMobile(value)}),
                  buildTextField("Company",custCompanyController,
                          (value) => {updateCompany(value)}),

                  SizedBox(
                    height: height * 0.02,
                  ),
                  Text("Languages Known",
                    style: textStyle,
                    //style: TextStyle(fontSize: 20,
                    //fontWeight: FontWeight.bold,
                  ),
                  Divider(),
                  ...languages
                      .map(
                        (language) => LanguagesWidget(
                      language: language,
                      onChanged: (value) {
                        setState(() {
                          language.selected = value;
                          if(language.selected==true)
                            lang.languages=language.name;
                        });
                      },
                    ),
                  )
                      .toList(),


                  SizedBox(
                    height: height * 0.02,
                  ),
                  Row(
                    children: <Widget>[
                      Expanded(
                          child: Text("Show on Call",
                            style: textStyle,
                            //style:TextStyle(
                            //fontSize: 25.0)
                          )
                      ),

                      Switch(
                        onChanged: toggleSwitch,
                        value: isSwitched,
                        //activeColor: Colors.blue,
                        //activeTrackColor: Colors.yellow,
                        //inactiveThumbColor: Colors.redAccent,
                        //inactiveTrackColor: Colors.orange,
                      ),

                      //Text('$textValue', style: TextStyle(fontSize: 20),)
                    ],),

                  Text("Remind on",style: textStyle,),
                  TextFormField(
                    controller: datefield,
                    decoration: InputDecoration(
                        suffixIcon: InkWell(
                          //onTap:_togglePasswordView,
                          child: Icon(Icons.calendar_today),
                          onTap:(){
                            setState((){

                              _selectDate(context);

                            });},
                        )),

                  ),
                  SizedBox(
                    height: height * 0.02,
                  ),

                  Text("Map",style: textStyle,),
                  SizedBox(
                    height: height * 0.02,
                  ),
                  Container(
                    height: height * 0.30,
                    width: width * 0.30,
                    child: GoogleMap(

                      initialCameraPosition: cameraPosition,
                      onMapCreated: (controller){
                        setState(() {
                          _controller=controller;

                        });
                      },
                      onTap: (coordinates){
                        _controller.animateCamera(CameraUpdate.newLatLng(coordinates));
                      },
                    ),
                  ),
                  SizedBox(
                    height: 35,
                  ),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: [
                      OutlineButton(
                        padding: EdgeInsets.symmetric(horizontal: 50),
                        shape: RoundedRectangleBorder(
                            borderRadius: BorderRadius.circular(20)),
                        onPressed: () {},
                        child: Text("CANCEL",
                            style: TextStyle(
                                fontSize: 14,
                                letterSpacing: 2.2,
                                color: Colors.black)),
                      ),
                      RaisedButton(
                        onPressed: () {
                          setState(() {
                            _saveCustomer();
                          });


                        },
                        //color: Colors.purpleAccent,
                        color: Theme.of(context).primaryColor,
                        padding: EdgeInsets.symmetric(horizontal: 50),
                        elevation: 2,
                        shape: RoundedRectangleBorder(
                            borderRadius: BorderRadius.circular(20)),
                        child: Text(
                          "SAVE",
                          style: TextStyle(
                              fontSize: 14,
                              letterSpacing: 2.2,
                              color: Colors.white),
                        ),
                      )
                    ],
                  )
                ],
              ),
          ),

          ),
        ));


  }

  Widget bottomSheet(){
    return Container(
      height: 100,
      width: MediaQuery.of(context).size.width ,
      margin: EdgeInsets.symmetric(
        horizontal:20,
        vertical:20,
      ),
      child: Column(
        children: <Widget>[
          Text("Choose profile photo",
            style: TextStyle(fontSize: 20.0),),
          SizedBox(
            height: 20,
          ),
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              FlatButton.icon(
                  onPressed: (){
                    getImage(ImageSource.camera);
                  },
                  icon:Icon(Icons.camera,color: Theme.of(context).primaryColor,), label:Text("camera")),
              FlatButton.icon(
                  onPressed: (){
                    getImage(ImageSource.gallery);
                  },
                  icon:Icon(Icons.photo_library), label:Text("Gallery"))
            ],

          )
        ],
      ),
    );
  }
  Widget ImageProfile(){
    return Center(
      child: Stack(
        children: <Widget>[
          CircleAvatar(
            radius: 80.0,
            backgroundImage: _imageFile==null?AssetImage('images/person_icon.jpg')
                :FileImage(File(_imageFile.path)),

          ),
          Positioned(
              bottom: 0,
              right: 0,
              child: Container(
                height: 40,
                width: 40,
                decoration: BoxDecoration(
                  shape: BoxShape.circle,
                  border: Border.all(
                    width: 4,
                    color: Theme.of(context).scaffoldBackgroundColor,
                  ),
                  color: Theme.of(context).primaryColor,

                ),
                child: InkWell(
                  onTap: (){
                    showModalBottomSheet(context: context, builder: (builder)=>bottomSheet());
                  },
                  child: Icon(
                    Icons.edit,
                    color: Colors.white,
                  ),
                ),
              )),
        ],
      ),
    );
  }






  //This is for 1st 3 Textfields name,mobile,company
  Widget buildTextField(String labelText,tController,Function onChanged) {
    return Padding(
      padding: const EdgeInsets.only(bottom: 35.0),
      child: TextField(
        controller:tController,
        style: TextStyle(
          fontSize: 20,
          fontWeight: FontWeight.bold,
          color: Colors.black,
        ),
        decoration: InputDecoration(
          contentPadding: EdgeInsets.only(bottom: 3),
          labelText: labelText,
          labelStyle:TextStyle(),
          floatingLabelBehavior: FloatingLabelBehavior.always,
        ),
        onChanged: (String value) {
          return onChanged(value);
        },
      ),
    );
  }
  void moveToLastScreen() {
    Navigator.pop(context, true);
  }
  void _saveCustomer() async {
    moveToLastScreen();
    // addCustomer.date = DateFormat.yMMMd().format(DateTime.now());
    var result;var res;
    if (addCustomer.custId != null) {  // Case 1: Update operation
      result = await dbService.updateCustomer(addCustomer);
    } else { // Case 2: Insert Operation
      result = await dbService.insertCustomer(addCustomer);
    }

    if (result != 0) {  // Success
      FormHelper.showAlertDialog(context,'Status', 'Customer Saved Successfully');
    } else {  // Failure
      FormHelper.showAlertDialog(context,'Status', 'Problem Saving Customer');
    }

    languages.forEach((lang) async {
      print("${lang.name} : ${lang.selected}");
      if (lang.selected) {
        await dbService.insertLanguages(lang);
      }
    });

  }
  String updateName(String value) {
    addCustomer.custName = custNameController.text;
  }

  String updateMobile(String value) {
    addCustomer.mobileNum = custMobileNoController.text;
  }
  String updateCompany(String value) {
    addCustomer.company = custCompanyController.text;
  }

语言模型.dart

import 'model.dart';

class LanguagesModel extends Model {
  static String table = 'languagesKnown';

  int custId;
  String languages;


  LanguagesModel({
    this.custId,
    this.languages
  });

  static LanguagesModel fromMap(Map<String, dynamic> map) {
    return LanguagesModel(
        custId: map["custId"],
        languages: map['languages'].toString(),


    );
  }

  Map<String, dynamic> toMap() {
    Map<String, dynamic> map = {
      'custId': custId,
      'languages': languages,
    };


    return map;
  }
}

语言.dart

class Language {
  String name;
  bool selected;

  Language(this.name, this.selected);
}


}

languages_widget.dart

import 'package:flutter/material.dart';
import 'package:customer/models/language.dart';

class LanguagesWidget extends StatelessWidget {
  final Language language;
  final Function onChanged;

  const LanguagesWidget({Key key, this.language, this.onChanged}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Row(
      children: [
        Checkbox(
          value: language.selected,
          onChanged: onChanged,
        ),
        Text(language.name)
      ],
    );
  }
}

1 个答案:

答案 0 :(得分:0)

lang 变量将只有最后选择的语言值。相反,您应该使用您的语言列表。

将您的 _saveCustomer 修改为:


void _saveCustomer() async {
   moveToLastScreen();
   var result;
   if (addCustomer.custId != null) {
      result = await dbService.updateCustomer(addCustomer);
   } else {
      result = await dbService.insertCustomer(addCustomer);
   }

   if (result != 0) {
      FormHelper.showAlertDialog(context,'Status', 'Customer Saved Successfully');
   } else {
      FormHelper.showAlertDialog(context,'Status', 'Problem Saving Customer');
   }

   // Iterating over the selected languages and saving them
   // Or you can pass the list to your dbService & iterate and save from there
   languages.forEach((lang) {
      print("${lang.name} : ${lang.selected}");
      if (lang.selected) {
         // Initialise your LanguageModel (Set your customer id as well)
         LanguagesModel language = LanguagesModel(languages:lang.name);
         await dbService.insertLanguages(language);
      }
   });
    
}