问题描述
谁能告诉我如何在 checkBoxlisttile 中选择多个选项。 在这里,我只能单击一个选项。当我检查特定项目时,我想将数据库中注释表中的状态列设置为已完成。 (实际上,我想选择已完成的项目并将其显示在另一个名为已完成的选项卡下。checkBoxlisttile 是动态创建的,即从数据库中创建。添加新笔记时,它会显示在此列表视图中。)
note_info.dart //这是显示笔记的屏幕,即列表视图
import 'dart:io';
import 'package:vers2cts/models/note_model.dart';
import 'package:vers2cts/models/customer_model.dart';
import 'package:vers2cts/services/db_service.dart';
import 'package:vers2cts/utils/db_helper.dart';
import 'package:Flutter/material.dart';
import 'package:sqflite/sqflite.dart';
import 'new_note.dart';
class Note_Info extends StatefulWidget{
final String appBarTitle;
final CustomerModel customer;
//Note_Info();
Note_Info(this. customer,this.appBarTitle);
@override
State<StatefulWidget> createState() {
//return Note_InfoState();
return Note_InfoState(this. customer,this.appBarTitle);
}
}
class Note_InfoState extends State<Note_Info> {
DBService dbService = DBService();
List<NoteModel> noteList;
int count = 0;
static final GlobalKey<ScaffoldState> scaffoldKey = new GlobalKey<ScaffoldState>();
NoteModel note=NoteModel();
String appBarTitle;
CustomerModel customer=new CustomerModel();
Note_InfoState(this.customer,this.appBarTitle);
bool rememberMe = false;
DateTime _date = DateTime.Now();
TextEditingController custfNameController = TextEditingController();
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
updateListView();
if (noteList == null) {
noteList = List<NoteModel>();
updateListView();
}
TextStyle titleStyle = Theme.of(context).textTheme.subhead;
var height = MediaQuery.of(context).size.height;
var name=customer.first_name+" "+customer.last_name;
custfNameController.text = name;
return DefaultTabController(
length: 4,child: Scaffold(
appBar: AppBar(
actions: [
IconButton(
icon: Icon(
Icons.add,),onpressed: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (BuildContext context) => NewNote(customer,note)));
},)
],body: Container(
child: Column(
children: <Widget>[
TextField(controller: custfNameController,style: TextStyle(
fontSize: 20.0,fontWeight: FontWeight.bold),textAlign: TextAlign.center),Padding(
padding: const EdgeInsets.all(15.0),child: Row(children: [
ImageProfile(customer.cust_photo),Padding(
padding: const EdgeInsets.only(left: 30.0),child: IconButton(
icon: Icon(
Icons.call,color: Colors.green,size: 45,onpressed: () {
},],SizedBox(
height: 50,child: AppBar(
bottom: TabBar(
tabs: [
Tab(
text: "All",Tab(
text: "Pending",Tab(
text: "Cancelled",Tab(
text: "Completed",// create widgets for each tab bar here
Expanded(
child: TabBarView(
children: [
// first tab bar view widget
Container(
child: getNotecheckList()
),// second tab bar view widget
Container(
),Container(
child: Center(
child: Text(
'Cancelled',Container(
child: Center(
child: Text(
'Completed',Padding(
padding: const EdgeInsets.all(8.0),child: Container(
height: 55.0,width: 200,child: RaisedButton(
elevation: 2,shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20)),color: Theme
.of(context)
.primaryColorDark,textColor: Colors.white,child: Text('Save',textScaleFactor: 1.5,onpressed: () {
setState(() {
//_reset();
});
},]
),)
));
}
Widget ImageProfile(String fileName) {
return Center(
child: CircleAvatar(
radius: 80.0,backgroundImage: fileName == null
?Assetimage('images/person_icon.jpg')
:FileImage(File(customer.cust_photo))),);
}
Future<void> updateListView() {
final Future<Database> dbFuture = DB.init();
dbFuture.then((database) {
int cid=customer.cust_id;
Future<List<NoteModel>> noteListFuture = dbService.getCustomerNotes(cid);
noteListFuture.then((noteList) {
setState(() {
this.noteList = noteList;
this.count = noteList.length;
});
});
});
}
int _isChecked=-1;
ListView getNotecheckList() {
return ListView.builder(
itemCount: count,itemBuilder: (BuildContext context,int position) {
return Card(
color: Colors.white,elevation: 2.0,child: CheckBoxListTile(
title: Text(this.noteList[position].note),subtitle: Text(this.noteList[position].actn_on),//secondary: const Icon(Icons.web),value: position== _isChecked,onChanged: (bool value) {
setState(() {
_isChecked = value?position:-1;
});
},controlAffinity: ListTileControlAffinity.leading,);
},);
}
}
new_note.dart //这是添加新笔记的地方。
import 'package:Flutter/material.dart';
import 'package:Flutter/painting.dart';
import 'package:table_calendar/table_calendar.dart';
import 'package:Flutter_speed_dial/Flutter_speed_dial.dart';
import 'package:smooth_star_rating/smooth_star_rating.dart';
import 'package:intl/intl.dart';
import 'package:vers2cts/models/customer_model.dart';
import 'package:vers2cts/models/note_model.dart';
import 'package:vers2cts/services/db_service.dart';
import 'package:vers2cts/utils/form_helper.dart';
class NewNote extends StatefulWidget{
final NoteModel note;
final CustomerModel customer;
NewNote(this.customer,this. note);
//Dropdown
/*
final String label;
final Function(Color) onChanged;
final double height;
final double width;
NewNote.fordropdwn({
Key key,this.onChanged,this.height = 25,this.width = 150,this.label,}) : super(key: key);*/
@override
State<StatefulWidget> createState() {
//return New_NoteState(this.customer);
return New_NoteState(this.customer,this.note);
}
}
class New_NoteState extends State<NewNote> with SingleTickerProviderStateMixin{
New_NoteState(this.customer,this.note);
NoteModel note=new NoteModel();
CustomerModel customer=new CustomerModel();
TextEditingController NoteController=TextEditingController();
TextEditingController custfNameController = TextEditingController();
DateTime _reminderDate = DateTime.Now();
DBService dbService=new DBService();
SpeedDial _speedDial(){
return SpeedDial(
// child: Icon(Icons.add),animatedIcon: AnimatedIcons.add_event,animatedIconTheme: IconThemeData(size: 24.0),backgroundColor: Colors.yellow,curve: Curves.easeInCirc,children: [
SpeedDialChild(
child: Icon(Icons.location_on,color: Colors.yellow,//backgroundColor: Theme.of(context).primaryColor,label: 'Add Location',//labelBackgroundColor:Theme.of(context).primaryColor,SpeedDialChild(
child: Icon(Icons.keyboard_voice),//backgroundColor: Colors.yellow,label: 'Add voice',//labelBackgroundColor: Colors.yellow
),SpeedDialChild(
child: Icon(Icons.attachment_outlined,color :Colors.redAccent),//backgroundColor:Theme.of(context).primaryColorLight,label: 'Add File',// labelBackgroundColor: Theme.of(context).primaryColorLight
),SpeedDialChild(
child: Icon(Icons.image,color: Colors.lightBlue,label: 'Add Image',// labelBackgroundColor: Colors.yellow,);
}
//for DropDownMenu
Color value=Colors.red;
final List<Color> colors = [
Colors.red,Colors.blue,Colors.green,Colors.yellow,Colors.pink,Colors.purple,Colors.brown,];
//for Switch
bool isSwitched = false;
var textValue = 'Switch is OFF';
void toggleSwitch(bool value) {
if(isSwitched == false)
{
setState(() {
isSwitched = true;
note.rmnd_ind=1;
//this.note.remindOn = _reminderDate.toString();
});
}
else
{
setState(() {
isSwitched = false;
note.rmnd_ind=0;
});
}
}
@override
Widget build(BuildContext context) {
var height = MediaQuery.of(context).size.height;
var width = MediaQuery.of(context).size.width;
var name=customer.first_name+customer.last_name;
custfNameController.text = name;
return WillPopScope(
onWillPop: () {
// Write some code to control things,when user press Back navigation button in device navigationBar
movetoLastScreen();
},child: Scaffold(
appBar:AppBar(),body:ListView(
children: <Widget>[
SizedBox(
height: 2.0,TextField(controller: custfNameController,style: TextStyle(
fontSize: 20.0,Align(
alignment: Alignment.centerLeft,child: Text("Add New",textAlign: TextAlign.left,style: TextStyle(fontSize: 22,SizedBox(
height: 2.0,Divider(),Padding(
padding: const EdgeInsets.all(8.0),child: TextField(
controller: NoteController,decoration: Inputdecoration(
border: OutlineInputBorder(
borderSide: const BorderSide(width: 2.0),)),keyboardType: TextInputType.multiline,minLines: 5,//normal textInputField will be displayed
maxLines: 5,// when user presses enter it will adapt to it
onChanged: (value) {
this.note.note = value;
},TableCalendar(
selectedDayPredicate: (day) {
return isSameDay(_reminderDate,day);
},onDaySelected: (selectedDay,focusedDay) {
setState(() {
String _reminderDate = DateFormat('dd-MM-yyyy').format(selectedDay);
note.actn_on=_reminderDate.toString();
});
},// Set initial date
focusedDay: DateTime.Now(),firstDay: DateTime.utc(2010,10,16),lastDay: DateTime.utc(2030,3,14),SizedBox(
height: height*0.03,Padding(
padding: const EdgeInsets.all(10.0),child: Row(//mainAxisAlignment: MainAxisAlignment.start,children: <Widget>[
Text("Remind me",style: TextStyle(fontSize: 20),Padding(
padding: const EdgeInsets.only(left:80.0),child: Container(
child: Switch(
onChanged: toggleSwitch,value: isSwitched,//activeColor: Colors.blue,//activeTrackColor: Colors.yellow,//inactiveThumbColor: Colors.redAccent,//inactiveTrackColor: Colors.orange,child: Row(mainAxisAlignment: MainAxisAlignment.start,children:<Widget>[
Text("Priority",style: TextStyle(fontSize: 20.0),Padding(
padding: const EdgeInsets.only(left:20.0),child: Container(
child: SmoothStarrating(
size: height=50.0,allowHalfrating: false,onRated: (value) {
this.note.prty=value;
print("rating value -> $value");
},)]),children: <Widget>[
Text("Color",child: Container(
child: DropdownButton<Color>(
value: value,//hint: Text(widget.label ?? ''),onChanged: (color) {
setState(() => value = color);
//widget.onChanged(color);
},items: colors.map((e) => DropdownMenuItem(
value: e,child: Container(
// width: 60.0,//height: 10.0,width: 60.0,// height: widget.height,color: e,)
.toList(),SizedBox(
height: height*0.08,child: Container(
height: 55.0,child: RaisedButton(
elevation: 2,shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20)),color: Theme.of(context).primaryColorDark,onpressed: (){
setState(() {
_save();
});
},floatingActionButton:_speedDial(),));
}
void movetoLastScreen() {
Navigator.pop(context,true);
}
void _save() async {
movetoLastScreen();
note.cust_id=customer.cust_id;
print(customer.cust_id);
print(note.cust_id);
int result;
if (note.note_id != null) { // Case 1: Update operation
result = await dbService.updateNote(note);
} else { // Case 2: Insert Operation
result = await dbService.insertNote(note);
}
if (result != 0) { // Success
FormHelper.showAlertDialog(context,'Status','Note Saved Successfully');
} else { // Failure
FormHelper.showAlertDialog(context,'Problem Saving Note');
}
}
}
db_service.dart
import 'package:vers2cts/models/customer_model.dart';
import 'package:vers2cts/models/languages_model.dart';
import 'package:vers2cts/models/note_model.dart';
import 'package:vers2cts/models/user_model.dart';
import 'package:vers2cts/utils/db_helper.dart';
class DBService {
Future<int> insertNote(NoteModel note) async {
await DB.init();
var result = await DB.insert(NoteModel.table,note);
return result;
}
Future<List<NoteModel>> getCustomerNotes(int customer) async {
await DB.init();
var res = await DB.rawQuery("note WHERE cust_id = '$customer'");
int count = res.length;
List<NoteModel> notelist = List<NoteModel>();
// For loop to create a 'Note List' from a 'Map List'
for (int i = 0; i < count; i++) {
notelist.add(NoteModel.fromMap(res[i]));
}
return notelist;
}
}
note_model.dart
import 'model.dart';
class NoteModel extends Model {
static String table = 'note';
bool isSelected=false;
int note_id;
int cust_id;
String note;
String actn_on;
int rmnd_ind;
double prty;
String colr;
String sts;
int id;
String cre_date;
String cre_by;
String mod_date;
String mod_by;
int txn_id;
int delete_ind;
NoteModel({
this.note_id,this.cust_id,this.note,this.actn_on,this.rmnd_ind,this.prty,this.colr,this.sts,this.id,this.cre_date,this.cre_by,this.mod_date,this.mod_by,this.txn_id,this.delete_ind
});
static NoteModel fromMap(Map<String,dynamic> map) {
return NoteModel(
note_id: map["note_id"],cust_id: map['cust_id'],note: map['note'].toString(),actn_on: map['actn_on'].toString(),rmnd_ind: map['rmnd_ind'],prty: map['prty'],colr: map['colr'].toString(),sts: map['sts'].toString(),id: map['id'],cre_date: map['cre_date'].toString(),cre_by: map['cre_by'].toString(),mod_date: map['mod_date'].toString(),mod_by: map['mod_by'].toString(),txn_id: map['txn_id'],delete_ind: map['delete_ind'],);
}
Map<String,dynamic> toMap() {
Map<String,dynamic> map = {
'note_id': note_id,'cust_id': cust_id,'note':note,'actn_on': actn_on,'rmnd_ind': rmnd_ind,'prty': prty,'colr': colr,'sts':sts,'id': id,'cre_date': cre_date,'cre_by': cre_by,'mod_date':mod_date,'mod_by':mod_by,'txn_id':txn_id,'delete_ind': delete_ind
};
if (note_id != null) {
map['note_id'] = note_id;
}
return map;
}
}
db_helper.dart
import 'dart:async';
import 'package:vers2cts/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,'CTS.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 note (note_id INTEGER PRIMARY KEY,cust_id INTEGER,'
'note TEXT,'
'actn_on TEXT,rmnd_ind INTEGER,prty REAL,colr TEXT,'
'sts TEXT,'
'id INTEGER,cre_date TEXT,cre_by TEXT,mod_date TEXT,mod_by TEXT,txn_id INTEGER,delete_ind INTEGER)');
}
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<Batch> batch() async => _db.batch();
static Future<List<Map<String,dynamic>>> rawQuery(String table) async =>
_db.query(table);
}
解决方法
您需要存储从用户那里选择的所有值,然后使用它。 例如 -
var selectedIndexes = [];
ListView getNotecheckList() {
return ListView.builder(
itemCount: count,itemBuilder: (_,int index) {
return Card(
color: Colors.white,elevation: 2.0,child: CheckboxListTile(
title: Text(this.noteList[position].note),subtitle: Text(this.noteList[position].actn_on),value: selectedIndexes.contains(index),onChanged: (_) {
if (selectedIndexes.contains(index)) {
selectedIndexes.remove(index); // unselect
} else {
selectedIndexes.add(index); // select
}
},controlAffinity: ListTileControlAffinity.leading,),);
},);
}