我正在使用颤振和 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)
],
);
}
}
答案 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);
}
});
}