I have some code that should return some graphs based on a Json file.
In the example below i should return 4 graphs, instead it retruns 3 and I get an index Error.
I have no ideia of where the index error is.
import 'dart:convert';
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:http/http.dart' as http;
import 'dart:math';
class Graficos extends StatefulWidget {
#override
_GraficosState createState() => _GraficosState();
}
class _GraficosState extends State<Graficos> {
List<charts.Series> seriesList;
int qteMeses = 12;
var jsonData;
List<Widget> todosGraficos = List();
bool primeirociclo = true;
TextEditingController editingController = TextEditingController();
List<LinearSales> dados = List();
List<double> precos = List();
double menorPreco = 0;
double maiorPreco = 0;
var graficos = <Widget>[];
final myController = TextEditingController();
var staticTicks;
var duplicateItems = List<String>();
var items = List<String>();
#override
void initState() {
super.initState();
_Carregar();
}
Future<String> _Carregar() async {
primeirociclo = true;
print('local');
var response = await _funcaoJson();
if (response.length != null) {
}
return 'ok';
}
#override
Widget build(BuildContext context) {
return Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: jsonData == null ?
Container() :
ListView(
padding: const EdgeInsets.all(10.0),
physics: AlwaysScrollableScrollPhysics(),
children: <Widget>[
Container(
height: MediaQuery.of(context).size.height / 10,
width: MediaQuery.of(context).size.width,
child: Row(
children: <Widget>[
Expanded(
child: TextField(
onChanged: (value) {
filterSearchResults(value);
},
controller: editingController,
decoration: InputDecoration(
labelText: "Pesquisa",
hintText: "Pesquisa",
prefixIcon: Icon(Icons.search),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(25.0)))),
),
)
],
),
),
Container(
height: MediaQuery.of(context).size.height / 10,
width: MediaQuery.of(context).size.width,
child: Row(
children: <Widget>[
Expanded(
child: TextFormField(
controller: myController,
keyboardType: TextInputType.number,
decoration: new InputDecoration(
hintText: 'Quantidade de meses',
),
),
),
RaisedButton(
color: Colors.lightBlue,
child: Text('Gerar Gráfico', style: TextStyle(
fontWeight: FontWeight.bold, fontSize: 16),
),
onPressed: () async {
qteMeses = int.parse(myController.text);
await _funcaoJson();
},
),
],
),
),
ListView.builder(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
scrollDirection: Axis.vertical,
itemCount: jsonData['pesquisa_total'][0]['pesquisas'][0]['items'].length,
itemBuilder: (BuildContext context, int index) {
dados.clear();
precos.clear();
montaGrafico(index);
return todosGraficos[index];
},
),
]));
}
void montaGrafico(int index) {
if (jsonData['pesquisa_total'][0]['pesquisas'][0]['items'][index]['ranking'] !=null) {
for (var i = qteMeses; i >= 0; i--) {
dados.add(
LinearSales(new DateTime(int.parse(
((jsonData['pesquisa_total'][0]['pesquisas'][i]['data_publicacao'])
.toString()).split("\/")[2]), int.parse(
((jsonData['pesquisa_total'][0]['pesquisas'][i]['data_publicacao'])
.toString()).split("\/")[1]), int.parse(
((jsonData['pesquisa_total'][0]['pesquisas'][i]['data_publicacao'])
.toString()).split("\/")[0])), double.parse(
(jsonData['pesquisa_total'][0]['pesquisas'][i]['items'][index]['ranking'][0]['preco']
.toString()).replaceAll(',', '.'))),
);
precos.add(double.parse(
(jsonData['pesquisa_total'][0]['pesquisas'][i]['items'][index]['ranking'][0]['preco']
.toString()).replaceAll(',', '.')));
}
}
if (jsonData['pesquisa_total'][0]['pesquisas'][0]['items'][index]['ranking'] !=null) {
seriesList = _pegaDados(dados);
}
Widget grafico;
if (jsonData['pesquisa_total'][0]['pesquisas'][0]['items'][index]['ranking'] !=null) {
grafico = Container(
height: MediaQuery.of(context).size.height * 0.4,
width: MediaQuery.of(context).size.width * 0.7,
child: new charts.TimeSeriesChart(
seriesList,
domainAxis: new charts.DateTimeAxisSpec(
tickProviderSpec: charts.DayTickProviderSpec(increments: [30]),
),
primaryMeasureAxis: new charts.AxisSpec(
tickProviderSpec: new charts.StaticNumericTickProviderSpec(
staticTicks)),
behaviors: [
new charts.ChartTitle(
jsonData['pesquisa_total'][0]['pesquisas'][0]['items'][index]['nome_produto'].toString(),
behaviorPosition: charts.BehaviorPosition.top,
titleOutsideJustification: charts.OutsideJustification.start,
innerPadding: 18),
new charts.ChartTitle('Mes',
behaviorPosition: charts.BehaviorPosition.bottom,
titleOutsideJustification:
charts.OutsideJustification.middleDrawArea),
new charts.ChartTitle('Preço',
behaviorPosition: charts.BehaviorPosition.start,
titleOutsideJustification:
charts.OutsideJustification.middleDrawArea),
new charts.PanAndZoomBehavior(),
new charts.RangeAnnotation([
new charts.RangeAnnotationSegment(new DateTime(int.parse(
((jsonData['pesquisa_total'][0]['pesquisas'][qteMeses]['data_publicacao'])
.toString()).split("\/")[2]), int.parse(
((jsonData['pesquisa_total'][0]['pesquisas'][qteMeses]['data_publicacao'])
.toString()).split("\/")[1]), int.parse(
((jsonData['pesquisa_total'][0]['pesquisas'][qteMeses]['data_publicacao'])
.toString()).split("\/")[0])),
new DateTime.now(),
charts.RangeAnnotationAxisType.domain),
new charts.LineAnnotationSegment(
maiorPreco, charts.RangeAnnotationAxisType.measure,
endLabel: 'Maior Preco: $maiorPreco',
color: charts.MaterialPalette.gray.shade400),
new charts.LineAnnotationSegment(
menorPreco, charts.RangeAnnotationAxisType.measure,
startLabel: 'Menor preco: $menorPreco',
color: charts.MaterialPalette.gray.shade400),
]),
]),
);
} else {
grafico = Divider();
}
todosGraficos.add(grafico);
print(todosGraficos.length);
}
List<charts.Series<LinearSales, DateTime>> _pegaDados(List<LinearSales> data) {
menorPreco = precos.reduce(min);
maiorPreco = precos.reduce(max);
double tickPreco = (menorPreco - 0.2);
staticTicks = <charts.TickSpec<double>>[
new charts.TickSpec(
tickPreco,
label: tickPreco.toStringAsPrecision(3),
),
new charts.TickSpec(tickPreco + 0.2),
new charts.TickSpec(tickPreco + 0.4),
new charts.TickSpec(tickPreco + 0.6),
new charts.TickSpec(tickPreco + 0.8),
];
print(data);
dados = data;
return [
new charts.Series<LinearSales, DateTime>(
id: 'Preço',
displayName: 'Preço',
domainFn: (LinearSales sales, _) => sales.mes,
measureFn: (LinearSales sales, _) => sales.sales,
data: data,
)
];
}
Future<String> _funcaoJson() async {
/*var data = await http.get(
'http://itajuba.myscriptcase.com/scriptcase/devel/conf/grp/Procon/libraries/php/pesquisa_total.php?id=3&meses=$qteMeses&fornecedor_id=23');
*/
String httpJson = 'http://itajuba.myscriptcase.com/scriptcase/devel/conf/grp/Procon/libraries/php/pesquisa_total.php';
var response = await http.post(httpJson, body: {
'id': '3',
'meses': qteMeses.toString(),
'fornecedor_id': '23'
});
setState(() {
jsonData = jsonDecode(response.body);
});
return 'Sucesso';
}
void filterSearchResults(String query) {
List<String> dummySearchList = List<String>();
dummySearchList.addAll(duplicateItems);
if(query.isNotEmpty) {
List<String> dummyListData = List<String>();
dummySearchList.forEach((item) {
if(item.contains(query)) {
dummyListData.add(item);
}
});
setState(() {
items.clear();
items.addAll(dummyListData);
});
return;
} else {
setState(() {
items.clear();
items.addAll(duplicateItems);
});
}
}
}
class LinearSales {
final DateTime mes;
final double sales;
LinearSales(this.mes, this.sales);
}
I/flutter (32442): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter (32442): The following RangeError was thrown building:
I/flutter (32442): RangeError (index): Invalid value: Not in range 0..6, inclusive: 8
I/flutter (32442):
I/flutter (32442): When the exception was thrown, this was the stack:
Can someone help me identify where the Index is wrong?
I foud where the problem was, my back-end guy added 2 more products this month, so when I was in itemCount: jsonData['pesquisa_total'][0]['pesquisas'][0]['items'].length it was 8, but for example itemCount: jsonData['pesquisa_total'][0]['pesquisas'][4]['items'].length it was 6 so there was my index error.
Related
I tried to fetch data from firestore to chip widgets but then show "LateInitializationError". And also chips should be can multi selection(select many chips). And also how to align 4 chips in a row like this example?I my code I think chips are show like ListView.
error..
I mean like this..
my code..
class uitry extends StatefulWidget {
const uitry({Key? key}) : super(key: key);
#override
State<uitry> createState() => _uitryState();
}
#override
Future<List<Words12>> fetchRecords() async {
var records = await FirebaseFirestore.instance.collection('12words').get();
return mapRecords(records);
}
List<Words12> mapRecords(QuerySnapshot<Map<String, dynamic>> records) {
var _list = records.docs
.map(
(words12) => Words12(
id: words12.id,
wordName: words12['wordName'],
categoryName: words12['categoryName'],
),
)
.toList();
return _list;
}
late int defaultChoiceIndex;
#override
void initState() {
initState();
defaultChoiceIndex = 0;
}
child: SizedBox(
width: width * 0.94,
height: height * 0.30,
child: FutureBuilder<List<Words12>>(
future: fetchRecords(),
builder: (context, snapshot) {
if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
} else {
List<Words12> data = snapshot.data ?? [];
return ListView.builder(
itemCount: data.length,
itemBuilder: (context, index) {
return (ChoiceChip(
label: Text(data[index].wordName),
selected: defaultChoiceIndex == index,
selectedColor: Colors.deepPurple,
onSelected: (value) {
setState(() {
defaultChoiceIndex =
value ? index : defaultChoiceIndex;
});
},
// backgroundColor: color,
elevation: 1,
padding: const EdgeInsets.symmetric(
horizontal: 5.0),
));
},
);
}
}),
),
#override
void initState() {
initState();
defaultChoiceIndex = 0;
}
Should be:
#override
void initState() {
super.initState();
defaultChoiceIndex = 0;
}
I believe it will initialize your defaultChoiceIndex then.
For the alignment of chips: Wrap your ChoiceChip in the ListView.builder in a Row(), with a mainAxisAlignment of your choosing:
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
ChoiceChip(etc.),
],
),
I tried it .Now it working..
code
SizedBox(
width: width * 0.94,
height: height * 0.30,
child: Column(
children: <Widget>[
const SizedBox(height: 16),
Wrap(
children: hobbyList.map(
(hobby) {
bool isSelected = false;
if (selectedHobby!.contains(hobby)) {
isSelected = true;
}
return GestureDetector(
onTap: () {
if (!selectedHobby!.contains(hobby)) {
if (selectedHobby!.length < 50) {
selectedHobby!.add(hobby);
setState(() {});
print(selectedHobby);
}
} else {
selectedHobby!.removeWhere(
(element) => element == hobby);
setState(() {});
print(selectedHobby);
}
},
child: Container(
margin: const EdgeInsets.symmetric(
horizontal: 5, vertical: 4),
child: Container(
padding: const EdgeInsets.symmetric(
vertical: 5, horizontal: 12),
decoration: BoxDecoration(
color: isSelected
? HexColor('#F5F185')
: HexColor('#D9D9D9'),
borderRadius:
BorderRadius.circular(18),
border: Border.all(
color: isSelected
? HexColor('#F5F185')
: HexColor('#D9D9D9'),
width: 2)),
child: Text(
hobby,
style: TextStyle(
color: isSelected
? Colors.black
: Colors.black,
fontSize: 14,
fontWeight: FontWeight.w600),
),
),
),
);
},
).toList(),
),
],
),
),
class _uitryState extends State<uitry> {
List<String> hobbyList = [
'Shopping',
'Brunch',
'Music',
'Road Trips',
'Tea',
'Trivia',
'Comedy',
'Clubbing',
'Drinking',
'Wine',
];
List<String>? selectedHobby = [];
I have three text form fields on the sign-in page
There are two of them for username and password that work well, I have no problem with them
But the first one is for entering the domain (it is programmed so that each client has its own domain), which is my problem.
I want that when the user enters his domain, the URL of the program, which is in the IP page, is changed and the sign-in page is called only once, without the need to call other pages.
thsis is signIn page code:
I suggest that you pay attention to _signIn and ElevatedButton.
import 'package:flutter/material.dart';
import 'package:mis_project/api/my_api.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:mis_project/conts/myString.dart';
import '../auth/auth_page.dart';
import '../conts/colors.dart';
import '../conts/mSize.dart';
class SignIn extends StatefulWidget {
const SignIn({Key key}) : super(key: key);
#override
_SignInState createState() => _SignInState();
}
class _SignInState extends State<SignIn> {
String postDomain;
bool isLoading = false;
PageController _pageController;
List<TextEditingController> tecList;
#override
void initState() {
super.initState();
_pageController = PageController();
tecList = List.generate(3, (index) {
return TextEditingController();
});
WidgetsBinding.instance.addPostFrameCallback((_) {
_showModalBottomSheet(context);
});
}
_signIn() async {
print('Sign is is called');
var data = {
'email': tecList[1].text,
'password': tecList[2].text,
};
var jsonResponse = null;
SharedPreferences localStorage = await SharedPreferences.getInstance();
var response = await CallApi().postData(data, 'login');
jsonResponse = json.decode(response.body);
if (jsonResponse != null) {
setState(() {});
localStorage.setString('token', jsonResponse['token']);
Navigator.push(
context, MaterialPageRoute(builder: (context) => AuthPage()));
} else {
setState(() {});
}
}
final _formKey = GlobalKey<FormState>();
#override
void dispose() {
for (var tec in tecList) {
tec.dispose();
}
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
backgroundColor: background_page,
body: isLoading
? Center(
child: CircularProgressIndicator(),
)
: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/image/background.jpg'),
fit: BoxFit.cover),
),
),
);
}
void _showModalBottomSheet(BuildContext context) {
showModalBottomSheet<void>(
elevation: 30,
isScrollControlled: true,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topRight: Radius.circular(30),
),
),
context: context,
builder: (BuildContext context) {
return SizedBox(
height: mDeviceSize(context).height * 0.71,
width: mDeviceSize(context).width,
child: PageView.builder(
controller: _pageController,
itemCount: 3,
itemBuilder: (context, index) {
return Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.only(
top: 40, left: 25, right: 25, bottom: 15),
child: Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
TextFormField(
textAlign: TextAlign.left,
textInputAction: TextInputAction.go,
style: TextStyle(color: Color(0xFF000000)),
cursorColor: view_all_color_HP,
controller: tecList[index],
keyboardType: TextInputType.text,
decoration: InputDecoration(
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: view_all_color_HP,
),
),
contentPadding: EdgeInsets.symmetric(
vertical: 5.0, horizontal: 10),
labelText: signing_input_label[index],
labelStyle: TextStyle(color: view_all_color_HP),
floatingLabelBehavior: FloatingLabelBehavior.auto,
border: OutlineInputBorder(),
alignLabelWithHint: true,
hintStyle: TextStyle(
color: view_all_color_HP,
fontSize: 15,
fontWeight: FontWeight.normal),
),
autofocus: true,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter some text';
}
return null;
},
),
SizedBox(
height: 10,
),
ElevatedButton(
onPressed: () {
int nextPage = index + 1;
if (nextPage < 3) {
_pageController.animateToPage(nextPage,
duration: const Duration(milliseconds: 500),
curve: Curves.ease);
}
if (index == 0) {
postDomain = tecList[0].text;
print('domain post is : $postDomain');
print('domain value is: ${tecList[0].text}');
}
if (index == 1) {
print('email value is: ${tecList[1].text}');
}
if (index == 2) {
print('pass: ${tecList[2].text}');
_signIn();
}
},
child: Text(signing_button_label[index]),
style: ElevatedButton.styleFrom(
elevation: 0,
primary: view_all_color_HP,
fixedSize:
Size(mDeviceSize(context).width * 0.3, 5),
minimumSize: Size(0, 45),
),
),
SizedBox(
height: MediaQuery.of(context).viewInsets.bottom,
),
],
),
),
),
],
);
},
),
);
},
);
}
}
and this is my APi page
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:shared_preferences/shared_preferences.dart';
class CallApi{
final String _urlF = 'https://';
final String _urlE = '.lajwardsoftwares.com/api/v1/';
postData(data, apiUrl) async {
var fullUrl = _urlF + _urlE + apiUrl + await _getToken();
print('full url is: $fullUrl');
return await http.post(
Uri.parse(fullUrl),
body: jsonEncode(data),
headers: _setHeaders()
);
}
getData(apiUrl) async {
var fullUrl = _urlF + apiUrl + await _getToken();
return await http.get(
Uri.parse(fullUrl),
headers: _setHeaders()
);
}
_setHeaders() => {
'Content-type' : 'application/json',
'Accept' : 'application/json',
};
_getToken() async {
SharedPreferences localStorage = await SharedPreferences.getInstance();
var token = localStorage.getString('token');
return '?token=$token';
// print("saied: getToken ${localStorage.getString('token')}"),};
}
}
i want this .lajwardsoftwares.com to stored from TextFromField
thanks
I want to display a listview from database. The notes stored in 'note' table are displayed successully. I want to display it as per the dates. i.e recent ones at the top and later ones(future ones) below them. if the date is of tomorrow then it should be at the top and day after tomorrow one below it. If the dates are same I want to sort them as per priority. Can anyone please help me.
(If u use any other date and time picker which can accept date and time together would also be helpful). In my case the table calendar only accepts the date. I am storing the date as TEXT(i dont know if its right)
new_note.dart// this is where I add a new note to the database.
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/color_dropdown.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);
#override
State<StatefulWidget> createState() {
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();
DateTime _selectedDay = DateTime.now();
DBService dbService=new DBService();
double _height;
double _width;
dynamic currentTime = DateFormat.jm().format(DateTime.now());
String _setTime, _setDate;
String _hour, _minute, _time;
String dateTime;
DateTime selectedDate = DateTime.now();
TimeOfDay selectedTime = TimeOfDay(hour: 00, minute: 00);
TextEditingController _dateController = TextEditingController();
TextEditingController _timeController = TextEditingController();
SpeedDial _speedDial(){
return SpeedDial(
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,),
label: 'Add Location',
),
SpeedDialChild(
child: Icon(Icons.keyboard_voice),
label: 'Add voice',
),
SpeedDialChild(
child: Icon(Icons.attachment_outlined,color :Colors.redAccent),
label: 'Add File',
),
SpeedDialChild(
child: Icon(Icons.image,color: Colors.lightBlue,),
label: 'Add Image',
),
],
);
}
//for Switch
bool isSwitched = false;
var textValue = 'Switch is OFF';
void toggleSwitch(bool value) {
if(isSwitched == false)
{
setState(() {
isSwitched = true;
note.rmnd_ind=1;
});
}
else
{
setState(() {
isSwitched = false;
note.rmnd_ind=0;
});
}
}
Future<Null> _selectTime(BuildContext context) async {
final TimeOfDay picked = await showTimePicker(
context: context,
initialTime: selectedTime,
);
if (picked != null)
setState(() {
selectedTime = picked;
_hour = selectedTime.hour.toString();
_minute = selectedTime.minute.toString();
_time = _hour + ' : ' + _minute;
_timeController.text = _time;
});
}
#override
void initState() {
_timeController.text=currentTime;
super.initState();
}
#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;
String _chosenValue;
return WillPopScope(
onWillPop: () {navigationBar
moveToLastScreen();
},
child: Scaffold(
appBar:AppBar(),
body:ListView(
children: <Widget>[
SizedBox(
height: 2.0,
),
TextField(controller: custfNameController,
style: TextStyle(
fontSize: 20.0, fontWeight: FontWeight.bold),
textAlign: TextAlign.center),
Align(
alignment: Alignment.centerLeft,
child: Text("Add New",textAlign: TextAlign.left,
style: TextStyle(fontSize: 22,fontWeight: FontWeight.bold),),
),
SizedBox(
height: 2.0,
),
Divider(),
SizedBox(
height: 2.0,
),
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;
},
),
),
Padding(
padding: const EdgeInsets.all(10.0),
child: TableCalendar(
selectedDayPredicate: (day) {
return isSameDay(_selectedDay, day);
},
onDaySelected: (selectedDay, focusedDay) {
setState(() {
_selectedDay=selectedDay;
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),),
),
Row(
children: <Widget>[
Expanded(child: Padding(
padding: const EdgeInsets.all(10.0),
child: Text("Set time",style: TextStyle(fontSize: 20),),
)),
Expanded(
child: Padding(
padding: const EdgeInsets.all(10.0),
child: InkWell(
onTap: () {
_selectTime(context);
},
child: TextFormField(
style: TextStyle(fontSize: 30),
textAlign: TextAlign.center,
onSaved: (String val) {
_setTime = val;
},
enabled: false,
keyboardType: TextInputType.text,
controller: _timeController,
),
),
),
),
]
),
SizedBox(
height: height*0.03,
),
Padding(
padding: const EdgeInsets.all(10.0),
child: Row(
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,
),
),
),
],),
),
Padding(
padding: const EdgeInsets.all(10.0),
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");
},
),
),
)]),
),
SizedBox(
height: height*0.08,
),
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(() {
_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 {
result = await dbService.insertNote(note);
}
if (result != 0) {
FormHelper.showAlertDialog(context,'Status', 'Note Saved Successfully');
} else {
FormHelper.showAlertDialog(context,'Status', 'Problem Saving Note');
}
}
}
note_info.dart // This is the screen which displays the listview
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 'package:vers2cts/utils/form_helper.dart';
import 'new_note.dart';
class Note_Info extends StatefulWidget{
final String appBarTitle;
final CustomerModel customer;
Note_Info(this. customer, this.appBarTitle);
#override
State<StatefulWidget> createState() {
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 viiew 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))),
);
}
ListView getNoteListView() {
TextStyle titleStyle = Theme.of(context).textTheme.subhead;
return ListView.builder(
itemCount: count,
itemBuilder: (BuildContext context, int position) {
return Card(
color: Colors.white,
elevation: 2.0,
child: ListTile(
title: Text(this.noteList[position].note, style: titleStyle,),
//subtitle: Text(this.customerList[position].date),
trailing: GestureDetector(
child: Icon(Icons.delete, color: Colors.grey,),
onTap: () {
// _delete(context, customerList[position]);
},
),
onTap: () {
//navigateToDetail(this.customerList[position],'Edit ');
},
),
);
},
);
}
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;
var selectedIndices = [];
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),
value: selectedIndices.contains(position),
onChanged: (_) {
if (selectedIndices.contains(position)) {
selectedIndices.remove(position);// unselect
} else {
selectedIndices.add(position); // select
}
},
controlAffinity: ListTileControlAffinity.leading,
),
);
},
);
}
}
}
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_service.dart
import 'package:vers2cts/models/note_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<Map<String, dynamic>>> getNoteMapList() async {
await DB.init();
var result = await DB.query(NoteModel.table);
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 (int i = 0; i < count; i++) {
notelist.add(NoteModel.fromMap(res[i]));
}
return notelist;
}
}
db_helper.dart actn_on saves the date and prty saves the priority
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<List<Map<String, dynamic>>> rawQuery(String table) async =>
_db.query(table);
}
Thankyou DarShan I got my answer I just had to use ORDER BY in my query
Future<List<NoteModel>> getCustomerNotes(int customer) async {
await DB.init();
var res = await DB.rawQuery("note WHERE cust_id = '$customer' ORDER BY actn_on ASC,prty DESC;");
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;
}
I need help in this please i have a RefreshIndicator that loads a ListView when there is data in the database however I want to make the widget return Text widget 'no data' if the table empty instead of the ListView.
but the when the table is empty it error appear
_TypeError (type 'String' is not a subtype of type 'Iterable')
and that will appear in the refresh method i don't know what should i do i appreciate any help thanks in advance.
this the UI for the page
class _onlineResultTab extends State<onlineResultTab> {
List<ResultsModelClass> resultslist = new List();
List<CoursesModelClass> coursesist = new List();
ResultsModelClass resultsModelClass;
CoursesModelClass courseModelClass;
final GlobalKey<RefreshIndicatorState> refreshKey = GlobalKey<RefreshIndicatorState>();
DataApiProvider dataApiProvider = new DataApiProvider();
Widget build(BuildContext context) {
return Scaffold(
body: RefreshIndicator(
key: refreshKey,
onRefresh: refreshList,
child: _resultwidget(context),
),
);
}
fetchResultDetails() async {
final allRows = await DbHelper.mydb.getOnlineResultList();
allRows.forEach((row) => {
resultsModelClass = ResultsModelClass(
"",
row["Res_Stud_Index"],
row["Res_Stud_Name"],
row["Res_Sem"].toString(),
"",
"",
row["Res_Batch"],
row["Res_Courses"],
row["Res_Grade"],
row["Res_GPA"].toString(),
row["Res_CGPA"],
row["Res_Status"],
row["faculty_desc_e"],
row["major_desc_e"]),
resultslist.add(resultsModelClass)
});
if (this.mounted) {
setState(() {});
}
}
fetchCourse() async {
final allRows = await DbHelper.mydb.getResultcoursesList();
allRows.forEach((row) => {
courseModelClass = CoursesModelClass(
row["Res_Courses"],
row["Res_Grade"],
),
coursesist.add(courseModelClass)
});
if (this.mounted) {
setState(() {});
}
}
List<String> listHeader = ['Student Results Details'];
Widget _resultwidget(context) {
final _size = MediaQuery.of(context).size;
return resultslist.length == 0
? ListView.builder(
controller: ScrollController(),
itemCount: 1,
itemBuilder: (context, index) {
return Center(
child: Padding(
padding: EdgeInsets.only(top: _size.height * 0.4),
child: Text(
"No Result Details !",
style: TextStyle(fontSize: 20),
),
));
},
physics: AlwaysScrollableScrollPhysics(),
)
: new ListView.builder(
itemCount: listHeader.length,
itemBuilder: (context, index) {
//var _size = MediaQuery.of(context).size;
return SingleChildScrollView(
child: Center(
child: Padding(
padding: EdgeInsets.only(bottom: _size.height * 0.02),
child: Column(
children: [
Card(
elevation: 20,
margin: EdgeInsets.symmetric(
horizontal: _size.width * 0.005,
),
child: Container(
height: 50.0,
decoration: BoxDecoration(
color: Theme.of(context).backgroundColor),
child: Center(
child: Text(
'Semester ' +
resultslist[0].Res_Sem +
' Result ',
style: TextStyle(
color: Colors.white,
fontSize: 17,
fontWeight: FontWeight.bold),
),
),
),
),
],
))),
);
},
);
}
the refresh method
Future<String> refreshList() async {
refreshKey.currentState?.show(atTop: false);
//await Future.delayed(Duration(seconds: 10));
var studentIndex;
final allRows = await DbHelper.mydb.MainInfoCehck();
allRows.forEach((row) => {
row["Stud_Index"],
studentIndex = row["Stud_Index"].toString()
//print( row["Stud_Index"].toString())
});
print(studentIndex);
//void refreshResult(String studentIndex)async{
await dataApiProvider.refresh_result(studentIndex);
// }
if (this.mounted) {
setState(() {
coursesist.clear();
resultslist.clear();
fetchResultDetails();
fetchCourse();
});
}
return null;
}
Future<String> refresh_result(String studentIndex) async {
var url = main_urll + "?studentIndex=" + studentIndex.trim();
final response = await http.get(url);
List<ResultDetailsModel> ResulttDetailsListModel = [];
final resultInfo = jsonDecode(response.body)['result_info'];
DbHelper.mydb.deleteTableData("Result");
print('Result informations : ' + resultInfo.toString());
for (Map i in resultInfo) {
ResulttDetailsListModel.add(ResultDetailsModel.fromJson(i));
DbHelper.mydb.saveResultDetails(ResultDetailsModel.fromJson(i));
}
return "";
}
Please check if
resultslist == null or resultslist.isNotEmpty()
for Handling empty list
Hy, im working on a project, using table_calendar plugin im receiving meetings record from database and showing them as a marker on the calendar, now i want to show that meeting details on the page in a list, but i don't have any idea how to do that, i able to print it meeting ids in the list, but how i can print other meetings details also, like location, time, customer name etc?
import 'package:flutter/material.dart';
import 'package:hexcolor/hexcolor.dart';
import 'package:intl/intl.dart';
import 'notifcation_dialog.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:table_calendar/table_calendar.dart';
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'variables.dart';
import 'package:flutter_datetime_picker/flutter_datetime_picker.dart';
import 'package:expandable/expandable.dart';
TextEditingController agendaController = new TextEditingController();
TextEditingController phoneController = new TextEditingController();
TextEditingController locationController = new TextEditingController();
meeting mee = new meeting();
meeting meet = new meeting();
String _time = '';
List meetDate;
CalendarController _controller;
String dateWithT;
String emailFromSharedPref, meetingAdded;
Map smData;
Map meetingDetail;
List meetingInfo, customerInfo;
List<dynamic> _selectedEvents;
Map<DateTime, List<dynamic>> _events;
Map<DateTime, List<dynamic>> c_nameMap;
class AddMeeting extends StatefulWidget {
#override
_AddMeetingeState createState() => _AddMeetingeState();
}
class _AddMeetingeState extends State<AddMeeting> {
#override
void initState() {
super.initState();
_controller = CalendarController();
_events = {};
_selectedEvents = [];
c_nameMap = {};
getIdAndGetMeetings();
}
Future getIdAndGetMeetings() async {
// getting email from SharedPreferences
SharedPreferences prefs = await SharedPreferences.getInstance();
emailFromSharedPref = prefs.getString('email');
// getting saleManager info using email
var url = "http://.../getSaleMangerDetal.php";
var response = await http.post(url, body: {
"m_email": emailFromSharedPref,
});
smData = jsonDecode(response.body);
// getting customer info using saleManagerID
var customerInfoUrl = "http://.../calender/getCustomerInfo.php";
var customerInfoResponse = await http.post(customerInfoUrl, body: {
"sm_id": smData['manager_id'],
});
// saving customer info in the list, because there are many dict in the list
customerInfo = jsonDecode(customerInfoResponse.body);
// get meetings details from server using saleManager Id
var getmeetingUrl = "http://.../getMeetings.php";
var getMeetiongResponse = await http.post(getmeetingUrl, body: {
"manager_id": smData['manager_id'],
});
meetingInfo = jsonDecode(getMeetiongResponse.body);
print(meetingInfo);
for (int i = 0; i < meetingInfo.length; i++) {
dateWithT =
meetingInfo[i]['m_date'].replaceAll(new RegExp(r'[^\w\s]+'), '');
dateWithT = dateWithT.replaceAll(' ', '');
dateWithT = dateWithT + "000000";
dateWithT = dateWithT.substring(0, 8) + 'T' + dateWithT.substring(8);
mee.dateTime = DateTime.parse(dateWithT);
if (_events[mee.dateTime] != null) {
_events[mee.dateTime].add(meetingInfo[i]['meeting_id']);
} else {
_events[mee.dateTime] = [meetingInfo[i]['meeting_id']];
}
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter Calendar'),
),
body: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
// Text(_time),
TableCalendar(
events: _events,
// initialCalendarFormat: CalendarFormat.week,
calendarStyle: CalendarStyle(
canEventMarkersOverflow: true,
todayColor: Colors.orange,
selectedColor: Theme.of(context).primaryColor,
todayStyle: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18.0,
color: Colors.white)),
headerStyle: HeaderStyle(
centerHeaderTitle: true,
formatButtonDecoration: BoxDecoration(
color: Colors.orange,
borderRadius: BorderRadius.circular(20.0),
),
formatButtonTextStyle: TextStyle(color: Colors.white),
formatButtonShowsNext: false,
),
startingDayOfWeek: StartingDayOfWeek.monday,
onDaySelected: (date, events) {
setState(() {
_selectedEvents = events;
});
},
builders: CalendarBuilders(
calendarController: _controller,
),
..._selectedEvents.map((event) => Stack(
children: <Widget>[
// getMeetingsIndividualDetails(event),
Card(
child: Container(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: ExpandablePanel(
header: Text(event),
// Text(getMeetingsIndividualDetails(event, 'c_name')),
collapsed: Text(
'qwe',
softWrap: true,
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
expanded: Text(
'as',
softWrap: true,
),
tapHeaderToExpand: true,
hasIcon: true,
),
),
),
),
],
)),
],
),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: _showAddDialog,
),
);
}
_showAddDialog() async {
await showDialog(
context: context,
builder: (context) => StatefulBuilder(builder: (context, setState) {
return ShowDialog();
}));
setState(() {
_selectedEvents = _events[mee.dateTime];
});
}
}
addMeetingToDatabase(List meetDate2) async {
// print(meetDate2[0]);
var getmeetingUrls = "http://.../addMeeting.php";
var getMeetiongResponses = await http.post(getmeetingUrls, body: {
"sm_id": smData['manager_id'],
"c_id": '2',
"agenda": agendaController.text,
"phone": phoneController.text,
"location": locationController.text,
"date": meetDate2[0],
"time": _time,
});
meetingAdded = jsonDecode(getMeetiongResponses.body);
print(meetingAdded);
}
class ShowDialog extends StatefulWidget {
#override
_ShowDialogState createState() => _ShowDialogState();
}
class _ShowDialogState extends State<ShowDialog> {
#override
Widget build(BuildContext context) {
return AlertDialog(
content: SingleChildScrollView(
child: Container(
// height: MediaQuery.of(context).size.height/3,
child: Column(
// mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 8.0, bottom: 8),
child: TextField(
controller: phoneController,
// maxLines: null,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Phone',
prefixIcon: Icon(Icons.phone_android),
labelStyle: TextStyle(fontSize: 15)),
),
),
Padding(
padding: const EdgeInsets.only(top: 8.0, bottom: 8),
child: TextField(
controller: locationController,
// maxLines: null,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Meeting Location',
prefixIcon: Icon(Icons.add_location),
labelStyle: TextStyle(fontSize: 15)),
),
),
Padding(
padding: const EdgeInsets.only(top: 8.0, bottom: 8),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
RaisedButton(
child: Text('Meeting Time'),
onPressed: () {
DatePicker.showTimePicker(context,
theme: DatePickerTheme(
containerHeight: 210.0,
),
showTitleActions: true, onConfirm: (time) {
print('confirm $time');
_time =
'${time.hour} : ${time.minute} : ${time.second}';
setState(() {});
},
currentTime: DateTime.now(),
locale: LocaleType.en);
setState(() {});
}),
Text(_time)
],
),
),
Padding(
padding: const EdgeInsets.only(top: 8.0, bottom: 8),
child: TextField(
controller: agendaController,
maxLines: null,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Agenda',
prefixIcon: Icon(Icons.message),
labelStyle: TextStyle(fontSize: 15)),
),
),
],
),
),
),
actions: <Widget>[
FlatButton(
child: Text("Save"),
onPressed: () {
// if (agendaController.text.isEmpty) return;
// if (_events[_controller.selectedDay] != null) {
// _events[_controller.selectedDay]
// .add(agendaController.text);
String asd = _controller.selectedDay.toString();
meetDate = asd.split(' ');
addMeetingToDatabase(meetDate);
agendaController.clear();
phoneController.clear();
locationController.clear();
Navigator.pop(context);
},
)
],
);
}
}
what i have achieved?
What i want to achieve
Instead of List<Dynamic>, it's better to map those data on an object so it can be accessed with a constant getter function.
Let Map<DateTime, List<dynamic>> _events; be Map<DateTime, EventDetails> _events;
where EventDetails contains for example:
class EventDetails {
String author;
String eventName;
String description;
EventDetails(
{required this.author,
required this.eventName,
required this.description});
}
Then you can add data using an Object.
EventDetails eventDetails = EventDetails(author: 'AUTHOR',
eventName: 'EVENT_NAME', description: 'DESCRIPTION');
...
_events[mee.dateTime].add(eventDetails);