Late initialising error in flutter while working with firebase - firebase

I'm working on this app to help people find the fitting wine for their meal. Now I wanted the user to be able to select the specific meal he or she is currently enjoying to have a better prediction what wine fits best. Now I tried implementing that but I'm getting this late error field must be initialised... I think I know where its coming from but I dont know how to solve it this is the code of the screen:
class _AskSomellierStep4ScreenState extends State<AskSomellierStep4Screen> {
late QueryDocumentSnapshot<Map<String, dynamic>> _selectedSnapshot;
List<String> dataLabel = [
'Home',
'Search',
'Account',
];
late Future resultsLoaded;
getResults() async {
var data = await FirebaseFirestore.instance
.collection(widget.wineOrMeal)
.where('type', isEqualTo: widget.selectedCuisine)
.get();
setState(() {
allResults = data.docs;
});
filterResultsList();
return data.docs;
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
...
Padding(
padding: const EdgeInsets.only(
left: 35,
top: 5,
),
child: SizedBox(
height: 370,
width: 320,
child: Center(
child: ListView.builder(
dragStartBehavior: DragStartBehavior.down,
scrollDirection: Axis.vertical,
itemCount: filteredResults.length,
itemBuilder: (context, index) => widget.mealVSWine
? PrefInformationCardWine(
snapShotDocument: filteredResults[index],
cardColor: Theme.of(context).primaryColor,
isSelected:
filteredResults[index] == _selectedSnapshot,
onSelected: () {
setState(() {
_selectedSnapshot = filteredResults[index];
});
},
)
: PrefInformationCardMeal(
snapShotDocument: filteredResults[index],
cardColor: Theme.of(context).primaryColor,
isSelected:
filteredResults[index] == _selectedSnapshot,
onSelected: () {
setState(() {
_selectedSnapshot = filteredResults[index];
});
},
),
),
),
)),
Padding(
padding: const EdgeInsets.only(
left: 35,
top: 25,
),
child: SubmitSettingChangesButton(
buttonText: 'Continue',
cancelText: 'Cancel',
cancelOnTap: () {
Navigator.pop(context);
},
continueOnTap: () {
Navigator.pushAndRemoveUntil(
context,
createRoute(FindingRecommendationScreen(
snapshotName: _selectedSnapshot,
)),
(route) => false);
},
),
),
...
If you need any further information just give me a note. I would be very thankful if you could help me with this:)
Code Screen 4:
class AskSomellierStep4Screen extends StatefulWidget {
const AskSomellierStep4Screen({
Key? key,
required this.stepDescription,
required this.wineOrMeal,
required this.mealVSWine,
required this.selectedCuisine,
}) : super(key: key);
final String wineOrMeal;
final String stepDescription;
final bool mealVSWine;
final String selectedCuisine;
#override
State<AskSomellierStep4Screen> createState() =>
_AskSomellierStep4ScreenState();
}
class _AskSomellierStep4ScreenState extends State<AskSomellierStep4Screen> {
QueryDocumentSnapshot<Map<String, dynamic>>? _selectedSnapshot;
List<String> dataLabel = [
'Home',
'Search',
'Account',
];
late Future resultsLoaded;
List<IconData> data = [
CustomIcons.home,
CustomIcons.search,
CustomIcons.user,
];
getResults() async {
var data = await FirebaseFirestore.instance
.collection(widget.wineOrMeal)
.where('type', isEqualTo: widget.selectedCuisine)
.get();
setState(() {
allResults = data.docs;
});
filterResultsList();
return data.docs;
}
List allResults = [];
List filteredResults = [];
onSearchChanged() {
print(searchController.text);
filterResultsList();
}
filterResultsList() {
var showResults = [];
if (searchController.text != '') {
// we have a search parameter
for (var searchSnapshot in allResults) {
var name = searchSnapshot['name'].toLowerCase();
if (name.contains(searchController.text.toLowerCase())) {
showResults.add(searchSnapshot);
}
}
} else {
// we do not have a search parameter
showResults = List.from(allResults);
}
setState(() {
filteredResults = showResults;
});
}
TextEditingController searchController = TextEditingController();
#override
void initState() {
super.initState();
searchController.addListener(onSearchChanged);
}
#override
void dispose() {
searchController.removeListener(onSearchChanged);
searchController.dispose();
super.dispose();
}
#override
void didChangeDependencies() {
super.didChangeDependencies();
resultsLoaded = getResults();
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
HomeScreenHeader(
subText: 'Wine and Food',
mainText: 'Ask your Somellier',
boxWidth: 238,
),
Padding(
padding: const EdgeInsets.only(
left: 172,
top: 92,
),
child: Text(
'Step 4',
style: GoogleFonts.poppins(
textStyle: TextStyle(
color: Theme.of(context).indicatorColor,
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
),
),
Padding(
padding: const EdgeInsets.only(
left: 97,
),
child: Text(
widget.stepDescription,
style: GoogleFonts.poppins(
textStyle: TextStyle(
color: Theme.of(context).primaryColorLight,
fontSize: 14,
fontWeight: FontWeight.w600,
),
),
),
),
Padding(
padding: const EdgeInsets.only(
left: 35,
top: 25,
),
child: Stack(
children: [
Container(
height: 35,
width: 320,
decoration: BoxDecoration(
color: Theme.of(context).primaryColor,
borderRadius: BorderRadius.circular(20.0),
),
),
Positioned(
left: 10,
top: 14.5,
child: SizedBox(
height: 21,
width: 300,
child: TextField(
controller: searchController,
style: GoogleFonts.poppins(
textStyle: const TextStyle(
color: Colors.white,
fontSize: 14,
fontWeight: FontWeight.bold)),
decoration: InputDecoration(
hintText: 'Search',
hintStyle: GoogleFonts.poppins(
textStyle: TextStyle(
color: Theme.of(context).hintColor,
fontSize: 16,
fontWeight: FontWeight.bold),
),
border: InputBorder.none,
),
),
),
),
Positioned(
left: 320 - 35,
top: 119 - 110,
child: SizedBox(
height: 17,
width: 17,
child: SvgPicture.asset(
'assets/icons/general/search.svg',
color: Theme.of(context).indicatorColor,
),
),
),
],
),
),
Padding(
padding: const EdgeInsets.only(
left: 35,
top: 15,
),
child: Text(
'Popular Choices',
style: GoogleFonts.poppins(
textStyle: const TextStyle(
color: Colors.white,
fontSize: 14,
fontWeight: FontWeight.w600,
),
),
),
),
Padding(
padding: const EdgeInsets.only(
left: 35,
top: 5,
),
child: SizedBox(
height: 370,
width: 320,
child: Center(
child: ListView.builder(
dragStartBehavior: DragStartBehavior.down,
scrollDirection: Axis.vertical,
itemCount: filteredResults.length,
itemBuilder: (context, index) => widget.mealVSWine
? PrefInformationCardWine(
snapShotDocument: filteredResults[index],
cardColor: Theme.of(context).primaryColor,
isSelected:
filteredResults[index] == _selectedSnapshot,
onSelected: () {
setState(() {
_selectedSnapshot = filteredResults[index];
});
},
)
: PrefInformationCardMeal(
snapShotDocument: filteredResults[index],
cardColor: Theme.of(context).primaryColor,
isSelected:
filteredResults[index] == _selectedSnapshot,
onSelected: () {
setState(() {
_selectedSnapshot = filteredResults[index];
});
},
),
),
),
)),
Padding(
padding: const Ed
geInsets.only(
left: 35,
top: 25,
),
child: SubmitSettingChangesButton(
buttonText: 'Continue',
cancelText: 'Cancel',
cancelOnTap: () {
Navigator.pop(context);
},
continueOnTap: () {
_selectedSnapshot != null
? () {
Navigator.pushAndRemoveUntil(
context,
createRoute(FindingRecommendationScreen(
snapshotName: _selectedSnapshot,
)),
(route) => false);
}
: null;
},
),
),
Padding(
padding: const EdgeInsets.only(
top: 15,
left: 171,
),
child: GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: SizedBox(
height: 16,
width: 47,
child: Center(
child: Text(
'Go Back',
style: GoogleFonts.poppins(
textStyle: TextStyle(
color: Theme.of(context).indicatorColor,
fontSize: 11,
fontWeight: FontWeight.bold,
),
),
),
),
),
),
),
],
),
);
}
}
Code Screen 5:
class FindingRecommendationScreen extends StatefulWidget {
const FindingRecommendationScreen({
Key? key,
required this.snapshotName,
}) : super(key: key);
final QueryDocumentSnapshot<Map<String, dynamic>>? snapshotName;
#override
State<FindingRecommendationScreen> createState() =>
_FindingRecommendationScreenState();
}
class _FindingRecommendationScreenState
extends State<FindingRecommendationScreen> {
bool progressDone = true;
late Future<IconData> iconSnapshot;
Future<bool> animationDone() async {
await Future.delayed(const Duration(milliseconds: 3000), () {
setState(() {
progressDone = true;
});
});
return progressDone;
}
Future<IconData> iconData(Future<bool> progress) async {
if (await progress == true) {
return Icons.home;
}
print('function used');
return Icons.done;
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
body: Column(
children: [
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 35,
vertical: 100,
),
child: Text(
'Your Somellier is searching...',
textAlign: TextAlign.center,
style: GoogleFonts.poppins(
textStyle: TextStyle(
color: Theme.of(context).indicatorColor,
fontSize: 24,
fontWeight: FontWeight.bold,
),
),
),
),
Padding(
padding: EdgeInsets.only(
left: (MediaQuery.of(context).size.width - 200) / 2,
right: (MediaQuery.of(context).size.width - 200) / 2,
top: 50,
),
child: CircularPercentIndicator(
radius: 120,
lineWidth: 4.0,
circularStrokeCap: CircularStrokeCap.round,
animation: true,
animationDuration: 3000,
percent: 1,
// center: FutureBuilder<IconData>(
// future: iconData(animationDone()),
// builder: (context, snapshot) {
// return Icon(
// snapshot.data,
// color: Colors.white,
// );
// },
// ),
// center: const Icon(
// Icons.done_rounded,
// color: Colors.white,
// size: 90,
// ),
center: Text(
'Finding Wine 🍷',
style: GoogleFonts.poppins(
textStyle: const TextStyle(
color: Colors.white,
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
),
progressColor: Theme.of(context).indicatorColor,
),
),
Padding(
padding: const EdgeInsets.only(
left: 35,
right: 35,
top: 200,
),
child: GestureDetector(
onTap: () {
Navigator.pushAndRemoveUntil(
context,
createRoute(const SomellierResultScreen()),
(route) => false);
},
child: Container(
height: 50,
width: MediaQuery.of(context).size.width - 70,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(
25,
),
color: Theme.of(context).primaryColor,
),
child: Center(
child: Text(
widget.snapshotName?['name'],
style: GoogleFonts.poppins(
textStyle: TextStyle(
color: Theme.of(context).indicatorColor,
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
),
),
),
),
),
],
),
);
}
}

Problem
The problem with _selectedSnapshot is that you use it before you ever initialize it with a value.
In your code, you are using
isSelected: filteredResults[index] == _selectedSnapshot,
This causes the error because _selectedSnapshot has no value assigned yet. In your code you assign your value only, when the user taps one of the cards.
onSelected: () {
setState(() {
_selectedSnapshot = filteredResults[index];
});
},
But you never get there, since the screen can't be build because of the error thrown.
Solution
Instead of
late QueryDocumentSnapshot<Map<String, dynamic>> _selectedSnapshot;
use
QueryDocumentSnapshot<Map<String, dynamic>>? _selectedSnapshot = null;
With the ?-Operator you allow your variable _selectedSnapshot to be null.
This means in your context, the user has not yet chosen one option.
You may want to disable the continue button until the user has chosen an option:
continueOnTap: _selectedSnapshot != null ? () {
Navigator.pushAndRemoveUntil(context, createRoute(FindingRecommendationScreen( snapshotName: _selectedSnapshot, )), (route) => false);
} : null,
This checks if _selectedSnapshot is not null. If so the user can continue. Otherwise the Button-Callback is null, which means nothing will happen, if the user presses continue.

Related

Can't pass data to next screen because selection state is unknown

I'm working on this app, that is supposed to tell you what kind of wine, or meal, you can enjoy with the specific meal or wine you're currently enjoying. Im currently at the point to make the user able to search for the wine/meal, he or she is currently enjoying to then ask his/her sommelier what wine/meal would fit best. Now my structure looks like this: The user opens the screen and he sees a ListView.builder of the wines/meals he can choose from that aren't ruled out rom the selection before (type...). Now I implemented a search that uses the fact of making a stateful list variable from the firebase data to then be able to search the list and display the results. Now to display these results I wrote a widget called PrefInformationCard which basically is a card that displays all the relevant data... Now to indicate to the user that the card he/she tapped on was selected I implemented a boolean check that changes the color of the widget. There are two problems with that. I implemented it in the widget which means on the screen and in the list view builder, I dont know, whether a card is selected and what card is selected so I can't pass the selected data to the next screen. Now the other problem is that there is the possibility of selecting multiple Cards at once.
In this first document you will see the code for the step 4 screen:
class AskSomellierStep4Screen extends StatefulWidget {
const AskSomellierStep4Screen({
Key? key,
required this.stepDescription,
required this.wineOrMeal,
required this.mealVSWine,
required this.selectedCuisine,
}) : super(key: key);
final String wineOrMeal;
final String stepDescription;
final bool mealVSWine;
final String selectedCuisine;
#override
State<AskSomellierStep4Screen> createState() =>
_AskSomellierStep4ScreenState();
}
class _AskSomellierStep4ScreenState extends State<AskSomellierStep4Screen> {
List<String> dataLabel = [
'Home',
'Search',
'Account',
];
late Future resultsLoaded;
List<IconData> data = [
CustomIcons.home,
CustomIcons.search,
CustomIcons.user,
];
getResults() async {
var data = await FirebaseFirestore.instance
.collection(widget.wineOrMeal)
.where('type', isEqualTo: widget.selectedCuisine)
.get();
setState(() {
allResults = data.docs;
});
filterResultsList();
return data.docs;
}
List allResults = [];
List filteredResults = [];
onSearchChanged() {
print(searchController.text);
filterResultsList();
}
filterResultsList() {
var showResults = [];
if (searchController.text != '') {
// we have a search parameter
for (var searchSnapshot in allResults) {
var name = searchSnapshot['name'].toLowerCase();
if (name.contains(searchController.text.toLowerCase())) {
showResults.add(searchSnapshot);
}
}
} else {
// we do not have a search parameter
showResults = List.from(allResults);
}
setState(() {
filteredResults = showResults;
});
}
TextEditingController searchController = TextEditingController();
#override
void initState() {
super.initState();
searchController.addListener(onSearchChanged);
}
#override
void dispose() {
searchController.removeListener(onSearchChanged);
searchController.dispose();
super.dispose();
}
#override
void didChangeDependencies() {
super.didChangeDependencies();
resultsLoaded = getResults();
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
HomeScreenHeader(
subText: 'Wine and Food',
mainText: 'Ask your Somellier',
boxWidth: 238,
),
Padding(
padding: const EdgeInsets.only(
left: 172,
top: 92,
),
child: Text(
'Step 4',
style: GoogleFonts.poppins(
textStyle: TextStyle(
color: Theme.of(context).indicatorColor,
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
),
),
Padding(
padding: const EdgeInsets.only(
left: 97,
),
child: Text(
widget.stepDescription,
style: GoogleFonts.poppins(
textStyle: TextStyle(
color: Theme.of(context).primaryColorLight,
fontSize: 14,
fontWeight: FontWeight.w600,
),
),
),
),
Padding(
padding: const EdgeInsets.only(
left: 35,
top: 25,
),
child: Stack(
children: [
Container(
height: 35,
width: 320,
decoration: BoxDecoration(
color: Theme.of(context).primaryColor,
borderRadius: BorderRadius.circular(20.0),
),
),
Positioned(
left: 10,
top: 14.5,
child: SizedBox(
height: 21,
width: 300,
child: TextField(
controller: searchController,
style: GoogleFonts.poppins(
textStyle: const TextStyle(
color: Colors.white,
fontSize: 14,
fontWeight: FontWeight.bold)),
decoration: InputDecoration(
hintText: 'Search',
hintStyle: GoogleFonts.poppins(
textStyle: TextStyle(
color: Theme.of(context).hintColor,
fontSize: 16,
fontWeight: FontWeight.bold),
),
border: InputBorder.none,
),
),
),
),
Positioned(
left: 320 - 35,
top: 119 - 110,
child: SizedBox(
height: 17,
width: 17,
child: SvgPicture.asset(
'assets/icons/general/search.svg',
color: Theme.of(context).indicatorColor,
),
),
),
],
),
),
Padding(
padding: const EdgeInsets.only(
left: 35,
top: 15,
),
child: Text(
'Popular Choices',
style: GoogleFonts.poppins(
textStyle: const TextStyle(
color: Colors.white,
fontSize: 14,
fontWeight: FontWeight.w600,
),
),
),
),
Padding(
padding: const EdgeInsets.only(
left: 35,
top: 5,
),
child: SizedBox(
height: 370,
width: 320,
child: Center(
child: ListView.builder(
dragStartBehavior: DragStartBehavior.down,
scrollDirection: Axis.vertical,
itemCount: filteredResults.length,
itemBuilder: (context, index) => widget.mealVSWine
? PrefInformationCardWine(
snapShotDocument: filteredResults[index],
cardColor: Theme.of(context).primaryColor,
selected: false,
)
: PrefInformationCardMeal(
snapshotDocument: filteredResults[index],
cardColor: Theme.of(context).primaryColor,
selected: false),
),
),
),
),
Padding(
padding: const EdgeInsets.only(
left: 35,
top: 25,
),
child: SubmitSettingChangesButton(
buttonText: 'Continue',
cancelText: 'Cancel',
cancelOnTap: () {
Navigator.pop(context);
},
continueOnTap: () {
Navigator.pushAndRemoveUntil(
context,
createRoute(FindingRecommendationScreen()),
(route) => false);
},
),
),
Padding(
padding: const EdgeInsets.only(
top: 15,
left: 171,
),
child: GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: SizedBox(
height: 16,
width: 47,
child: Center(
child: Text(
'Go Back',
style: GoogleFonts.poppins(
textStyle: TextStyle(
color: Theme.of(context).indicatorColor,
fontSize: 11,
fontWeight: FontWeight.bold,
),
),
),
),
),
),
),
],
),
);
}
}
This is the relevant code for the PrefInformationCard:
class PrefInformationCardWine extends StatefulWidget {
PrefInformationCardWine({
Key? key,
required this.snapShotDocument,
required this.cardColor,
required this.selected,
}) : super(key: key);
DocumentSnapshot snapShotDocument;
Color cardColor;
bool selected;
#override
State<PrefInformationCardWine> createState() =>
_PrefInformationCardWineState();
}
class _PrefInformationCardWineState extends State<PrefInformationCardWine> {
Color backgroundColor(context, selected) {
setState(() {
if (widget.selected == true) {
widget.cardColor = Theme.of(context).primaryColorLight;
} else {
widget.cardColor = Theme.of(context).primaryColor;
}
});
return widget.cardColor;
}
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(
bottom: 25,
),
child: GestureDetector(
onTap: () {
setState(() {
widget.selected = !widget.selected;
});
},
child: Stack(
children: [
Container(
height: 185,
width: 320,
decoration: BoxDecoration(
color: backgroundColor(context, widget.selected),
boxShadow: [
BoxShadow(
offset: const Offset(0, 4),
color: const Color(0xff000000).withOpacity(.25),
),
],
borderRadius: BorderRadius.circular(
35,
),
),
),
...
I would be glad if someone could help me with this issue because I frankly dont have a clue, how to solve this. Thank you in advance:)
Padding(
padding: const EdgeInsets.only(
left: 35,
top: 25,
),
child: SubmitSettingChangesButton(
buttonText: 'Continue',
cancelText: 'Cancel',
cancelOnTap: () {
Navigator.pop(context);
},
continueOnTap: () {
Navigator.pushAndRemoveUntil(
context,
createRoute(FindingRecommendationScreen(
snapshotName: _selectedSnapshot,
)),
(route) => false);
},
),
),
That's how I wanted to pass the Data
Rather than dealing with the selected state within your cards, you should use a callback to set the state in your step 4 screen.
(This will rebuild the entire step 4 screen, but I'm unsure of another way with just using setState)
For example:
late DocumentSnapshot _selectedSnapshot;
final List filteredResults = [];
#override
Widget build(BuildContext context) {
return SizedBox(
height: 370,
width: 320,
child: Center(
child: ListView.builder(
dragStartBehavior: DragStartBehavior.down,
scrollDirection: Axis.vertical,
itemCount: filteredResults.length,
itemBuilder: (context, index) => widget.mealVSWine
? PrefInformationCardWine(
snapShotDocument: filteredResults[index],
cardColor: Theme.of(context).primaryColor,
isSelected: filteredResults[index] == _selectedSnapshot,
onSelected: () {
setState(() {
_selectedSnapshot = filteredResults[index];
});
},
)
: PrefInformationCardMeal(
snapshotDocument: filteredResults[index],
cardColor: Theme.of(context).primaryColor,
isSelected: filteredResults[index] == _selectedSnapshot,
onSelected: () {
setState(() {
_selectedSnapshot = filteredResults[index];
});
},
),
),
),
);
}
}
Then in your card:
class PrefInformationCardWine extends StatefulWidget {
PrefInformationCardWine({
Key? key,
required this.snapShotDocument,
required this.cardColor,
required this.isSelected,
required this.onSelected,
}) : super(key: key);
DocumentSnapshot snapShotDocument;
Color cardColor;
bool isSelected;
VoidCallback onSelected;
#override
State<PrefInformationCardWine> createState() =>
_PrefInformationCardWineState();
}
class _PrefInformationCardWineState extends State<PrefInformationCardWine> {
Color backgroundColor(context, selected) {
setState(() {
if (widget.isSelected == true) {
widget.cardColor = Theme.of(context).primaryColorLight;
} else {
widget.cardColor = Theme.of(context).primaryColor;
}
});
return widget.cardColor;
}
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(
bottom: 25,
),
child: GestureDetector(
onTap: widget.onSelected,
child: Stack(
children: [
Container(
height: 185,
width: 320,
decoration: BoxDecoration(
color: backgroundColor(context, widget.isSelected),
boxShadow: [
BoxShadow(
offset: const Offset(0, 4),
color: const Color(0xff000000).withOpacity(.25),
),
],
borderRadius: BorderRadius.circular(
35,
),
),
)
...

How to update the Circular Percentage Indicator once we click each Checkbox List

I want to do the checklist section which have circular percentage indicator. The percentage should updated once the list of checklist(checkbox) is clicked. Each Checkbox should hold 25% because have 4 checklist and the overall percentage is 100. Please help me how to update the percentage.
This is the interface
class ReportForm extends StatefulWidget {
final int itemIndex;
final Project project;
const ReportForm({this.itemIndex, this.project});
#override
State<ReportForm> createState() => _ReportFormState();
}
class _ReportFormState extends State<ReportForm> {
FirebaseFirestore _firebaseFirestore = FirebaseFirestore.instance;
UserModel loggedInUser = UserModel();
double progress = 0.0;
currentProgressColor() {
if (progress >= 0.6 && progress < 0.8) {
return Colors.red;
}
if(progress >= 0.8){
return Colors.green;
}
else{
return Colors.orange;
}
}
final checklist = [
CheckBoxState(title: 'Attendance'),
CheckBoxState(title: 'Equipment Used'),
CheckBoxState(title: 'Work Performed'),
CheckBoxState(title: 'Remarks'),
];
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Container(
height: 650,
width: 370,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(13),
boxShadow: [
BoxShadow(
offset: Offset(0, 1),
blurRadius: 17,
spreadRadius: -23,
color: kShadowColor,
),
],
),
child: Column(
children: <Widget>[
SizedBox(
height:40,
),
CircularPercentIndicator(
radius: 200.0,
circularStrokeCap: CircularStrokeCap.round,
lineWidth: 25.0,
progressColor: currentProgressColor(),
percent: progress,
animation: true,
animationDuration: 1500,
center: new Text("${this.progress * 100}%", style: TextStyle(
fontSize: 30,
),),
footer: new Text("Daily Report Completion",
style: TextStyle(
fontSize: 15,
color: Colors.green,
),),),
SizedBox(
height:20,
),
StreamBuilder<QuerySnapshot>(
stream: _firebaseFirestore.collection("Attendance").snapshots(),
builder: (context, snapshot) {
return GestureDetector(
onTap: () {
Navigator.push(context, MaterialPageRoute(
builder: (context) => Attendance(
),
));
},
child: Card(
clipBehavior: Clip.antiAlias,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(13.0)
),
elevation: 10,
margin: EdgeInsets.fromLTRB(10.0, 2.0, 10.0, 2.0),
child: Container(
color: Colors.white,
width: 350,
height:60,
child: Padding(
padding: const EdgeInsets.all(2.0),
child: buildSingleCheckbox(CheckBoxState(title: 'Attendance')),
),
),
),
);
}
),
SizedBox(
height:18,
),
GestureDetector(
onTap: () {
Navigator.push(context, MaterialPageRoute(
builder: (context) => DetailsForm(project: widget.project, itemIndex: widget.itemIndex),
));
},
child: Card(
clipBehavior: Clip.antiAlias,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(13.0)
),
elevation: 10,
margin: EdgeInsets.fromLTRB(10.0, 2.0, 10.0, 2.0),
child: Container(
color: Colors.white,
width: 350,
height: 60,
child: Padding(
padding: const EdgeInsets.all(2.0),
child: buildSingleCheckbox(CheckBoxState(title: 'Equipment Used')),
),
),
),
),
SizedBox(
height:18,
),
GestureDetector(
onTap: () {
Navigator.push(context, MaterialPageRoute(
builder: (context) => HomeScreen(),
));
},
child: Card(
clipBehavior: Clip.antiAlias,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(13.0)
),
elevation: 10,
margin: EdgeInsets.fromLTRB(10.0, 2.0, 10.0, 2.0),
child: Container(
color: Colors.white,
width: 350,
height: 60,
child: Padding(
padding: const EdgeInsets.all(2.0),
child: buildSingleCheckbox(CheckBoxState(title: 'Work Performed')),
),
),
),
),
SizedBox(
height:18,
),
GestureDetector(
onTap: () {
Navigator.push(context, MaterialPageRoute(
builder: (context) => Remarks(),
));
},
child: Card(
clipBehavior: Clip.antiAlias,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(13.0)
),
elevation: 10,
margin: EdgeInsets.fromLTRB(10.0, 2.0, 10.0, 2.0),
child: Container(
color: Colors.white,
width: 350,
height: 60,
child: Padding(
padding: const EdgeInsets.all(2.0),
child: buildSingleCheckbox(CheckBoxState(title: 'Remarks')),
),
),
),
),
],
),
),
);
}
Widget buildSingleCheckbox(CheckBoxState checkbox) => StatefulBuilder(
builder: (context, _setState) => CheckboxListTile(
activeColor: Colors.green,
value: checkbox.value,
title: Text(checkbox.title),
onChanged: (value) =>
_setState(() => checkbox.value = value),
),
);
}
class CheckBoxState{
final String title;
bool value;
CheckBoxState({
#required this.title,
this.value = false,});
}
I did a small test you can apply according to your need
import 'package:flutter/material.dart';
import 'package:percent_indicator/circular_percent_indicator.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Teste',
debugShowCheckedModeBanner: false,
home: Teste(),
);
}
}
class Teste extends StatefulWidget {
const Teste({Key? key}) : super(key: key);
#override
_TesteState createState() => _TesteState();
}
class _TesteState extends State<Teste> {
List<bool> checkboxStatus = [];
double percentage = 0.0;
final checklist = ['Attendance', 'Equipment Used', 'Work Performed', 'Remarks'];
#override
void initState() {
super.initState();
checklist.forEach((element) => checkboxStatus.add(false));
}
currentProgressColor() {
if (percentage >= 0.6 && percentage < 0.8) {
return Colors.red;
}
if (percentage >= 0.8) {
return Colors.green;
} else {
return Colors.orange;
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Container(
height: 650,
width: 370,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(13),
boxShadow: [BoxShadow(offset: Offset(0, 1), blurRadius: 17, spreadRadius: -23, color: Colors.orange)],
),
child: Column(
children: <Widget>[
SizedBox(height: 40),
CircularPercentIndicator(
animateFromLastPercent: true,
radius: 200.0,
circularStrokeCap: CircularStrokeCap.round,
lineWidth: 25.0,
progressColor: currentProgressColor(),
percent: percentage,
animation: true,
animationDuration: 1500,
center: Text('${percentage * 100} %'),
footer: Text("Daily Report Completion", style: TextStyle(fontSize: 15, color: Colors.green)),
),
SizedBox(height: 20),
Expanded(
child: ListView.builder(
itemCount: checklist.length,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Card(
clipBehavior: Clip.antiAlias,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(13.0)),
elevation: 10,
child: ElevatedButton(
onPressed: () {
if (checklist[index] == 'Attendance') {
Navigator.push(context, MaterialPageRoute(builder: (context) => Attendance()));
} else if() {
/// other page
}
},
style: ElevatedButton.styleFrom(primary: Colors.white),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(checklist[index], style: TextStyle(color: Colors.black)),
Checkbox(
value: checkboxStatus[index],
onChanged: (value) {
if (checkboxStatus[index] == false) {
percentage += (1 / checklist.length);
} else {
percentage -= (1 / checklist.length);
}
setState(() => checkboxStatus[index] = !checkboxStatus[index]);
},
checkColor: Colors.white,
)
],
),
),
),
);
},
),
)
],
),
),
),
);
}
}

How to navigate without context in List widget Flutter

I am developing a flutter web app in which I have developed custom navbar but I am struggling to add navigation in the navbar items. I've tried Get to navigate without context but unfortunately it isn't working on the list I've created. I did tried to create function and put navigation as required for it but still no luck.
import 'package:animated_text_kit/animated_text_kit.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:get/get.dart';
import 'package:shimmer/shimmer.dart';
import 'package:customweb/about.dart';
double collapsableHeight = 0.0;
Color selected = Color(0xffffffff);
Color notSelected = Color(0xafffffff);
class Nav extends StatefulWidget {
#override
_NavState createState() => _NavState();
}
class _NavState extends State<Nav> {
#override
Widget build(BuildContext context) {
double width = MediaQuery.of(context).size.width;
return SafeArea(
child: Scaffold(
body: Stack(
children: [
Align(
alignment: Alignment.topCenter,
child: Padding(
padding: EdgeInsets.only(top: 250),
child: Image.asset(
"assets/logo.png",
scale: 2,
)),
),
Align(
alignment: Alignment.bottomCenter,
child: Padding(
padding: EdgeInsets.only(bottom: 120),
child: Text(
"Download now available on",
style: TextStyle(fontSize: 30),
))),
Align(
alignment: Alignment.bottomCenter,
child: Padding(
padding: EdgeInsets.only(right: 200, bottom: 50),
child: Image.asset(
"assets/1200px-Google_Play_Store_badge_EN.png",
scale: 8,
))),
Align(
alignment: Alignment.bottomCenter,
child: Padding(
padding: EdgeInsets.only(left: 200, bottom: 50),
child: Image.asset(
"assets/1200px-Download_on_the_App_Store_Badge.png",
scale: 8,
))),
AnimatedContainer(
margin: EdgeInsets.only(top: 79.0),
duration: Duration(milliseconds: 375),
curve: Curves.ease,
height: (width < 800.0) ? collapsableHeight : 0.0,
width: double.infinity,
color: Color(0xff121212),
child: SingleChildScrollView(
child: Column(
children: navBarItems,
),
),
),
Container(
color: Colors.amber,
height: 80.0,
padding: EdgeInsets.symmetric(horizontal: 24.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
AnimatedTextKit(
animatedTexts: [
FadeAnimatedText(
'Get It',
textStyle: TextStyle(fontSize: 26, color: Colors.white),
),
FadeAnimatedText(
'All Amazing Stuff',
textStyle: TextStyle(fontSize: 22, color: Colors.white),
),
FadeAnimatedText(
'One Platform',
textStyle: TextStyle(fontSize: 24, color: Colors.white),
),
FadeAnimatedText(
'Endless Services',
textStyle: TextStyle(fontSize: 24, color: Colors.white),
),
FadeAnimatedText(
'Available Soon',
textStyle: TextStyle(fontSize: 24, color: Colors.white),
),
],
onTap: () {
print("");
},
),
LayoutBuilder(builder: (context, constraints) {
if (width < 800.0) {
return NavBarButton(
onPressed: () {
if (collapsableHeight == 0.0) {
setState(() {
collapsableHeight = 240.0;
});
} else if (collapsableHeight == 240.0) {
setState(() {
collapsableHeight = 0.0;
});
}
},
);
} else {
return Row(
children: navBarItems,
);
}
})
],
),
),
],
),
),
);
}
}
List<Widget> navBarItems = [
NavBarItem(
text: 'About',
onPressed: () {
Get.to(AboutPage());
},
),
NavBarItem(
text: 'Services',
onPressed: () {
Get.to(AboutPage());
},
),
NavBarItem(
text: 'FAQ',
onPressed: () {
Get.to(AboutPage());
},
),
];
class NavBarItem extends StatefulWidget {
final String text;
final Function onPressed;
NavBarItem({
required this.text,
required this.onPressed,
});
#override
_NavBarItemState createState() => _NavBarItemState();
}
class _NavBarItemState extends State<NavBarItem> {
Color color = notSelected;
#override
Widget build(BuildContext context) {
return MouseRegion(
onEnter: (value) {
setState(() {
color = selected;
});
},
onExit: (value) {
setState(() {
color = notSelected;
});
},
child: Material(
color: Colors.transparent,
child: InkWell(
splashColor: Colors.white60,
onTap: () {},
child: Container(
height: 60.0,
alignment: Alignment.centerLeft,
margin: EdgeInsets.symmetric(horizontal: 24.0),
child: Text(
widget.text,
style: TextStyle(
fontSize: 16.0,
color: color,
),
),
),
),
),
);
}
}
class NavBarButton extends StatefulWidget {
final Function onPressed;
NavBarButton({
required this.onPressed,
});
#override
_NavBarButtonState createState() => _NavBarButtonState();
}
class _NavBarButtonState extends State<NavBarButton> {
Widget build(BuildContext context) {
return Container(
height: 55.0,
width: 60.0,
decoration: BoxDecoration(
border: Border.all(
color: Color(0xcfffffff),
width: 2.0,
),
borderRadius: BorderRadius.circular(15.0),
),
child: Material(
color: Colors.transparent,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12.0),
),
child: InkWell(
splashColor: Colors.white60,
onTap: () {
setState(() {
widget.onPressed();
});
},
child: Icon(
Icons.menu,
size: 30.0,
color: Color(0xcfffffff),
),
),
),
);
}
}
Any help will be highly appreciated
Hi Asver Seb you are following wrong method. I've recently done a job on flutter web here use my code of navbar/header to build what you are looking for it will do perfectly fine.
class Header extends StatelessWidget {
const Header({
Key? key,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.symmetric(vertical: 20, horizontal: 40),
child: Row(
children: <Widget>[
Image.asset(
'assets/images/logo.png',
width: 50,
),
SizedBox(width: 10),
Shimmer.fromColors(
baseColor: Colors.transparent,
highlightColor: Colors.amber,
child: Text(
"Webster",
style: TextStyle(fontSize: 32, fontWeight: FontWeight.w800),
)),
Spacer(),
NavItem(
title: 'Home',
tapEvent: () {
Get.to(HomeScreen());
},
),
NavItem(
title: 'About',
tapEvent: () {
Get.to(About());
},
),
NavItem(
title: 'FAQ',
tapEvent: () {
Get.to(Faq());
},
),
],
),
);
}
}
class NavItem extends StatelessWidget {
const NavItem({Key? key, required this.title, required this.tapEvent})
: super(key: key);
final String title;
final GestureTapCallback tapEvent;
#override
Widget build(BuildContext context) {
return InkWell(
onTap: tapEvent,
hoverColor: Colors.transparent,
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 15),
child: Text(
title,
style: TextStyle(fontWeight: FontWeight.w300),
),
),
);
}
}

firebase is not connection with flutter app

what is the problem ?
the loading widget is working after that not Connection widget is running
how I can solve this problem
my code:
import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:marwa_app/component/myResponsiveLibrary.dart'; import 'package:marwa_app/component/Logo.dart'; import 'package:marwa_app/component/MyDrawer.dart'; import 'package:geolocator/geolocator.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:firebase_core/firebase_core.dart';
class Reporting extends StatefulWidget { #override
_ReportingState createState() => _ReportingState(); }
class _ReportingState extends State<Reporting> { final formKey = GlobalKey<FormState>(); final scaffoldKey = GlobalKey<ScaffoldState>();
BoxDecoration boxDecoration() {
return BoxDecoration(
color: MainModel().mainColor,
borderRadius: BorderRadius.all(Radius.circular(40.0)),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.15),
spreadRadius: 5,
blurRadius: 5,
offset: Offset(2, 2), // changes position of shadow
),
],
); }
TextStyle titleStyle() {
return TextStyle(
color: MainModel().whiteColor,
fontSize: MainModel().setFont(MainModel().largeFont, getWidth())); }
TextStyle textStyle() {
return TextStyle(
color: MainModel().whiteColor,
fontSize: MainModel().setFont(MainModel().middleFont, getWidth()),
); }
double getWidth() {
return MediaQuery.of(context).size.width; }
final _name = TextEditingController(); final _phone = TextEditingController(); final _emType = TextEditingController(); double lat; double lon; bool _initialized = false; bool _error
= false;
void initializeFlutterFire() async {
try {
await Firebase.initializeApp();
setState(() {
_initialized = true;
});
} catch(e) {
// Set `_error` state to true if Firebase initialization fails
setState(() {
_error = true;
});
} }
#override void initState() {
initializeFlutterFire();
super.initState(); } #override Widget build(BuildContext context) {
if(_error) {
return notConnection();
}
if (!_initialized) {
return Loading();
}
return isConnection(); }
Widget isConnection() {
final widthScreen = MediaQuery.of(context).size.width;
return Scaffold(
key: scaffoldKey,
backgroundColor: MainModel().mainColor,
appBar: AppBar(
backgroundColor: Color(0xff323266),
leading: IconButton(
icon: Icon(
Icons.notifications_active,
color: MainModel().thirdColor,
),
onPressed: () => {}),
title: Logo(),
centerTitle: true,
actions: [
Builder(
builder: (context) => IconButton(
icon: Icon(
Icons.menu,
color: MainModel().thirdColor,
),
onPressed: () => Scaffold.of(context).openEndDrawer(),
tooltip: MaterialLocalizations.of(context).openAppDrawerTooltip,
),
),
],
),
endDrawer: Drawer(
child: MyDrawer(),
),
body: ListView(
padding: EdgeInsets.only(
top: MainModel()
.setPadding(MainModel().largePadding, widthScreen)),
children: [
Form(
key: formKey,
child: Column(
children: [
Directionality(
textDirection: TextDirection.rtl,
child: Container(
padding: EdgeInsets.symmetric(horizontal: 20),
margin: EdgeInsets.symmetric(horizontal: 20),
alignment: Alignment.centerRight,
decoration: boxDecoration(),
child: TextFormField(
controller: _name,
textDirection: TextDirection.rtl,
autofocus: true,
decoration: InputDecoration(
border: InputBorder.none,
hintStyle: textStyle(),
hintText: 'الاسم الرباعي'),
validator: (value) {
if (value.isEmpty) {
return "يرجى ادخل الاسم";
} else {
return null;
}
},
),
),
),
Padding(
padding: EdgeInsets.only(
top: MainModel().setPadding(
MainModel().middlePadding, widthScreen)),
),
Directionality(
textDirection: TextDirection.rtl,
child: Container(
padding: EdgeInsets.symmetric(horizontal: 20),
margin: EdgeInsets.symmetric(horizontal: 20),
alignment: Alignment.centerRight,
decoration: boxDecoration(),
child: TextFormField(
controller: _phone,
keyboardType: TextInputType.number,
textDirection: TextDirection.rtl,
autofocus: true,
decoration: InputDecoration(
border: InputBorder.none,
hintStyle: textStyle(),
hintText: 'رقم الهاتف'),
validator: (value) {
if (value.isEmpty) {
return "يرجى ادخال رقم الهاتف";
} else {
return null;
}
},
),
),
),
Padding(
padding: EdgeInsets.only(
top: MainModel().setPadding(
MainModel().middlePadding, widthScreen)),
),
Directionality(
textDirection: TextDirection.rtl,
child: Container(
padding: EdgeInsets.symmetric(horizontal: 20),
margin: EdgeInsets.symmetric(horizontal: 20),
alignment: Alignment.centerRight,
decoration: boxDecoration(),
child: TextFormField(
controller: _emType,
textDirection: TextDirection.rtl,
autofocus: true,
decoration: InputDecoration(
border: InputBorder.none,
hintStyle: textStyle(),
hintText: 'نوع الابلاغ'),
validator: (value) {
if (value.isEmpty) {
return "يرجى ادخال نوع الابلاغ (الحالة)";
} else {
return null;
}
},
),
),
),
Padding(
padding: EdgeInsets.only(
top: MainModel().setPadding(
MainModel().middlePadding, widthScreen)),
),
Container(
child: GestureDetector(
onTap: () async {
bool isLocationServiceEnabled =
await Geolocator.isLocationServiceEnabled();
if (isLocationServiceEnabled == true) {
Position position =
await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.high);
lon = position.longitude;
lat = position.latitude;
} else {
print(
'امنح التطبيق من الوصول الى موقع... ثم اعد الارسال');
}
},
child: Image.asset('images/location.png')),
),
Padding(
padding: EdgeInsets.only(
bottom: MainModel().setPadding(
MainModel().largePadding * 2, widthScreen))),
RaisedButton(
onPressed: () {
Firebase.initializeApp();
if (formKey.currentState.validate()) {
// save data in firebase
FirebaseFirestore.instance
.collection('Data')
.doc()
.set({
'name': _name,
'phone': _phone,
'em-type': _emType,
});
scaffoldKey.currentState.showSnackBar(SnackBar(
content: Text('تم ارسال بياناتك .... '
'سيتم التواصل معك من الجهات المختصة')));
}
},
child: Text('ارسال'),
)
],
))
],
)); }
Widget notConnection() {
final widthScreen = MediaQuery.of(context).size.width;
return Scaffold(
key: scaffoldKey,
backgroundColor: MainModel().mainColor,
appBar: AppBar(
backgroundColor: Color(0xff323266),
leading: IconButton(
icon: Icon(
Icons.notifications_active,
color: MainModel().thirdColor,
),
onPressed: () => {}),
title: Logo(),
centerTitle: true,
actions: [
Builder(
builder: (context) => IconButton(
icon: Icon(
Icons.menu,
color: MainModel().thirdColor,
),
onPressed: () => Scaffold.of(context).openEndDrawer(),
tooltip: MaterialLocalizations.of(context).openAppDrawerTooltip,
),
),
],
),
endDrawer: Drawer(
child: MyDrawer(),
),
body: ListView(
padding: EdgeInsets.only(
top: MainModel()
.setPadding(MainModel().largePadding, widthScreen)),
children: [
Container(
child: Center(
child: Text('not Connection of Database'),
),
)
])); }
Widget Loading() {
final widthScreen = MediaQuery.of(context).size.width;
return Scaffold(
key: scaffoldKey,
backgroundColor: MainModel().mainColor,
appBar: AppBar(
backgroundColor: Color(0xff323266),
leading: IconButton(
icon: Icon(
Icons.notifications_active,
color: MainModel().thirdColor,
),
onPressed: () => {}),
title: Logo(),
centerTitle: true,
actions: [
Builder(
builder: (context) => IconButton(
icon: Icon(
Icons.menu,
color: MainModel().thirdColor,
),
onPressed: () => Scaffold.of(context).openEndDrawer(),
tooltip: MaterialLocalizations.of(context).openAppDrawerTooltip,
),
),
],
),
endDrawer: Drawer(
child: MyDrawer(),
),
body: Container(
child: Center(
child: Text('Loading'),
),
)
); } }
I don't have any error on compiler but not connected firebase.
just I want to take data from textfeild and saved in firebase.
my data is (name, phone, location, type of emergency).

Display Cloud Firebase data? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
Hey Does anyone know how I can Display this variable url from my Cloud Firebase?
It would be very nice if someone could do a example that would be massive! :)
class EditProfile extends StatefulWidget {
#override
_EditProfileState createState() => _EditProfileState();
}
class _EditProfileState extends State<EditProfile> {
FocusNode myFocusNode1 = new FocusNode();
FocusNode myFocusNode3 = new FocusNode();
final _formkey = GlobalKey<FormState>();
String _UserName ;
String _Email ;
String _URL;
File _image;
Future getImage(BuildContext context) async {
var image = await ImagePicker.pickImage(source: ImageSource.gallery);
setState(() {
_image = image;
print('Image Path $_image');
uploadPic(context);
});
}
Future<DocumentSnapshot> getUserInfo() async {
var firebaseUser = await FirebaseAuth.instance.currentUser;
return await FirebaseFirestore.instance.collection("SerX")
.doc(firebaseUser.uid)
.get();
}
Future uploadPic(BuildContext context) async {
String fileName = basename(_image.path);
StorageReference firebaseStorageRef = FirebaseStorage.instance.ref().child(
fileName);
StorageUploadTask uploadTask = firebaseStorageRef.putFile(_image);
StorageTaskSnapshot taskSnapshot = await uploadTask.onComplete;
var downUrl = await (await uploadTask.onComplete).ref.getDownloadURL();
_URL = downUrl.toString();
setState(() async {
print('Profile Picture uploaded');
var firebaseUser = await FirebaseAuth.instance.currentUser;
FirebaseFirestore.instance.collection("SerX").doc(firebaseUser.uid).update({"url" : downUrl});
Scaffold.of(context).showSnackBar(
SnackBar(content: Text('Profile Picture Uploaded')));
});
}
#override
void dispose() {
myFocusNode1 = FocusNode();
myFocusNode3 = FocusNode();
super.dispose();
}
#override
Widget build(BuildContext context) {
myFocusNode1.addListener(() {setState(() {
}); });
myFocusNode3.addListener(() {setState(() {
}); });
final user = Provider.of<Userf>(context);
return StreamBuilder<UserData>(
stream: DatabaseService(uid: user.uid).userData,
builder: (context, snapshot) {
if(snapshot.hasData){
UserData userData = snapshot.data;
return Form(
key: _formkey,
child: Scaffold(
appBar: AppBar(
bottom: PreferredSize(
child: Container(
color: Colors.blue,
height: 4.0,
),
preferredSize: Size.fromHeight(0)),
backgroundColor: Colors.black,
leading: IconButton(icon: Icon(Icons.arrow_back ,color: Colors.blue,),onPressed: (){
Navigator.pushReplacement(context,
MaterialPageRoute(builder: (context) => HomeScreen()));
},),
title: Text('Profile', style: TextStyle(
color:Colors.white,
fontSize: 25,
fontWeight: FontWeight.bold,
fontFamily: 'Orbitron',
),
textAlign: TextAlign.center,
),
),
body: Container(
color: Colors.black,
child: ListView(
children: [
Stack(
children: [
Container(
margin: EdgeInsets.fromLTRB(140,45,0,0),
width: 130,
height: 130,
decoration: BoxDecoration(
border: Border.all(
width: 3,
color: Colors.blue,
),
boxShadow: [BoxShadow(
spreadRadius: 2, blurRadius: 10,
color: Colors.white.withOpacity(0.1),
offset: Offset(0,10),
),
],
shape: BoxShape.circle,
image: DecorationImage(
fit: BoxFit.cover,
image: (_image != null) ? FileImage(
_image)
: NetworkImage(_URL.toString()),
)
),
),
Positioned(
bottom: 0,
right: 150,
child: Container(
height: 35,
width: 35,
decoration: BoxDecoration(
border: Border.all(width: 2, color: Colors.blue),
shape: BoxShape.circle,
color: Colors.white,
),
child: IconButton(icon: Icon(Icons.edit), color: Colors.blue,iconSize:
17, onPressed: () async {
getImage(context);
},),
),
)
],
),
SizedBox(height: 40),
TextFormField(
initialValue: userData.Username,
onChanged: (val) => setState(() => _UserName = val),
validator: (input){
if (input.isEmpty) {
return 'Please enter a username';
}
if(input.length < 6){
return 'Your username needs to be at least 6 characters';
}else if(input.length > 12){
return 'Your username needs to be at most 12 characters';
}
if (!RegExp(
r'^[a-zA-Z0-9]+$')
.hasMatch(input)) {
return 'a-z, A-Z, 0-9';
}
},
focusNode: myFocusNode1,
style: TextStyle(
color: Colors.white,
fontSize: 15,
fontWeight: FontWeight.bold,
fontFamily: 'Orbitron',
),
decoration: InputDecoration(
focusedBorder: OutlineInputBorder(
borderSide: const BorderSide(color: Colors.blue, width: 1.0),
borderRadius: BorderRadius.circular(25.0),
),
enabledBorder: OutlineInputBorder(
borderSide: const BorderSide(color: Colors.white, width: 1.0),
borderRadius: BorderRadius.circular(25.0),
),
icon: Icon(Icons.edit, color: Colors.blue,),
contentPadding: EdgeInsets.only(bottom: 3),
labelText: "Username",
labelStyle: TextStyle(color: myFocusNode1.hasFocus ? Colors.blue : Colors.white),
floatingLabelBehavior: FloatingLabelBehavior.always,
prefixIcon: myFocusNode1.hasFocus ? Icon(Icons.account_circle, color: Colors.blue,): Icon(Icons.account_circle, color: Colors.white,),
hintStyle: TextStyle(
color: Colors.white,
fontSize: 15,
fontWeight: FontWeight.bold,
fontFamily: 'Orbitron',
),
),
),
SizedBox(height: 35),
Row(
children: [
SizedBox(width: 40,),
RaisedButton(
onPressed: (){
Navigator.pushReplacement(context, MaterialPageRoute(
builder: (context) => HomeScreen()));
},
color: Colors.white,
padding: EdgeInsets.symmetric(horizontal: 10),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
elevation: 2,
child: Text("CANCEL",
style:TextStyle(
color: Colors.black,
fontSize: 25,
fontWeight: FontWeight.bold,
fontFamily: 'Orbitron',
letterSpacing: 2.2,
),),
),
SizedBox(width: 30,),
RaisedButton(
onPressed: () async{
if(_formkey.currentState.validate()){
await DatabaseService(uid: user.uid).updateUserData(
_UserName ?? userData.Username,
_Email ?? userData.Email,
_URL ?? userData.URL);
Navigator.pushReplacement(context, MaterialPageRoute(
builder: (context) => LoadingUpdate()));
}
},
color: Colors.blue,
padding: EdgeInsets.symmetric(horizontal: 30),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
elevation: 2,
child: Text("SAVE" ,style:TextStyle(
color: Colors.black,
fontSize: 27,
fontWeight: FontWeight.bold,
fontFamily: 'Orbitron',
letterSpacing: 2.2,
),),
)
],
),
],
)
),
),
);
}else{
return Center(
child: SpinKitFadingCircle(color: Colors.white, size: 20.0),
heightFactor: 29,
);
}
}
);
}
}
BoxDecoration myBoxDecoration() {
return BoxDecoration(
border: Border.all(
color: Colors.blue, // <--- border color
width: 5.0,
),
);
dnkjcnsjkndkcnsjkcnkjsndckjnsdkjcnsjkdcnkjnsdkcjnsd
skcnkjsndcknsdkjcnkjsdcnkjnsdjkcnsjkdcnjknsdc
scdhbsdjbcjhsdbcjhbsdhjcbsjhdcbhjdbsjdbcjhsbdc
scjbsdjhcsjdcbjhsdbcjhbsdc
final FirebaseAuth _firebaseAuth = FirebaseAuth.instance;
try {
DocumentSnapshot document = await _firestore
.collection('SerX')
.doc(documentID) //replace with the document id
.get();
Map<String, dynamic> json = document.data() // your data
// for example to get the email value -> json["Email"]
} catch (e) {
throw Exception();
}

Resources