I need help I am developing an app using SQLite, here is my scenario I want to make favorite feature using SQLLITE, if the value does exist then fill the heart icon with red color otherwise remove the color from the heart icon i already implement method check value if already exist but i dont how using in listview.
import 'package:bibleapp/favourite.dart';
import 'package:bibleapp/main.dart';
import 'package:flutter/material.dart';
import 'package:flutter_tts/flutter_tts.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
import 'package:share_plus/share_plus.dart';
import 'package:sqflite/sqflite.dart';
import 'Dbhelper.dart';
import 'package:favorite_button/favorite_button.dart';
class Allverse extends StatefulWidget {
late int booknumber;
late int chapternumber;
late int versenumber;
late String bookname;
#override
_AllverseState createState() => _AllverseState();
Allverse(this.bookname,this.booknumber, this.chapternumber,this.versenumber);
}
class _AllverseState extends State<Allverse> {
final ItemScrollController itemScrollController = ItemScrollController();
late int versenumber;
String _selectedView = 't_kjv';
#override
void initState() {
// TODO: implement initState
super.initState();
versenumber=widget.versenumber-1;
setState(() {
getallverse(_selectedView,widget.booknumber,widget.chapternumber);
Future.delayed(Duration(seconds: 1), () {
itemScrollController.jumpTo(
index: versenumber,
);
});
});
}
var check=false;
List<Map<String, dynamic>> allverse = [];
void getallverse(datbase,booknumber,chapternumber) async {
final data = await Dbhelper.fetchallverse(datbase,booknumber, chapternumber);
setState(() {
allverse= data;
});
}
//add favourite
// Collect Data from DB
FlutterTts flutterTts = FlutterTts();
speak(String txt)async{
await flutterTts.setLanguage('"en-US');
await flutterTts.setPitch(1);
await flutterTts.speak(txt);
}
int? checkfavurite;
//THIS METHOD CHECK IF VALUE ALREADY EXIST THEN RETURN 1
Future<bool>uidExists(id) async {
final db = await Dbhelper().db;
var result = await db?.rawQuery(
'SELECT EXISTS(SELECT 1 FROM favourite WHERE bookid="$id")',
);
checkfavurite= Sqflite.firstIntValue(result!);
print(checkfavurite);
return checkfavurite == 1;
}
#override
void dispose() {
// TODO: implement dispose
super.dispose();
flutterTts.stop();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title:Row(
children: [
Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
GestureDetector(
onTap: (){
setState(() {
Navigator.push(
context,
PageRouteBuilder(
pageBuilder: (context, animation1, animation2) =>MyApp(),
transitionDuration: Duration(seconds: 0),
),
);
});
},
child: Icon(Icons.menu_book_sharp)),
Text('Books',style: TextStyle(
fontSize: 9
),),
],
),
SizedBox(width: 10),
Expanded(
child: Text('${widget.bookname} ${widget.chapternumber}:${widget.versenumber}',style: TextStyle(
fontSize: 16
)),
)
]
),
actions: <Widget>[
PopupMenuButton(
initialValue: 0,
// add icon, by default "3 dot" icon
// icon: Icon(Icons.book)
itemBuilder: (context){
return [
PopupMenuItem<int>(
value: 0,
child: Text("King James version"),
),
PopupMenuItem<int>(
value: 1,
child: Text("American Standard-ASV1901"),
),
PopupMenuItem<int>(
value: 2,
child: Text("BIble in Basic English"),
),
PopupMenuItem<int>(
value: 3,
child: Text("Darby English"),
),
PopupMenuItem<int>(
value: 4,
child: Text("Young's Literal Translation"),
),
PopupMenuItem<int>(
value: 5,
child: Text("World Englis bible"),
),
PopupMenuItem<int>(
value: 6,
child: Text("Webster's Bible"),
),
PopupMenuItem<int>(
value: 7,
child: Text("Favourite verse"),
),
];
},
onSelected:(value){
if(value == 0){
setState(() {
getallverse('t_kjv', widget.booknumber, widget.chapternumber);
});
}else if(value == 1){
setState(() {
getallverse('t_asv', widget.booknumber, widget.chapternumber);
});
}else if(value == 2){
setState(() {
getallverse('t_bbe', widget.booknumber, widget.chapternumber);
});
}
else if(value == 3){
setState(() {
getallverse('t_dby', widget.booknumber, widget.chapternumber);
});
}
else if(value == 4){
setState(() {
getallverse('t_ylt', widget.booknumber, widget.chapternumber);
});
}
else if(value == 5){
setState(() {
getallverse('t_web', widget.booknumber, widget.chapternumber);
});
}
else if(value == 6){
setState(() {
getallverse('t_wbt', widget.booknumber, widget.chapternumber);
});
}
else if(value == 7){
setState(() {
Navigator.push(
context,
PageRouteBuilder(
pageBuilder: (context, animation1, animation2) =>Favourite(),
transitionDuration: Duration(seconds: 0),
),
);
});
}
}
),
],
),
body:Container(
color:Colors.white70,
child: ScrollablePositionedList.builder(
shrinkWrap: true,
itemCount: allverse.length,
itemScrollController: itemScrollController,
itemBuilder:(context,index) {
//HERE IS METHOD CALLING
uidExists(allverse[index]['id']);
return Container(
color: index ==versenumber? Colors.yellow[100]:null,
child: GestureDetector(
onTap:(){
print(index);
},
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: EdgeInsets.only(top: 4),
child: CircleAvatar(
backgroundColor: Colors.lightBlueAccent,
radius: 11,
child: Text(
allverse[index]['v'].toString(),style: TextStyle(
fontSize: 12,
color: Colors.black,
fontWeight: FontWeight.bold
),
)
),
),
Expanded(
child: Text.rich(
TextSpan(
children: [
TextSpan(text: allverse[index]['t'],
style: GoogleFonts.heebo(
fontSize: 22,
wordSpacing: 2.0,
color: Colors.black,
fontWeight: FontWeight.w400
)
),
WidgetSpan(
child: GestureDetector(
onTap: (){
speak(allverse[index]['t']);
},
child: Icon(Icons.mic, size: 23)
),
),
],
),
),
),
// Expanded(
// child: RichText(
// text: TextSpan(
//
// text:allverse[index]['t'],
// style: TextStyle(
//
// color: Colors.black, fontSize:19,
//
//
// ),
//
// ),
//
// ),
//
// ),
GestureDetector(
onTap: (){
String verse=allverse[index]['t'];
String versenumber=allverse[index]['v'].toString();
Share.share('${widget.bookname} ${widget.chapternumber}:${versenumber}\n${verse}');
},
child: Icon(
Icons.share,
color: Colors.pinkAccent,
),
)
],
),
Padding(
padding: EdgeInsets.only(left: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children:[
//favourite here....
],
),
)
],
),
// child: Card(
// elevation: 1.1,
// color: index ==versenumber? Colors.yellowAccent:Colors.white,
// child: ListTile(
// leading: CircleAvatar(
// backgroundColor: Colors.lightBlue,
// //backgroundColor:Colors.primaries[Random().nextInt(Colors.primaries.length)] ,
// radius: 12,
// child: Text(allverse[index]['v'].toString(),style: TextStyle(
// color: Colors.white,
// fontSize:12
// ),),
// ),
// title: Column(
// children: [
// RichText(text: TextSpan(
// text: allverse[index]['t'],
// style: TextStyle(
// color: Colors.black, fontSize: 16),
//
// ),),
// Row(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
// children: [
// Icon(
// Icons.favorite_border,
// color: Colors.red[500],
// ),
// Icon(
// Icons.speaker,
// color: Colors.red[500],
// ),
// ],
// )
// ],
//
// ),
//
// trailing: Icon(
// Icons.share,
// color: Colors.red,
// ),
// ),
// ),
),
);
},
),
)
);
}
}
Related
I'm trying to get a list of veterinary clinics within a certain radius using google-maps-api. I am able to get the clinics in one radius but not getting any results when trying to add more radius' with a dropdownbutton. the radius' should be 2.5km,5km and 10km radius. this is my code:
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/src/widgets/container.dart';
import 'package:flutter/src/widgets/framework.dart';
import 'package:flutter_rating_bar/flutter_rating_bar.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:geolocator/geolocator.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:vet_bookr/constant.dart';
import 'package:vet_bookr/models/vet_clinic.dart';
import 'package:vet_bookr/oScreens/vetMaps.dart';
import 'package:http/http.dart' as http;
import '../utils/constants.dart';
class PetClinicsPage extends StatefulWidget {
// PetClinicsPage(this.vetClinic);
const PetClinicsPage({super.key});
#override
State<PetClinicsPage> createState() => _PetClinicsPageState();
}
class _PetClinicsPageState extends State<PetClinicsPage> {
bool isLoading = true;
String dropdownvalue = 'in 2.5Kms';
var apiChanger = 0;
var apis = [
'in 2.5Kms',
'in 5Kms',
'in 10Kms',
];
#override
void initState() {
// TODO: implement initState
super.initState();
getTotalData();
}
late List<VetClinic>? vetClinic;
late GoogleMapController googleMapController;
static const String _kLocationServicesDisabledMessage =
'Location services are disabled.';
static const String _kPermissionDeniedMessage = 'Permission denied.';
static const String _kPermissionDeniedForeverMessage =
'Permission denied forever.';
static const String _kPermissionGrantedMessage = 'Permission granted.';
void _onMapCreated(GoogleMapController controller) {
googleMapController = controller;
}
Set<Marker> _markers = Set<Marker>();
Future<Position> determinePosition() async {
///Check if location is enabled
bool isLocationEnabled = await Geolocator.isLocationServiceEnabled();
if (!isLocationEnabled) {
return Future.error(_kLocationServicesDisabledMessage);
}
/**
* Request Location Permission
*/
await Geolocator.requestPermission();
///Check if the kind of permission we got
LocationPermission locationPermission = await Geolocator.checkPermission();
if (locationPermission == LocationPermission.denied) {
return Future.error(_kPermissionDeniedMessage);
}
if (locationPermission == LocationPermission.deniedForever) {
return Future.error(_kPermissionDeniedForeverMessage);
}
return Geolocator.getCurrentPosition();
}
Future<List<double>> getLatLng() async {
Position position = await determinePosition();
List<double> latLong = [position.latitude, position.longitude];
return latLong;
}
Future<void> getTotalData() async {
List<double> latLng = await getLatLng();
String vetsUrl = "https://maps.googleapis.com/maps/api/place/nearbysearch/json?keyword=vets&location=${latLng[0]},${latLng[1]}&radius=$apiChanger&type=veterinary_care&key=${Constants.apiKey}";
///Getting the data
final response = await http.get(Uri.parse(vetsUrl));
final Map<String, dynamic> data = jsonDecode(response.body);
print(data);
vetClinic = (data["results"] as List).map((vetJson) {
print(vetJson);
return VetClinic.fromJson(vetJson);
}).toList();
print(vetClinic);
/**
* Adding the markerss
*/
if (!mounted) return;
setState(() {
isLoading = false;
});
}
clinicTile(data) {
return GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => VetsMaps(
vetClinic: data,
)));
},
child: Container(
margin: EdgeInsets.only(top: 0.03.sh),
width: 0.9.sw,
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.sp),
),
child: Padding(
padding: EdgeInsets.all(10.0.sp),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
data.name,
style: TextStyle(
fontSize: 16.sp,
fontWeight: FontWeight.w400,
color: Color(0xffFF8B6A)),
),
SizedBox(
height: 0.008.sh,
),
Text(
data.address,
style:
TextStyle(fontSize: 11.sp, fontWeight: FontWeight.w300),
),
SizedBox(
height: 0.005.sh,
),
Text(
data.timing ? "Currently Open" : "Currently Closed",
style: TextStyle(
fontSize: 15.sp,
color:
data.timing ? Colors.greenAccent : Colors.redAccent),
),
SizedBox(
height: 0.005.sh,
),
Container(
child: RatingBar.builder(
initialRating: data.rating,
direction: Axis.horizontal,
allowHalfRating: true,
itemCount: 5,
itemPadding: EdgeInsets.symmetric(horizontal: 1.0),
itemSize: 0.03.sh,
itemBuilder: (context, _) => Icon(
Icons.star,
color: Colors.amber,
),
onRatingUpdate: (rating) {
print(rating);
},
ignoreGestures: true,
),
)
],
),
),
),
),
);
}
void apisChanger() async {
if(dropdownvalue == apis[0]){
apiChanger = 2500;
}
if(dropdownvalue == apis[1]){
apiChanger = 5000;
}
if(dropdownvalue == apis[2]){
apiChanger = 10000;
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.transparent,
elevation: 0,
leading: IconButton(
icon: Icon(
Icons.arrow_back,
color: Colors.black,
),
onPressed: () {
Navigator.pop(context);
},
),
),
backgroundColor: kBackgroundColor,
body: SingleChildScrollView(
child: Padding(
padding: EdgeInsets.only(top: 10.sp, left: 10.sp, right: 10.sp),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// sBox(h: 10),
Row(
children: [
Padding(
padding: EdgeInsets.only(left: 10.0.sp, top: 15.sp),
child: Text(
'Veterinary Clinics Near Me',
style: TextStyle(color: Colors.deepOrange[300], fontSize: 22),
),
),
Container(
padding: EdgeInsets.only(top: 0.02.sh, left: 0.01.sw),
height: 0.04.sh,
child: DropdownButton(
value: dropdownvalue,
underline: SizedBox(),
icon: const Icon(Icons.keyboard_arrow_down),
items: apis.map((String items) {
return DropdownMenuItem(
value: items,
child: Text(items),
);
}).toList(),
onChanged: (String? newValue) {
apisChanger();
setState(() {
dropdownvalue = newValue!;
});
},
),
), ],
),
Divider(
thickness: 2,
color: Colors.deepOrange[300],
indent: 15,
endIndent: 10,
),
// sBox(h: 1),
isLoading
? Container(
width: 1.sw,
height: 0.7.sh,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
height: 15.sp,
width: 15.sp,
child: CircularProgressIndicator(
strokeWidth: 2,
color: Color(0xffFF8B6A),
),
),
],
),
)
: ListView.builder(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemCount: vetClinic?.length,
itemBuilder: ((context, index) {
return clinicTile(vetClinic![index]);
}),
)
],
),
),
),
);
}
}
ive tried creating a variable which changes depending on the index of the array for the dropdown button but when i try this it doesnt work
am building a flutter app and am am working with a data from a API i got the list and evreything i did a search bar that works properly by typing either the number of the ticket or the description but am trying to add a new filter , a checkbox that filters the data i have 2 problems
1: when i press on a checkbox and type confirm it works and it shows but the checkbox dosent stay checked
2: how can i implement it so it filter the data from the api directly
and thank you
// ignore_for_file: use_key_in_widget_constructors, avoid_print, avoid_unnecessary_containers, curly_braces_in_flow_control_structures, prefer_const_constructors, non_constant_identifier_names, unnecessary_new, avoid_function_literals_in_foreach_calls, unused_import, avoid_types_as_parameter_names, unused_label, unused_element, file_names, library_private_types_in_public_api, unnecessary_string_interpolations
import 'dart:convert';
import 'dart:io';
import 'package:az/Actifs.dart';
import 'package:az/SR_Details.dart';
import 'package:az/main.dart';
import 'package:badges/badges.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:http/http.dart' as http;
import 'package:intl/intl.dart';
import 'class/sr.dart';
import 'package:dropdown_search/dropdown_search.dart';
class DataFromAPI extends StatefulWidget {
#override
_DataFromAPIState createState() => _DataFromAPIState();
}
List<Sr> _MyAllData=[];
List<Sr> _SrForDsiplay=[];
Map<String, Color> map={
"QUEUED":Color.fromARGB(255, 255, 136, 0),
"CLOSED":Colors.grey,
"Rejected":Colors.red,
"INPROG":Colors.green,
"PENDING":Colors.blue,
"RESOLVED":Colors.green,
"NEW":Colors.blue,
};
Map<String, String> map1={
"1":"Urgent",
"2":"High",
"3":"Medium",
"4":"Low",
};
/*Map<String, Color> map3={
"Urgent":Colors.red,
"High":Color.fromARGB(255, 255, 139, 131),
"Medium":Colors.blue,
"Low":Colors.green,
"null":Colors.grey,
};*/
class Multiselect extends StatefulWidget {
final List<String> items;
const Multiselect({Key? key, required this.items}) : super(key: key);
#override
State<Multiselect> createState() => _MultiselectState();
}
class _MultiselectState extends State<Multiselect> {
final List<String> _selectedItems=[];
void _itemChange(String itemValue, bool isSelected) {
setState(() {
if (isSelected) {
_selectedItems.add(itemValue);
} else {
_selectedItems.remove(itemValue);
}
});
}
// this function is called when the Cancel button is pressed
void _cancel() {
Navigator.pop(context);
}
// this function is called when the Submit button is tapped
void _submit() {
Navigator.pop(context, _selectedItems);
}
#override
Widget build(BuildContext context) {
return AlertDialog(
title: const Text('Select Topics'),
content: SingleChildScrollView(
child: ListBody(
children: widget.items
.map((item) => CheckboxListTile(
value: _selectedItems.contains(item),
title: Text(item),
controlAffinity: ListTileControlAffinity.leading,
onChanged: (isChecked) => _itemChange(item, isChecked!),
))
.toList(),
),
),
actions: [
TextButton(
onPressed: _cancel,
child: const Text('Cancel'),
),
ElevatedButton(
onPressed: _submit,
child: const Text('Submit'),
),
],
);
}
}
class _DataFromAPIState extends State<DataFromAPI> {
List<String> _selectedItems=[];
String title_string = "Liste des SR :";
void _ShowMultiSelect() async{
final List<String> items=[
'QUEUED',
'CLOSED',
'Rejected',
'INPROG',
'PENDING',
'RESOLVED',
'NEW',
];
final List<String>? results =await showDialog(
context: context,
builder: (BuildContext context) {
return Multiselect(items: items);
},
);
if(results !=null){
setState(() {
_selectedItems=results;
});
}
}
#override
void initState() {
loadData().then((value) {
_MyAllData.clear();
setState(() {
_MyAllData.addAll(value);
_SrForDsiplay=_MyAllData;
});
});
super.initState();
}
Future<List<Sr>> loadData() async {
try {
var response = await http.get(Uri.parse(
'http:MXSR/?_lid=&_lpwd=&_format=json'));
if (response.statusCode == 200) {
final jsonBody = json.decode(response.body);
Demandes data = Demandes.fromJson(jsonBody);
final srAttributes = data.queryMxsrResponse.mxsrSet.sr;
title_string='Liste des SR : ${srAttributes.length.toString()}';
return srAttributes;
}
} catch (e) {
throw Exception(e.toString());
}
throw Exception("");
}
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner:false,
home: new Scaffold(resizeToAvoidBottomInset: false ,
appBar: AppBar(
title: Text(title_string),
leading: IconButton(
icon: Icon(Icons.arrow_back), onPressed: () { Navigator.push(
context, MaterialPageRoute(builder: (context) => Home())); },
),
flexibleSpace: InkWell(onTap: () {
},),
),
body: FutureBuilder<List<Sr>?>(
future: loadData(),
builder: (context, snapshot) {
if (_MyAllData.isEmpty) {
return SizedBox(
height: MediaQuery.of(context).size.height / 1.3,
child: Center(
child: CircularProgressIndicator(),
),
);
} else { return
ListView(
children: <Widget>[Padding(
padding: const EdgeInsets.all(8.0),
child: Column(children:<Widget>[ElevatedButton(onPressed: _ShowMultiSelect,
child: const Text('Filter')),
const Divider(
height: 30,
),
Wrap(
children: _selectedItems
.map((e) => Chip(
label: Text(e),
))
.toList(),
),
Row(children:<Widget>[ Expanded(
child: TextField(
decoration:
InputDecoration( hintText: "Enter id or description"),
onChanged: (text) {
text=text.toLowerCase();
setState(() {
_SrForDsiplay =_MyAllData.where((srAttributes) {
var srDescription = srAttributes.attributes.description!.content.toString().toLowerCase();
var srID= srAttributes.attributes.ticketid.content.toString();
return srDescription.contains(text) || srID.contains(text);
}).toList();
title_string='Liste des SR : ${_SrForDsiplay.length.toString()}';
print(title_string);
}
);
},
)),])
],
),),
new ListView.builder(scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: _SrForDsiplay.length,
itemBuilder: ((_, index) {
return
new ListTile(
title: new Card(
margin: new EdgeInsets.symmetric(
vertical: 2.0, horizontal: 8.0),
elevation: 10,
child: new ListTile(
title: new Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(padding: new EdgeInsets.all(2.0)),
Row(children :[
Container(
decoration: BoxDecoration(
border: Border.all(
color: Color.fromARGB(255, 255, 255, 255),
),
color: map['${_SrForDsiplay[index].attributes.status.content}'],
borderRadius: BorderRadius.all(Radius.circular(20)),
),
child:Text(' ${_SrForDsiplay[index].attributes.status.content} '),
),
Container(child: Text(' '),),
Container(
decoration: BoxDecoration(
border: Border.all(
color: Color.fromARGB(255, 255, 255, 255),
),
color:Colors.grey,
borderRadius: BorderRadius.all(Radius.circular(20)),
),
child:Text( map1['${_SrForDsiplay[index].attributes.reportedpriority?.content}'] ?? " null "),
),
],
),
SizedBox(
height: 8,
),
Row(children: <Widget>[
Expanded( child: Container(child: Text('${_SrForDsiplay[index].attributes.description?.content}',style: GoogleFonts.openSans(
textStyle: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600)),),),),
Expanded(child: Container(child:Text( ' ${_SrForDsiplay[index].attributes.ticketid.content}',style: GoogleFonts.openSans(
textStyle: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w400)),)))
],),
new Divider(
color: Color.fromARGB(255, 110, 109, 109),
),
Text(
'Reported : ${DateFormat.yMMMMEEEEd().format(DateTime.parse('${_SrForDsiplay[index].attributes.statusdate.content}' ))}' ,
style: GoogleFonts.openSans(
textStyle: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w400)),
),
new Text(
'Reported by : ${_SrForDsiplay[index].attributes.reportedby?.content}',style: GoogleFonts.openSans(
textStyle: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w400)),
),
Row(children: [new Image(image: AssetImage('assets/courroi.png'), width: 20),
Text(
'${_SrForDsiplay[index].relatedMbos?.asset[0].attributes.descriptionasset?.content}'),], ),
Row(children: [new Image(image: AssetImage('assets/emp.png'), width: 20),
Text(
'${_SrForDsiplay[index].attributes.assetsiteid?.content}'),], ) ,
Divider(
color: Color.fromARGB(255, 110, 109, 109),
),
Row(children:[
Expanded(child: Badge(
position: BadgePosition.topEnd(top: -8, end: 20),
badgeColor: Colors.grey,
badgeContent: Text('1'),
child :IconButton(icon :Icon(Icons.file_present_rounded), padding: const EdgeInsets.all(0),
onPressed: () {
},
),
)
),
Expanded(child: IconButton (
icon: Icon(Icons.file_copy),
onPressed: () { },
),),
Expanded(child: IconButton(onPressed:() {
}, icon: Icon(Icons.delete)) )
],)
],
),
trailing: Icon(Icons.arrow_forward_ios_rounded),
),
),
onTap: () {
Navigator.push(
context,MaterialPageRoute(builder: (context) =>SrDetailsScreen(sr: _SrForDsiplay[index])),
);
}
);
}
),
)
]
);
}
},
),
),
);
}
}
i am adding shuffle() function but the error is showing Another exception was thrown: type 'String' is not a subtype of type 'int' of 'index' is there any solution to put question in shuffle i don't know where to add this shuffle function there was not any error in this project the json files is added with this code
i am adding mydata.shuffle() in this code
#override
Widget build(BuildContext context) {
setasset();
return FutureBuilder(
future:
DefaultAssetBundle.of(context).loadString(assettoload, cache: false),
builder: (context, snapshot) {
List? mydata = json.decode(snapshot.data.toString());
if (mydata == null) {
return Scaffold(
body: Center(
child: Text(
"Loading",
),
),
);
} else {
return quizpage(mydata: mydata);
}
},
);
}
}
class quizpage extends StatefulWidget {
final List mydata;
quizpage({required this.mydata});
#override
_quizpageState createState() => _quizpageState();
}
class _quizpageState extends State<quizpage> {
_quizpageState();
Color colortoshow = Colors.indigoAccent;
int marks = 0;
int i = 1;
bool disableAnswer = false;
// extra varibale to iterate
int timer = 30;
String showtimer = "30";
Map<String, Color> btncolor = {
"a": Colors.indigo.shade900,
"b": Colors.indigo.shade900,
"c": Colors.indigo.shade900,
"d": Colors.indigo.shade900,
};
bool canceltimer = false;
#override
void initState() {
starttimer();
super.initState();
}
#override
void setState(fn) {
if (mounted) {
super.setState(fn);
}
}
void starttimer() async {
const onesec = Duration(seconds: 1);
Timer.periodic(onesec, (Timer t) {
setState(() {
if (timer < 1) {
t.cancel();
nextquestion();
} else if (canceltimer == true) {
t.cancel();
} else {
timer = timer - 1;
}
showtimer = timer.toString();
});
});
}
void nextquestion() {
canceltimer = false;
timer = 30;
setState(() {
if (i < 10) {
i++;
} else {
Navigator.of(context).pushReplacement(MaterialPageRoute(
builder: (context) => resultpage(marks: marks),
));
}
btncolor["a"] = Colors.indigo.shade900;
btncolor["b"] = Colors.indigo.shade900;
btncolor["c"] = Colors.indigo.shade900;
btncolor["d"] = Colors.indigo.shade900;
disableAnswer = false;
});
starttimer();
}
void checkanswer(String k) {
if (widget.mydata[2][i.toString()] == widget.mydata[1][i.toString()][k]) {
marks = marks + 5;
} else {}
setState(() {
btncolor[k] = colortoshow;
canceltimer = true;
disableAnswer = true;
});
Timer(Duration(seconds: 2), nextquestion);
}
Widget choicebutton(String k) {
return Padding(
padding: EdgeInsets.symmetric(
vertical: 10.0,
horizontal: 20.0,
),
child: SizedBox(
height: 60,
width: 400,
child: OutlinedButton(
onPressed: () => checkanswer(k),
child: Text(
widget.mydata[1][i.toString()][k] ?? "",
style: TextStyle(
fontWeight: FontWeight.w600,
color: Colors.black,
fontFamily: "Alike",
fontSize: 18.0,
),
maxLines: 1,
),
style: OutlinedButton.styleFrom(
side: BorderSide(width: 3.0, color: Colors.indigo.shade900),
backgroundColor: Colors.transparent,
shape: const StadiumBorder()),
),
),
);
}
#override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations(
[DeviceOrientation.portraitDown, DeviceOrientation.portraitUp]);
return WillPopScope(
onWillPop: () async {
return await showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text(
"Quizstar",
),
content: Text("You Can't Go Back At This Stage."),
actions: <Widget>[
ElevatedButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text(
'Ok',
),
)
],
));
},
child: SafeArea(
child: Scaffold(
body: Column(
children: <Widget>[
Expanded(
flex: 3,
child: Container(
width: 500,
height: 200,
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage(
"assets/canva4.png",
),
fit: BoxFit.cover,
),
),
padding: EdgeInsets.all(15.0),
alignment: Alignment.bottomLeft,
child: Text(
widget.mydata[0][i.toString()],
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.w700,
fontSize: 20.0,
fontFamily: "Quando",
),
),
),
),
Divider(height: 10, color: Colors.black, thickness: 10),
Expanded(
flex: 6,
child: AbsorbPointer(
absorbing: disableAnswer,
child: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
choicebutton('a'),
choicebutton('b'),
choicebutton('c'),
choicebutton('d'),
],
),
),
),
),
Expanded(
flex: 1,
child: Container(
alignment: Alignment.topCenter,
child: Center(
child: Text(
showtimer,
style: TextStyle(
fontSize: 35.0,
fontWeight: FontWeight.w700,
fontFamily: 'Times New Roman',
),
),
),
),
),
],
),
),
),
);
}
}
I'm trying to accomplished something like had been issued here : Flutter single `DataCell` color
I want to grey out the cell to let user know that was supposed to leave blank. Currently I manage to fill the height of datacell but the width.
my code snippet:
_data[i][newColumn] = Container(
width: double.infinity,
height: double.infinity,
color: Colors.grey,
child: Text(''));
Result: Last cell at the most right which fill up height space only:
full code :
import 'dart:convert';
import 'dart:ui';
import 'package:http/http.dart';
import 'package:flutter/material.dart';
class InspectionSheet extends StatefulWidget {
const InspectionSheet({Key? key}) : super(key: key);
#override
State<InspectionSheet> createState() => _InspectionSheetState();
}
class _InspectionSheetState extends State<InspectionSheet> {
GlobalKey<FormState> _formKey = new GlobalKey();
bool validate = false;
TextEditingController ctrlsampleSize = TextEditingController();
final List<Map<String, dynamic>> _data = [
{
//"checkitemID": "0",
"Ballooning No": "1",
"Datatype": "1",
"Specifications": ".325+-0.020",
"Tool": "CALIPER",
"LSL": "0.305",
"Target": "2",
"USL": "0.325",
"Tol-": "0.02",
"Tol+": "0.02",
"Image": "",
"WI": ""
},
{
//"checkitemID": "0",
"Ballooning No": "2",
"Datatype": "2",
"Specifications": ".325+-0.020",
"Tool": "CALIPER",
"LSL": "0.305",
"Target": "2",
"USL": "0.325",
"Tol-": "0.02",
"Tol+": "0.02",
"Image": "",
"WI": ""
},
];
late List<String> _columnNames;
//String _selectedValue = inputList.first;
String _selectedValue = 'PASS';
void startbutton() {
validateEmpty();
if (_formKey.currentState!.validate()) {
addDataCol();
}
}
void validateEmpty() {
//if (_formKey.currentState!.validate()) {
// // If the form is valid, display a snackbar. In the real world,
// // you'd often call a server or save the information in a database.
// ScaffoldMessenger.of(context).showSnackBar(
// const SnackBar(content: Text('Processing Data')),
// );
ctrlsampleSize.text.isEmpty ? validate = false : validate = true;
//}
}
void addDataCol() {
int colNo = int.parse(ctrlsampleSize.text);
if (colNo < 1) {
return;
}
setState(() {
for (var i = 1; i <= colNo; i++) {
_addColumn('Data $i');
}
});
}
void _addColumn(String newColumn) {
if (_columnNames.contains(newColumn)) {
return;
}
setState(() {
for (var i = 0; i <= _data.length - 1; i++) {
if (_data[i]['Datatype'] == '1') {
_data[i][newColumn] = TextFormField();
} else if (_data[i]['Datatype'] == '2') {
_data[i][newColumn] = DropdownButton<String>(
value: _selectedValue,
icon: const Icon(Icons.arrow_drop_down_circle_outlined),
elevation: 16,
underline: Container(
height: 2,
color: Colors.blue,
),
onChanged: (newValue) {
setState(() {
_selectedValue = newValue!;
});
},
items:
// inputList.map<DropdownMenuItem<String>>((String value) {
// return DropdownMenuItem<String>(
// value: value,
// child: Text(value),
// onTap: () {
// _selectedValue = value;
// },
// );
// }).toList(),
[
DropdownMenuItem(
value: 'PASS',
child: const Text('PASS'),
onTap: () {
_selectedValue = 'PASS';
},
),
DropdownMenuItem(
value: 'FAIL',
child: const Text('FAIL'),
onTap: () {
_selectedValue = 'FAIL';
},
),
DropdownMenuItem(
value: 'UAI',
child: const Text('UAI'),
onTap: () {
_selectedValue = 'UAI';
},
),
DropdownMenuItem(
value: 'NA',
child: const Text('NA'),
onTap: () {
_selectedValue = 'NA';
},
)
]);
} else if (_data[i]['Datatype'] == '3') {
if (newColumn == 'Data 1') {
_data[i][newColumn] = TextButton(
onPressed: () {
_displayTextInputDialog(context);
},
child: const Text('-'));
} else {
_data[i][newColumn] = Container(
width: double.infinity,
height: double.infinity,
color: Colors.grey,
child: Text(''));
}
} else {
_data[i][newColumn] = TextButton(
onPressed: () {
_displayTextInputDialog(context);
},
child: const Text('-'));
}
}
_columnNames.add(newColumn);
});
}
#override
void initState() {
dateInput.text = "";
_columnNames = _data[0].keys.toList();
//set the initial value of text field
super.initState();
//// Start listening to changes.
ctrlsampleSize.addListener(() {});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: ListView(
children: [
Form(
child: Row(
children: [
Container(
width: MediaQuery.of(context).size.width,
height: 210,
child: Form(
key: _formKey,
child: ListView(
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Container(
width: 200,
height: 200,
child: Column(
children: <Widget>[
TextFormField(
controller: ctrlsampleSize,
validator: ((value) {
if (value == null || value.isEmpty) {
return 'Please enter sample size';
}
return null;
}),
],
),
),
Padding(
padding: const EdgeInsets.fromLTRB(0, 5, 0, 0),
child: Container(
width: 400,
height: 200,
decoration: BoxDecoration(
border: Border.all(color: Colors.black),
image: DecorationImage(
image: AssetImage('images/Test1.jpg'),
fit: BoxFit.fill,
)),
),
),
],
),
],
),
),
Container(
child: Container(
child: Center(
child: Row(
// add Column
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Padding(
padding: const EdgeInsets.fromLTRB(15, 15, 860, 0),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: const [
Text(
"Total Parameter : 6",
textAlign: TextAlign.left,
style: TextStyle(
fontSize: 16, fontWeight: FontWeight.bold),
),
],
),
),
Padding(
padding: const EdgeInsets.fromLTRB(15, 15, 8, 0),
child: ElevatedButton(
onPressed: () => startbutton(),
child: const Text('Start'),
),
),
Padding(
padding: const EdgeInsets.fromLTRB(15, 15, 8, 0),
child: ElevatedButton(
onPressed: () {},
child: const Text('Reset'),
),
),
Padding(
padding: const EdgeInsets.fromLTRB(15, 15, 8, 0),
child: ElevatedButton(
onPressed: () {},
child: const Text('Save'),
),
),
],
),
),
)),
Padding(
padding: const EdgeInsets.all(8.0),
child:
//****uncomment if use Provider */
// Container(
// decoration: BoxDecoration(
// border: Border.all(color: Colors.black),
// ),
// child: ConstrainedBox(
// constraints: const BoxConstraints(
// maxHeight: 600,
// maxWidth: 813,
// ),
// child: Column(
// children: [
// Expanded(
// child: ChangeNotifierProvider<CheckItemProvider>(
// create: (context) => CheckItemProvider(),
// child: Consumer<CheckItemProvider>(
// builder: (context, provider, child) {
// provider.getData(context);
// return const Center(
// child: CircularProgressIndicator());
// // when we have the json loaded... let's put the data into a data table widget
// return
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: DataTable(
headingRowHeight: 30,
border: TableBorder.all(
color: Colors.grey,
),
headingRowColor: MaterialStateColor.resolveWith(
(states) => Colors.lightBlue),
headingTextStyle: const TextStyle(
color: Colors.white, fontWeight: FontWeight.w800),
columns: _columnNames.map((columnName) {
return DataColumn(
label: Text(
columnName,
// style: const TextStyle(
// fontSize: 18,
// fontWeight: FontWeight.w600,
// ),
),
);
}).toList(),
rows:
_data // Loops through dataColumnText, each iteration assigning the value to element
.map((row) {
return DataRow(
cells: row.values.map((cellValue) {
try {
return DataCell(
cellValue,
onTap: () {},
);
} catch (e) {
return DataCell(Text(cellValue));
}
;
}).toList());
}).toList(),
),
),
),
//},
// ),
// ),
// ),
// ],
// ),
// ),
// ),
),
],
),
);
}
}
Im using table_calendar package in my project, but ive faced two problems so far :
The calendar doesnt load todays events below the calendar, i would love to hear some ideas how to get this one done.
Even if i put (code below) in tables parameters, it doesnt allow to switch calendar modes.
code for swiching calendar modes for 2nd bullet point of my problems:
availableCalendarFormats: const {
CalendarFormat.month: '',
CalendarFormat.week: '',
},
Just in case, here is the whole code for page which has problems :
class Lecture_graph extends StatefulWidget {
Lecture_graph({Key key}) : super(key: key);
#override
State<Lecture_graph> createState() => myLectureGraph();
}
class myLectureGraph extends State<Lecture_graph>
with TickerProviderStateMixin {
List _selectedEvents;
DateTime _selectedDate = DateTime.now();
Map<DateTime, List<Lecture>> _events;
CalendarController _calendarController;
AnimationController _animationController;
List<Lecture> _lectures;
String coursecode = "";
bool isJoin, isBreaks = false;
bool isLoading = true;
final Map<DateTime, List> _holidays = {
// DateTime(2021, 1, 1): ['New Year\'s Day'],
// DateTime(2021, 2, 14): ['Valentine\'s Day'],
// DateTime(2021, 3, 8): ['Woman\'s Day'],
};
Future<Map<DateTime, List>> getLectures(DateTime _selectedDate) async {
print("getLectures started.");
setState(() {
isLoading = true;
});
Map<DateTime, List<Lecture>> mapFetch = {};
//get saved course
if (coursecode == "" || coursecode == null) {
coursecode = await _checkSavedCourse();
//debug
print('courscode recieved from sharedprefs');
}
//build request URL
var requestURL =
'https://lekcijas.va.lv/lekcijas_android/getMonthLectures.php?date=' +
DateFormat('yyyy-MM').format(_selectedDate) +
(isBreaks ? "&breaks" : "") +
(isJoin ? "&join" : "") +
"&program=" +
coursecode +
"&lang=" +
AppLocalizations.of(context).translate('request_language');
print("Lecture request url : $requestURL");
//wait for response
var response = await http.get(Uri.parse(requestURL));
var data = json.decode(response.body)["result"];
//clear array after each request
if (_lectures != null) _lectures.clear();
try {
//create lectures from json response
_lectures = List<Lecture>.from(data.map((x) => Lecture.fromJson(x)));
} on Exception catch (_) {
print("Error occured getting lectures");
}
_lectures.forEach((element) {
if (mapFetch[element.lecture_date] != null) {
mapFetch[element.lecture_date] += [element];
} else {
mapFetch[element.lecture_date] = [element];
}
});
setState(() {
isLoading = false;
});
print("getLectures finished.");
return mapFetch;
}
Future<void> _saveVales(String key, bool value) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
print("Sharedpref $key is set to $value now");
prefs.setBool(key, value);
}
Future<void> _checkSavedParameters() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
isBreaks = prefs.getBool('lectures_breaks') == null
? false
: prefs.getBool('lectures_breaks');
isJoin = prefs.getBool('lectures_join') == null
? false
: prefs.getBool('lectures_join');
}
Future<String> _checkSavedCourse() async {
//check saved parameters for lecture requests too
await _checkSavedParameters();
SharedPreferences prefs = await SharedPreferences.getInstance();
String _coursecode = prefs.getString('savedCourse');
if (_coursecode == "" || _coursecode == null) {
Navigator.pop(context);
Navigator.push(
context,
MaterialPageRoute(builder: (context) => CourseSelectionPage()),
);
return null;
} else {
return _coursecode;
}
}
void _onDaySelected(DateTime day, List events) {
print('CALLBACK: _onDaySelected');
setState(() {
_selectedEvents = events;
});
}
#override
void initState() {
super.initState();
//enable portrait only mode
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]);
_selectedEvents = [];
_calendarController = CalendarController();
_animationController = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 400),
);
_animationController.forward();
WidgetsBinding.instance.addPostFrameCallback((_) {
getLectures(_selectedDate).then((val) => setState(() {
_events = val;
}));
});
}
#override
void dispose() {
_calendarController.dispose();
//unlock orientation mode
SystemChrome.setPreferredOrientations([
DeviceOrientation.landscapeRight,
DeviceOrientation.landscapeLeft,
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]);
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(coursecode +
" | " +
AppLocalizations.of(context).translate('lectures_title')),
actions: <Widget>[
IconButton(
icon: Icon(
Icons.settings,
color: Colors.white,
),
onPressed: () {
showDialog(
context: context,
builder: (context) {
return StatefulBuilder(
builder: (context, setState) {
return AlertDialog(
title: Text(
AppLocalizations.of(context).translate('settings')),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
Row(
children: [
CupertinoSwitch(
value: isJoin,
onChanged: (bool value) {
_saveVales('lectures_join', value);
isJoin = value;
WidgetsBinding.instance
.addPostFrameCallback((_) {
getLectures(_selectedDate)
.then((val) => setState(() {
_events = val;
}));
});
},
),
Text(AppLocalizations.of(context)
.translate('join_lectures'))
],
),
SizedBox(height: 10),
Row(
children: [
CupertinoSwitch(
value: isBreaks,
onChanged: (bool value) {
_saveVales('lectures_breaks', value);
isBreaks = value;
WidgetsBinding.instance
.addPostFrameCallback((_) {
getLectures(_selectedDate)
.then((val) => setState(() {
_events = val;
}));
});
},
),
Text(AppLocalizations.of(context)
.translate('show_breaks'))
],
),
SizedBox(height: 10),
SizedBox(
width: double.infinity,
child: OutlinedButton(
onPressed: () {
//close popup
Navigator.pop(context);
//close page
Navigator.pop(context);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
CourseSelectionPage()),
);
},
child: Text(
AppLocalizations.of(context)
.translate('select_course'),
style: TextStyle(color: Colors.lime),
)),
)
],
),
actions: <Widget>[
FlatButton(
onPressed: () => Navigator.pop(context),
child: Text(AppLocalizations.of(context)
.translate('close')),
),
],
);
},
);
},
);
},
)
],
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
isLoading
? Expanded(child: Center(child: CircularProgressIndicator()))
: _buildTableCalendarWithBuilders(),
const SizedBox(height: 2.0),
Expanded(child: _buildEventList()),
],
),
),
);
}
Widget _buildTableCalendarWithBuilders() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Card(
color: Colors.white,
margin: const EdgeInsets.all(8.0),
clipBehavior: Clip.antiAlias,
child: TableCalendar(
locale:
AppLocalizations.of(context).translate('request_language') ==
'lv'
? "lv_LV"
: "en_US",
initialSelectedDay: _selectedDate,
calendarController: _calendarController,
events: _events,
holidays: _holidays,
initialCalendarFormat: CalendarFormat.month,
formatAnimation: FormatAnimation.scale,
startingDayOfWeek: StartingDayOfWeek.monday,
availableGestures: AvailableGestures.all,
availableCalendarFormats: const {
CalendarFormat.month: '',
CalendarFormat.week: '',
},
calendarStyle: CalendarStyle(
outsideDaysVisible: false,
weekendStyle: TextStyle().copyWith(color: Colors.blue[800]),
holidayStyle: TextStyle().copyWith(color: Colors.blue[800]),
),
daysOfWeekStyle: DaysOfWeekStyle(
weekendStyle: TextStyle().copyWith(color: Colors.blue[600]),
),
headerStyle: HeaderStyle(
centerHeaderTitle: true,
formatButtonVisible: false,
),
builders: CalendarBuilders(
selectedDayBuilder: (context, date, _) {
return FadeTransition(
opacity:
Tween(begin: 0.0, end: 1.0).animate(_animationController),
child: Container(
margin: const EdgeInsets.all(4.0),
padding: const EdgeInsets.only(top: 5.0, left: 6.0),
color: Colors.deepOrange[300],
width: 100,
height: 100,
child: Text(
'${date.day}',
style: TextStyle().copyWith(fontSize: 16.0),
),
),
);
},
todayDayBuilder: (context, date, _) {
return Container(
margin: const EdgeInsets.all(4.0),
padding: const EdgeInsets.only(top: 5.0, left: 6.0),
color: Colors.amber[400],
width: 100,
height: 100,
child: Text(
'${date.day}',
style: TextStyle().copyWith(fontSize: 16.0),
),
);
},
markersBuilder: (context, date, events, holidays) {
final children = <Widget>[];
if (events.isNotEmpty) {
children.add(
Positioned(
right: 1,
bottom: 1,
child: _buildEventsMarker(date, events),
),
);
}
if (holidays.isNotEmpty) {
children.add(
Positioned(
right: -2,
top: -2,
child: _buildHolidaysMarker(),
),
);
}
return children;
},
),
onDaySelected: (date, events, holidays) {
_onDaySelected(date, events);
_animationController.forward(from: 0.0);
},
onVisibleDaysChanged: _onVisibleDaysChanged,
),
),
],
);
}
void _onVisibleDaysChanged(
DateTime first, DateTime last, CalendarFormat format) {
_selectedDate = first;
WidgetsBinding.instance.addPostFrameCallback((_) {
getLectures(_selectedDate).then((val) => setState(() {
_events = val;
}));
});
print('CALLBACK: _onVisibleDaysChanged');
}
Widget _buildEventsMarker(DateTime date, List events) {
return AnimatedContainer(
duration: const Duration(milliseconds: 300),
decoration: BoxDecoration(
shape: BoxShape.circle,
color: _calendarController.isSelected(date)
? Colors.brown[500]
: _calendarController.isToday(date)
? Colors.brown[300]
: Colors.green[400],
),
width: 18.0,
height: 18.0,
child: Center(
child: Text(
'${events.length}',
style: TextStyle().copyWith(
color: Colors.white, fontSize: 12.0, fontWeight: FontWeight.w900),
),
),
);
}
Widget _buildHolidaysMarker() {
return Icon(
Icons.add_box,
size: 20.0,
color: Colors.blueGrey[800],
);
}
Widget _buildEventList() {
return ListView(
children: _selectedEvents.reversed
.map((lecture) => Container(
decoration: BoxDecoration(
border: Border.all(width: 0.1),
// borderRadius: BorderRadius.circular(2.0),
color: hexToColor(lecture.color),
),
margin:
const EdgeInsets.symmetric(horizontal: 6.0, vertical: 1.5),
child: ListTile(
title: Column(
children: [
Align(
alignment: Alignment.centerLeft,
child: Text(
lecture.start + " - " + lecture.end,
style: new TextStyle(
fontSize: 12.0,
color: Colors.black,
),
),
),
Align(
alignment: Alignment.centerLeft,
child: Text(lecture.lecture,
style: new TextStyle(
fontSize: 16.0,
color: Colors.black,
)),
),
],
),
onTap: () => displayDialog(lecture, context),
),
))
.toList(),
);
}
void displayDialog(Lecture selectedLecture, BuildContext ctx) {
//if selected lecture is a break
if (!selectedLecture.lecturer.isEmpty &&
!selectedLecture.classroom.isEmpty &&
!selectedLecture.programs.isEmpty) {
showDialog(
barrierDismissible: true,
context: ctx,
builder: (BuildContext context) => new AlertDialog(
title: new Text(AppLocalizations.of(context).translate('info_title')),
content: new Wrap(
runSpacing: 5,
children: [
Align(
alignment: Alignment.centerLeft,
child: Text(
AppLocalizations.of(context).translate('info_time') +
selectedLecture.start +
" - " +
selectedLecture.end),
),
Align(
alignment: Alignment.centerLeft,
child: Text(
AppLocalizations.of(context).translate('info_lecturer') +
selectedLecture.lecturer),
),
Align(
alignment: Alignment.centerLeft,
child: Text(
AppLocalizations.of(context).translate('info_classroom') +
selectedLecture.classroom),
),
Align(
alignment: Alignment.centerLeft,
child: Text(
AppLocalizations.of(context).translate('info_lecture') +
selectedLecture.lecture),
),
Align(
alignment: Alignment.centerLeft,
child: Text(
AppLocalizations.of(context).translate('info_date') +
DateFormat('yyyy-MM-dd')
.format(selectedLecture.lecture_date)
.toString()),
),
Align(
alignment: Alignment.centerLeft,
child: Text(
AppLocalizations.of(context).translate('info_programs') +
selectedLecture.programs),
),
],
),
actions: [
new TextButton(
child: Text(AppLocalizations.of(context).translate('close')),
onPressed: () => Navigator.pop(context, true),
),
],
),
);
}
}
}
In case someone wants to see JSON request results, here is the link for that.
So i got this fixed, adding this to TableCalendar() parameters:
(i called selectedEvents variable update once calendar finished building (because im showing CircularProgressIndicator instead of it while i recieve data from http request) )
onCalendarCreated: (d1, d2, cf){WidgetsBinding.instance
.addPostFrameCallback((_) => _onDaySelected(_selectedDate, _events[_selectedDate]));},
changed _onDaySelected method to:
(here i change selectedday variable to day recieved from calendar click and change state of selectedEvents, replacing them with total_events_map[key_which_is_selectedDay])
void _onDaySelected(DateTime day, List events) {
print('CALLBACK: _onDaySelected');
//dates are used with nulled time
_selectedDate = DateTime(day.year, day.month, day.day, 0, 0, 0);
setState(() {
_selectedEvents = _events[_selectedDate];
});
}
and changed _buildEventList() to this :
(so if selectedEvents are empty, it tells user so, if not, generates a list of items from selectedEvents)
Widget _buildEventList() {
if(_selectedEvents == null)
return ListView(
children: [
Card(
clipBehavior: Clip.antiAlias,
margin: const EdgeInsets.all(8.0),
child: ListTile(
title: Column(
children: [
Align(
alignment: Alignment.centerLeft,
child: Text(tr('nothing_planned'),
style: new TextStyle(
fontSize: 16.0,
color: Colors.black,
)),
),
],
),
),
),
],
);
else return ListView(
children: _selectedEvents.reversed
.map((lecture) => Container(
decoration: BoxDecoration(
border: Border.all(width: 0.1),
// borderRadius: BorderRadius.circular(2.0),
color: hexToColor(lecture.color),
),
margin:
const EdgeInsets.symmetric(horizontal: 6.0, vertical: 1.5),
child: ListTile(
title: Column(
children: [
Align(
alignment: Alignment.centerLeft,
child: Text(
lecture.start + " - " + lecture.end,
style: new TextStyle(
fontSize: 12.0,
color: Colors.black,
),
),
),
Align(
alignment: Alignment.centerLeft,
child: Text(lecture.lecture,
style: new TextStyle(
fontSize: 16.0,
color: Colors.black,
)),
),
],
),
onTap: () => displayDialog(lecture, context),
),
))
.toList(),
);
}