How to Get the Number of Pages in Pageview to be used in a line indicator in Flutter? - flutter

May i ask for help on how to get the number of pages inside a pageview,
similar to listview you can get the number of list via listview.length, but for pageview there is no pageview.length property that i can use,
i tried using pageview.builder but i couldnt initiate the data as a list showig an issue that i need to initiate it as an initializers?,
please help me figure it out
i need the data inside the pageview to be used inside the _lineprogressindicator, to show how many are the questionaires inside to make an indicator
here is my code
import 'dart:async';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:survey/content/thankyou.dart';
import 'package:survey/widgets/animations.dart';
import 'package:survey/widgets/buttonstyle.dart';
import 'package:survey/widgets/widgetlist.dart';
class questionaires extends StatefulWidget {
#override
_questionairesState createState() => _questionairesState();
}
class _questionairesState extends State<questionaires> {
TextStyle conqueststyle = TextStyle(
fontSize: 15, fontWeight: FontWeight.bold, color: Colors.indigo);
TextStyle questionstyle = TextStyle(
fontSize: 17,
fontWeight: FontWeight.bold,
);
String titletop = 'Post Visit Patient Satisfaction';
String q1 = "Sample Question HERE";
String q2 = "Sample Question HERE";
String q3 = "Sample Question HERE";
String q4 = "Sample Question HERE";
int percentagenum = 0;
int _currValue = 1;
bool _loading;
double _progress;
final _texteditingcontroller = TextEditingController();
final _pageController = PageController(initialPage: 0, keepPage: true);
var _currentpage = 0;
List answernumbers = ["5", "4", "3", "2", "1"];
List currentselectedvalue = [];
List usingCollection1 = [
"Excellent",
"Very Good",
"Good",
"Fair",
"Poor",
];
#override
void dispose() {
super.dispose();
_texteditingcontroller.dispose();
_loading = false;
_progress = 0.0;
percentagenum = 0;
_currValue = 0;
usingTimes1 = '';
usingTimes = '';
usingTimes2 = '';
}
void initState() {
super.initState();
usingTimes1 = '';
usingTimes = '';
usingTimes2 = '';
_loading = false;
_progress = 0.0;
percentagenum = 0;
_texteditingcontroller.clear();
_currValue = 0;
}
void pageChanged(int index) {
setState(() {
_currentpage = index;
});
}
void _selectedanswers(data1, data2) {
if (_progress.toStringAsFixed(1) == '1.0') {
print(data1);
print(data2);
_texteditingcontroller.text;
}
}
void _updateProgress() {
setState(() {
_progress += 0.25;
percentagenum += 25;
if (_progress.toStringAsFixed(1) == '1.0') {
_loading = false;
_progress = 0;
percentagenum = 0;
Navigator.push(context, FadeRoute(page: thankyou()));
return;
}
});
}
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
backgroundColor: Colors.white,
resizeToAvoidBottomPadding: false,
body: Padding(
padding: EdgeInsets.all(20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
width: 100,
height: 60,
child: Image.asset(imgtit),
),
Stack(
children: <Widget>[
Container(
child: Text(
titletop,
style: conqueststyle,
maxLines: 1,
),
),
_buildPageView(),
_lineprogressindicator()
],
)
],
),
),
),
);
}
_buildPageView() {
return Container(
height: MediaQuery.of(context).size.height / 1.25,
child: PageView(
controller: _pageController,
onPageChanged: (index) {
pageChanged(index);
},
children: <Widget>[
_emojiquestions(q1),
_selectedutton(q2),
_numberrating(q3),
_textboxquestion(q4),
],
));
}
_lineprogressindicator() {
return Positioned(
left: 0.0,
right: 0.0,
bottom: 0.0,
child: Column(
children: <Widget>[
RaisedButton(
shape: RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(50.0),
),
color: Colors.indigo,
onPressed: () {
_pageController.nextPage(
duration: kTabScrollDuration, curve: Curves.ease);
_loading = !_loading;
_updateProgress();
},
child: Icon(
Icons.check,
color: Colors.white,
size: 50,
),
),
SizedBox(
height: 10,
),
Text('%$percentagenum'),
LinearProgressIndicator(
value: _progress,
),
],
),
);
}
_emojiquestions(String quest1) {
final using = usingCollection1[index];
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Text(
'Question 1',
style: conqueststyle,
textAlign: TextAlign.right,
),
SizedBox(
height: 20,
),
TextField(
decoration: InputDecoration.collapsed(hintText: quest1),
maxLines: 5,
style: conqueststyle,
),
Expanded(
child: Center(
child: Container(
height: 300,
child: ListView.separated(
separatorBuilder: (context, index) => SizedBox(height: 10),
itemCount: usingCollection1.length,
itemBuilder: (context, index) => GestureDetector(
onTapUp: (index) {
_selectedanswers(index, null);
},
child: Card(
color: usingTimes == usingCollection1[index]
? Colors.blue.withAlpha(100)
: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0),
),
child: Column(
children: <Widget>[
Row(
children: <Widget>[
SizedBox(
height: 50,
width: 70,
child: Image.asset(emojiimage[index]),
),
Text(usingCollection1[index])
],
),
Divider(
height: index < usingCollection1.length ? 1.0 : 0.0,
),
],
),
),
),
)),
),
)
],
);
}
_selectedutton(String quest1) {
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Text(
'Question 1',
style: conqueststyle,
textAlign: TextAlign.right,
),
SizedBox(
height: 20,
),
TextField(
decoration: InputDecoration.collapsed(hintText: quest1),
maxLines: 5,
style: conqueststyle,
),
Expanded(
child: Center(
child: Container(
height: 300,
child: Column(
children: List.generate(usingCollection1.length, (int index) {
final using = usingCollection1[index];
return GestureDetector(
onTap: () {
setState(() {
_currValue = index;
_selectedanswers(index, null);
usingTimes = using.identifier;
});
},
child: Card(
color: usingTimes == using.identifier
? Colors.blue.withAlpha(100)
: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0),
),
child: Column(
children: <Widget>[
Row(
children: <Widget>[
Radio(
value: index,
groupValue: _currValue,
onChanged: (val) =>
setState(() => _currValue = val),
),
Text(using.displayContent)
],
),
Divider(
height:
index < usingCollection1.length ? 1.0 : 0.0,
),
],
),
));
}),
),
),
),
)
],
);
}
_numberrating(quest) {
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Text(
'Question 2',
style: conqueststyle,
textAlign: TextAlign.right,
),
SizedBox(
height: 20,
),
TextField(
decoration: InputDecoration.collapsed(hintText: quest),
maxLines: 5,
style: conqueststyle,
),
Text("**5 is the highest"),
Container(
height: MediaQuery.of(context).size.height / 12.0,
width: MediaQuery.of(context).size.width,
child: ListView.builder(
physics: NeverScrollableScrollPhysics(),
scrollDirection: Axis.horizontal,
itemCount: usingCollection1.length,
itemBuilder: (context, index) {
final using = usingCollection1[index];
return GestureDetector(
onTapUp: (index) {
setState(() {
_selectedanswers(null, index);
usingTimes = using.identifier;
});
},
child: Card(
color: usingTimes == using.identifier
? Colors.blue.withAlpha(100)
: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0),
side: BorderSide(color: Colors.indigoAccent)),
child: Column(
children: <Widget>[
SizedBox(
height: 50,
width: 50,
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
answernumbers[index],
textAlign: TextAlign.center,
style: conqueststyle,
),
],
)),
),
],
),
),
);
},
),
)
],
);
}
_textboxquestion(quest) {
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Text(
'Question 2',
style: conqueststyle,
textAlign: TextAlign.right,
),
SizedBox(
height: 20,
),
TextField(
decoration: InputDecoration.collapsed(hintText: quest),
maxLines: 5,
style: conqueststyle,
),
TextFormField(
decoration: InputDecoration(
hintText: "Your FeedBack Here",
border: OutlineInputBorder(),
),
controller: _texteditingcontroller,
maxLines: 7,
style: conqueststyle,
)
],
);
}
}

For your case were the number of elements is known beforehand, I would suggest that you store your pages in a local variable and then call length on it. A small snippet would look something like this:
class MyState extends State<MyWidget> {
List<Widget> _pages = [
Container(color: Colors.blue,),
Container(color: Colors.amber,),
];
#override
Widget build(BuildContext context) {
return MyComplexWidgetTree(
child: PageView(
controller: PageController(),
children: _pages,
),
);
}
void _myMethodThatRequiresNumberOfPages() {
int numberOfPages = pages.length;
}
}

Related

I have a Error Closure call with mismatched arguments: function '_GameDetailsPageState.build.<anonymous closure>

I am currently creating comments in the app that the user will be able to do and after doing the function I get this error and I don't know how to fix it.
error
https://i.stack.imgur.com/rbLph.png
https://i.stack.imgur.com/Xa4vg.png
https://i.stack.imgur.com/9SPQR.png
https://i.stack.imgur.com/5Wxag.png
I searched for similar errors but those solutions did not help me
CustomTextField
class CustomTextField extends StatelessWidget {
String? hint;
final TextEditingController commentController;
final Function(String)? onSubmit;
CustomTextField(
{this.hint, required this.onSubmit, required this.commentController});
#override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TextField(
controller: commentController,
onSubmitted: onSubmit,
decoration: InputDecoration(
hintText: "$hint",
hintStyle: TextStyle(fontSize: 12),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(15),
borderSide: BorderSide(
color: Colors.deepPurple.shade200, width: 0)),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(15),
borderSide: BorderSide(width: 2.0))),
)
],
),
);
}
}
Comments List
import 'package:intl/intl.dart';
import '../../../../../assets/paidwork_icons.dart';
import '../../../../../common/utils/paidwork_colors.dart';
class CommentsList extends StatefulWidget {
final List<Comment> comments;
CommentsList(this.comments);
#override
State<CommentsList> createState() => _CommentsListState();
}
class _CommentsListState extends State<CommentsList> {
int likes = 0;
int dislikes = 0;
void giveLike() {
setState(() {
if (likes == 0) {
likes++;
} else {
likes--;
}
});
}
void giveDisLike() {
setState(() {
if (dislikes == 0) {
dislikes++;
} else {
dislikes--;
}
});
}
#override
Widget build(BuildContext context) {
return Container(
height: 300,
child: widget.comments.isEmpty
? Column(
children: <Widget>[
Text(
'No comments added yet!',
style: Theme.of(context).textTheme.headline6,
),
SizedBox(
height: 20,
),
Container(
height: 200,
child: Image.asset(
'assets/images/waiting.png',
fit: BoxFit.cover,
),
),
],
)
: ListView.builder(
itemBuilder: (ctx, index) {
return Card(
child: Row(
children: <Widget>[
Container(
width: 400,
height: 235,
decoration: BoxDecoration(
color: PaidworkColors.lightWhite,
borderRadius: BorderRadius.circular(10)),
child: Column(
children: [
SizedBox(
height: 8,
),
Padding(
padding: const EdgeInsets.only(left: 10),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Container(
width: 50,
child: Image(image: AssetImage('')),
),
SizedBox(
width: 10,
),
Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Container(
child: Row(
children: [
Text(
'Maciej',
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.w500,
fontFamily: 'Poppins',
fontSize: 15),
),
SizedBox(
width: 10,
),
Text(
DateFormat('yyyy/MM/dd').format(
widget.comments[index].date),
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.grey,
),
),
],
),
),
Container(
child: Row(
children: [
Icon(
PaidworkIcons
.paidwork_icon_chart_alt,
size: 30,
),
SizedBox(
width: 10,
),
],
),
),
Container(
width: 320,
child: Text(
widget.comments[index].description,
style: TextStyle(
color: Colors.black,
fontFamily: 'Poppins',
fontSize: 14),
),
),
Container(
width: 320,
child: Row(
children: [
Container(
child: Row(
children: [
Text(
likes.toString(),
style: TextStyle(
color: PaidworkColors
.lightUnactive),
),
GestureDetector(
onTap: () => giveLike(),
child: Icon(
PaidworkIcons
.paidwork_icon_heroicons_hand_like,
color: PaidworkColors
.lightUnactive,
),
)
],
),
),
SizedBox(
width: 20,
),
Container(
child: Row(
children: [
Text(
'${dislikes}',
style: TextStyle(
color: PaidworkColors
.lightUnactive),
),
GestureDetector(
onTap: () {
giveDisLike();
},
child: Icon(
PaidworkIcons
.paidwork_icon_heroicons_hand_dislike,
color: PaidworkColors
.lightUnactive,
),
)
],
),
),
],
)),
],
),
],
),
),
],
),
)
],
),
);
},
itemCount: widget.comments.length,
),
);
}
}
Functions
void _startAddNewTransaction(BuildContext context) {
showModalBottomSheet(
context: context,
builder: (_) {
return AddingCommentForm(
commentController: commentController,
userCommentAvatar: 'assets/images/account_game_avatar.png',
userCommentUsername: 'Maciej',
userCommentDate: '21.12.2222',
addYourReview: () {},
cancelReview: () {},
addTx: _addNewTransaction);
},
);
}
final List<Comment> _userComments = [];
void _addNewTransaction(String txDescription, String txDifficulty) {
final newTx = Comment(
description: txDescription,
difficulty: txDifficulty,
date: DateTime.now(),
id: DateTime.now().toString(),
);
setState(() {
_userComments.add(newTx);
});
}
bool openAddReviewForm = false;
void addReview() {
setState(() {
openAddReviewForm = !openAddReviewForm;
});
}
final TextEditingController commentController = TextEditingController();
void submitData() {
final enteredDescription = commentController.text;
if (enteredDescription.isEmpty) {
return;
}
widget.addTx(
enteredDescription,
);
Navigator.of(context).pop();
}

The state of my checkboxes keep returning to their original value in flutter

I have a profile page with some widgets which after saving and redrawing, they keep their new states, but my checkboxes do not, and I have not modified them at all. The new value is being saved on the database, but on the UI it's not preserved. If I turn the email checkbox to true, the 'true' boolean is saved, but it's not displayed on the frontend after pressing the submit button.
class _ProfilePageState extends State<ProfilePage> {
final _formKey = GlobalKey<FormState>();
bool? emailIsChecked = false;
bool? smsisChecked = false;
bool isTextFieldEnabled = false;
bool isIgnored = true;
bool isVisible = false;
bool editIsVisible = true;
bool emailIsEnabled = false;
bool smsIsEnabled = false;
bool nameEdit = false;
late TextEditingController countryController;
late TextEditingController languageController;
#override
void initState() {
super.initState();
countryController = TextEditingController(text: globals.signedInUser!.country);
languageController = TextEditingController(text: globals.signedInUser!.language);
selectedCountry = globals.signedInUser!.country;
selectedLanguage = globals.signedInUser!.language;
globals.signedInUser!.notifications.forEach(
(element) {
if ((element['type']) == 'Email') {
emailIsChecked = element['status'];
}
if ((element['type']) == 'SMS') {
smsisChecked = element['status'];
}
},
);
cleanInputStates();
}
#override
void dispose() {
countryController.dispose();
languageController.dispose();
super.dispose();
}
checkEditVisibility() {
if (editIsVisible == true) {
return true;
}
if (editIsVisible == false) {
return false;
}
}
checkEditAvailability() {
if (editIsVisible == false) {
return true;
}
if (editIsVisible == true) {
return false;
}
}
cleanInputStates() {
isTextFieldEnabled = false;
isIgnored = true;
editIsVisible = true;
isVisible = false;
smsIsEnabled = false;
emailIsEnabled = false;
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Form(
key: _formKey,
child: Row(
children: [
Flexible(
flex: 5,
child: Padding(
padding: const EdgeInsets.only(top: 20),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
height: 30,
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Visibility(
visible: editIsVisible,
maintainSize: true,
maintainAnimation: true,
maintainState: true,
child: ElevatedButton.icon(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(Colors.green)),
icon: const Icon(Icons.edit),
label: Text('Edit'),
onPressed: () {
setState(() {
isTextFieldEnabled = true;
isIgnored = false;
isVisible = true;
editIsVisible = false;
smsIsEnabled = true;
emailIsEnabled = true;
});
}),
),
SizedBox(
width: 250,
)
],
),
SizedBox(
height: 30,
),
Flexible(
flex: 1,
child: Padding(
padding: const EdgeInsets.only(top: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
height: 20,
),
... // TextFieldInputs
Row(
children: [
Container(
child: Text(
"Country: ",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 22,
color: Colors.black.withOpacity(0.3),
),
),
),
SizedBox(
width: 100,
),
Container(
width: 300,
child: IgnorePointer(
ignoring: isIgnored,
child: DropdownButtonFormField2(
decoration: InputDecoration(
isDense: true,
contentPadding: EdgeInsets.zero,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(15),
),
),
isExpanded: true,
hint: const Text(
'Select Your Country',
style: TextStyle(fontSize: 14),
),
icon: const Icon(
Icons.arrow_drop_down,
color: Colors.black45,
),
iconSize: 30,
buttonHeight: 60,
buttonPadding: const EdgeInsets.only(left: 20, right: 10),
dropdownDecoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
),
items: countryItems
.map((item) => DropdownMenuItem<String>(
value: item,
child: Text(
item,
style: const TextStyle(
fontSize: 14,
),
),
))
.toList(),
validator: (valueCountry) {
if (valueCountry == null) {
return 'Please select country.';
}
return null;
},
value: selectedCountry,
onChanged: (String? valueCountry) {
selectedCountry = valueCountry;
setState(() {
valueCountry;
});
},
),
),
),
// ),
],
),
SizedBox(
height: 20,
),
Row(
children: [
Container(
child: Text(
"Language: ",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 22,
color: Colors.black.withOpacity(0.3),
),
),
),
SizedBox(
width: 80,
),
Container(
width: 300,
child: IgnorePointer(
ignoring: isIgnored,
child: DropdownButtonFormField2(
decoration: InputDecoration(
isDense: true,
contentPadding: EdgeInsets.zero,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(15),
),
),
isExpanded: true,
hint: const Text(
'Select Your Language',
style: TextStyle(fontSize: 14),
),
icon: const Icon(
Icons.arrow_drop_down,
color: Colors.black45,
),
iconSize: 30,
buttonHeight: 60,
buttonPadding: const EdgeInsets.only(left: 20, right: 10),
dropdownDecoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
),
items: languageItems
.map((item) => DropdownMenuItem<String>(
value: item,
child: Text(
item,
style: const TextStyle(
fontSize: 14,
),
),
))
.toList(),
value: selectedLanguage,
validator: (valueLanguage) {
if (valueLanguage == null) {
return 'Please select language.';
}
return null;
},
onChanged: (String? valueLanguage) {
selectedLanguage = valueLanguage;
setState(() {
valueLanguage;
});
},
),
),
),
// ),
],
),
Row()
],
),
SizedBox(
width: 120,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Container(
child: Row(
children: [
Text(
"Receive notifications by: ",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 22,
color: Colors.black.withOpacity(0.3),
),
),
],
),
),
],
),
SizedBox(
height: 10,
),
Row(
children: [
Container(
width: 300,
child: CheckboxListTile(
enabled: emailIsEnabled,
title: Text("E-mail"),
value: emailIsChecked,
onChanged: (bool? newEmailValue) {
setState(() {
emailIsChecked = newEmailValue;
});
},
activeColor: Colors.green,
),
),
],
),
Row(
children: [
Container(
width: 300,
child: CheckboxListTile(
enabled: smsIsEnabled,
title: Text("SMS"),
value: smsisChecked,
onChanged: (bool? newSmsValue) {
setState(() {
smsisChecked = newSmsValue;
});
},
activeColor: Colors.green,
),
),
],
),
SizedBox(
height: 100,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Visibility(
visible: isVisible,
child: Row(
children: <Widget>[
ElevatedButton(
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all(Colors.red)),
onPressed: () {
setState(() {
cleanInputStates();
_formKey.currentState!.reset();
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ProfilePage()));
});
print("Cleaning states");
},
child: Text("Dismiss"),
),
SizedBox(
width: 100,
),
ElevatedButton(
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all(Colors.green)),
onPressed: () {
if (_formKey.currentState!.validate()) {
final userInfo = {
"_id": globals.signedInUser!.userId,
"firstName": firstnameTextController.text,
"lastName": lastnameTextController.text,
"email": emailTextController.text,
"phoneNumber": phoneNumberTextController.text,
"country": selectedCountry.toString(),
"language": selectedLanguage.toString(),
"notifications": [
{"type": "Email", "status": emailIsChecked},
{"type": "SMS", "status": smsisChecked}
]
};
globals.socketController.updateUser(userInfo);
Fluttertoast.showToast(
msg: "Applying changes.", // message
toastLength: Toast.LENGTH_LONG, // length
gravity: ToastGravity.BOTTOM_RIGHT, // location
timeInSecForIosWeb: 2,
webBgColor: "#4caf50",
);
}
print("DATA IS BEING SAVED");
setState(() {
if (_formKey.currentState!.validate()) {
globals.signedInUser!.email =
emailTextController.text;
globals.signedInUser!.phoneNumber =
phoneNumberTextController.text;
globals.signedInUser!.firstName =
firstnameTextController.text;
globals.signedInUser!.lastName =
lastnameTextController.text;
globals.signedInUser!.country =
selectedCountry as String;
globals.signedInUser!.language =
selectedLanguage as String;
cleanInputStates();
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ProfilePage()));
} else {
print("ingresando else");
}
});
},
child: Text("Save"),
),
],
),
)
],
)
],
),
],
),
),
),
],
), //Column ends here
),
),
],
),
),
);
}
}
Update: After some testings and workarounds, I found that the second issue was due to not assigning a new value prior to returning to the initState. To do that, I added the following code segment into the setState() of the submit button, which is the fetch of the notification parameters within the initState() but assigning the new checkbox values into the array. Additionally, I removed the cleanInputStates(); on the initState as #Paulo mentioned and everything else kept the same.
globals.signedInUser!.notifications.forEach(
(element) {
if ((element['type']) == 'Email') {
element['status'] = emailIsChecked;
}
if ((element['type']) == 'SMS') {
element['status'] = smsisChecked;
}
},
);

How to usage Obx() with getx in flutter?

On my UI screen, I have 2 textfields in a column. If textFormFieldEntr is empty, hide textFormFiel. If there is a value in the textFormFieldEntr, let the other textfield be visible. After I set the bool active variable to false in the Controller class, I checked the value in the textFormFieldEntr in the showText class. I'm wrong using obx on the UI screen. The textfields are listed in the _formTextField method. Can you answer by explaining the correct obx usage on the code I shared?
class WordController extends GetxController {
TextEditingController controllerInput1 = TextEditingController();
TextEditingController controllerInput2 = TextEditingController();
bool active = false.obs();
final translator = GoogleTranslator();
RxList data = [].obs;
#override
void onInit() {
getir();
super.onInit();
}
void showText() {
if (!controllerInput1.text.isEmpty) {
active = true;
}
}
ekle(Word word) async {
var val = await WordRepo().add(word);
showDilog("Kayıt Başarılı");
update();
return val;
}
updateWord(Word word) async {
var val = await WordRepo().update(word);
showDilog("Kayıt Başarılı");
return val;
}
deleteWord(int? id) async {
var val = await WordRepo().deleteById(id!);
return val;
}
getir() async {
//here read all data from database
data.value = await WordRepo().getAll();
print(data);
return data;
}
translateLanguage(String newValue) async {
if (newValue == null || newValue.length == 0) {
return;
}
List list = ["I", "i"];
if (newValue.length == 1 && !list.contains(newValue)) {
return;
}
var translate = await translator.translate(newValue, from: 'en', to: 'tr');
controllerInput2.text = translate.toString();
//addNote();
return translate;
}
showDilog(String message) {
Get.defaultDialog(title: "Bilgi", middleText: message);
}
addNote() async {
var word =
Word(wordEn: controllerInput1.text, wordTr: controllerInput2.text);
await ekle(word);
getir();
clear();
}
clear() {
controllerInput2.clear();
controllerInput1.clear();
}
updateNote() async {
var word =
Word(wordEn: controllerInput1.text, wordTr: controllerInput2.text);
await updateWord(word);
await getir();
update();
}
}
UI:
class MainPage extends StatelessWidget {
bool _active=false.obs();
String _firstLanguage = "English";
String _secondLanguage = "Turkish";
WordController controller = Get.put(WordController());
final _formKey = GlobalKey<FormState>();
#override
Widget build(BuildContext context) {
controller.getir();
return Scaffold(
drawer: _drawer,
backgroundColor: Colors.blueAccent,
appBar: _appbar,
body: _bodyScaffold,
floatingActionButton: _floattingActionButton,
);
}
SingleChildScrollView get _bodyScaffold {
return SingleChildScrollView(
child: Column(
children: [
chooseLanguage,
translateTextView,
],
),
);
}
AppBar get _appbar {
return AppBar(
backgroundColor: Colors.blueAccent,
centerTitle: true,
title: Text("TRANSLATE"),
elevation: 0.0,
);
}
get chooseLanguage => Container(
height: 55.0,
decoration: buildBoxDecoration,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
firstChooseLanguage,
changeLanguageButton,
secondChooseLanguage,
],
),
);
get buildBoxDecoration {
return BoxDecoration(
color: Colors.white,
border: Border(
bottom: BorderSide(
width: 3.5,
color: Colors.grey,
),
),
);
}
refreshList() {
controller.getir();
}
get changeLanguageButton {
return Material(
color: Colors.white,
child: IconButton(
icon: Icon(
Icons.wifi_protected_setup_rounded,
color: Colors.indigo,
size: 30.0,
),
onPressed: () {},
),
);
}
get secondChooseLanguage {
return Expanded(
child: Material(
color: Colors.white,
child: InkWell(
onTap: () {},
child: Center(
child: Text(
this._secondLanguage,
style: TextStyle(
color: Colors.blue[600],
fontSize: 22.0,
),
),
),
),
),
);
}
get firstChooseLanguage {
return Expanded(
child: Material(
color: Colors.white,
child: InkWell(
onTap: () {},
child: Center(
child: Text(
this._firstLanguage,
style: TextStyle(
color: Colors.blue[600],
fontSize: 22.0,
),
),
),
),
),
);
}
get translateTextView => Column(
children: [
Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(8.0)),
),
margin: EdgeInsets.only(left: 2.0, right: 2.0, top: 2.0),
child: _formTextField,
),
Container(
height: Get.height/1.6,
child: Obx(() {
return ListView.builder(
itemCount: controller.data.length,
itemBuilder: (context, index) {
return Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(5.0)),
),
margin: EdgeInsets.only(left: 2.0, right: 2.0, top: 0.8),
child: Container(
color: Colors.white30,
height: 70.0,
padding:
EdgeInsets.only(left: 8.0, top: 8.0, bottom: 8.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
firstText(controller.data, index),
secondText(controller.data, index),
],
),
historyIconbutton,
],
),
),
);
},
);
}),
)
],
);
get _formTextField {
return Form(
key: _formKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
color: Colors.white30,
height: 120.0,
padding: EdgeInsets.only(left: 16.0, top: 8.0, bottom: 8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
textFormFieldEntr,
favoriIconButton,
],
),
),
textFormField //burası kapandı
],
),
);
}
get textFormFieldEntr {
return Flexible(
child: Container(
child: TextFormField(
onTap: () {
showMaterialBanner();
},
// onChanged: (text) {
// controller.translateLanguage(text);
// },
controller: controller.controllerInput1,
maxLines: 6,
validator: (controllerInput1) {
if (controllerInput1!.isEmpty) {
return "lütfen bir değer giriniz";
} else if (controllerInput1.length > 22) {
return "en fazla 22 karakter girebilirsiniz";
}
return null;
},
decoration: InputDecoration(
hintText: "Enter",
contentPadding: const EdgeInsets.symmetric(vertical: 5.0),
),
),
),
);
}
void showMaterialBanner() {
ScaffoldMessenger.of(Get.context!).showMaterialBanner(MaterialBanner(
backgroundColor: Colors.red,
content: Padding(
padding: const EdgeInsets.only(top: 30.0),
child: Column(
children: [
TextFormField(
controller: controller.controllerInput1,
maxLines: 6,
onChanged: (text) {
controller.translateLanguage(text);
controller.showText();
},
validator: (controllerInput2) {
if (controllerInput2!.length > 22) {
return "en fazla 22 karakter girebilirsiniz";
}
return null;
},
decoration: InputDecoration(
suffixIcon: IconButton(onPressed: () {
FocusScope.of(Get.context!).unfocus();
closeBanner();
}, icon: Icon(Icons.clear),),
contentPadding: const EdgeInsets.symmetric(vertical: 5.0),
),
),
SizedBox(height: 80.0),
TextFormField(
controller: controller.controllerInput2,
maxLines: 6,
validator: (controllerInput2) {
if (controllerInput2!.length > 22) {
return "en fazla 22 karakter girebilirsiniz";
}
return null;
},
decoration: InputDecoration(
contentPadding: const EdgeInsets.symmetric(vertical: 5.0),
),
),
],
),
),
actions: [
IconButton(
onPressed: () {
closeBanner();
},
icon: Icon(
Icons.arrow_forward_outlined,
color: Colors.indigo,
size: 36,
),
),
]));
}
void closeBanner() {
ScaffoldMessenger.of(Get.context!).hideCurrentMaterialBanner();
}
// } controller.controllerInput1.text==""?_active=false: _active=true;
get textFormField {
return Visibility(
visible: controller.active,
child: Container(
color: Colors.white30,
height: 120.0,
padding: EdgeInsets.only(left: 16.0, right: 42.0, top: 8.0, bottom: 8.0),
child: Container(
child: TextFormField(
controller: controller.controllerInput2,
maxLines: 6,
validator: (controllerInput2) {
if (controllerInput2!.length > 22) {
return "en fazla 22 karakter girebilirsiniz";
}
return null;
},
decoration: InputDecoration(
contentPadding: const EdgeInsets.symmetric(vertical: 5.0),
),
),
),
),
);
}
FutureBuilder<dynamic> get historyWordList {
return FutureBuilder(
future: controller.getir(),
builder: (context, AsyncSnapshot snapShot) {
if (snapShot.hasData) {
var wordList = snapShot.data;
return ListView.builder(
itemCount: wordList.length,
itemBuilder: (context, index) {
return Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(5.0)),
),
margin: EdgeInsets.only(left: 8.0, right: 8.0, top: 0.8),
child: Container(
color: Colors.white30,
height: 70.0,
padding: EdgeInsets.only(left: 8.0, top: 8.0, bottom: 8.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
firstText(wordList, index),
secondText(wordList, index),
],
),
historyIconbutton,
],
),
),
);
},
);
} else {
return Center();
}
},
);
}
IconButton get historyIconbutton {
return IconButton(
onPressed: () {},
icon: Icon(Icons.history),
iconSize: 30.0,
);
}
Text firstText(wordList, int index) {
return Text(
"İngilizce: ${wordList[index].wordEn ?? ""}",
style: TextStyle(
fontWeight: FontWeight.w600,
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
);
}
Text secondText(wordList, int index) {
return Text(
"Türkçe: ${wordList[index].wordTr ?? ""}",
style: TextStyle(
fontWeight: FontWeight.w400,
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
);
}
get favoriIconButton {
return IconButton(
alignment: Alignment.topRight,
onPressed: () async {
bool validatorKontrol = _formKey.currentState!.validate();
if (validatorKontrol) {
String val1 = controller.controllerInput1.text;
String val2 = controller.controllerInput2.text;
print("$val1 $val2");
await controller.addNote();
await refreshList();
}
await Obx(() => textFormField(
controller: controller.controllerInput2,
));
await Obx(() => textFormField(
controller: controller.controllerInput1,
));
},
icon: Icon(
Icons.forward,
color: Colors.blueGrey,
size: 36.0,
),
);
}
FloatingActionButton get _floattingActionButton {
return FloatingActionButton(
onPressed: () {
Get.to(WordListPage());
},
child: Icon(
Icons.app_registration,
size: 30,
),
);
}
Drawer get _drawer {
return Drawer(
child: ListView(
// Important: Remove any padding from the ListView.
padding: EdgeInsets.zero,
children: <Widget>[
userAccountsDrawerHeader,
drawerFavorilerim,
drawersettings,
drawerContacts,
],
),
);
}
ListTile get drawerContacts {
return ListTile(
leading: Icon(Icons.contacts),
title: Text("Contact Us"),
onTap: () {
Get.back();
},
);
}
ListTile get drawersettings {
return ListTile(
leading: Icon(Icons.settings),
title: Text("Settings"),
onTap: () {
Get.back();
},
);
}
ListTile get drawerFavorilerim {
return ListTile(
leading: Icon(
Icons.star,
color: Colors.yellow,
),
title: Text("Favorilerim"),
onTap: () {
Get.to(FavoriListPage());
},
);
}
UserAccountsDrawerHeader get userAccountsDrawerHeader {
return UserAccountsDrawerHeader(
accountName: Text("UserName"),
accountEmail: Text("E-mail"),
currentAccountPicture: CircleAvatar(
backgroundColor: Colors.grey,
child: Text(
"",
style: TextStyle(fontSize: 40.0),
),
),
);
}
}
You can simple do it like this
class ControllerSample extends GetxController{
final active = false.obs
functionPass(){
active(!active.value);
}
}
on page
final sampleController = Get.put(ControllerSample());
Obx(
()=> Form(
key: yourkeyState,
child: Column(
children: [
TextFormField(
//some other needed
//put the function on onChanged
onChanged:(value){
if(value.isEmpty){
sampleController.functionPass();
}else{
sampleController.functionPass();
}
}
),
Visibility(
visible: sampleController.active.value,
child: TextFormField(
//some other info
)
),
]
)
)
)

How to add/sum TextFormField values in Flutter?

How can I add the values of several formfields in Flutter to dynamically calculate a total field? Imagine E.g. If the three textformfields had values of 1, 2, 3 then the total field should display 6.
I am able to convert the values to double using double.parse(value).
Code:
class _GivingPageState extends State<GivingPage> {
final _formKey = GlobalKey<FormState>();
double collection1;
double collection2;
double collection3;
double total;
#override
void initState() {
collection1 = 0;
collection2 = 0;
collection3 = 0;
total = 0;
super.initState();
}
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: GestureDetector(
onTap: () {
FocusScope.of(context).unfocus();
},
child: Column(
children: <Widget>[
Expanded(
child: buildContent(),
),
],
),
),
),
);
}
Widget buildContent() {
return Container(
color: Colors.white,
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 10.0),
child: lightCard(
child: Container(
padding: EdgeInsets.only(left: 0.0, right: 10, top: 10, bottom: 10),
child: Padding(
padding: const EdgeInsets.only(left: 18.0, bottom: 10),
child: Container(
child: Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(left: 0.0, bottom: 10),
child: Text(
'Collection Baskets',
style: TextStyle(
fontSize: 16, fontWeight: FontWeight.bold),
),
),
Text('Which collection baskets(s) are you giving to?'),
SizedBox(height: 15),
_buildBasket(
collectionName: 'Amount 1',
collection: collection1,
),
SizedBox(height: 10),
_buildBasket(
collectionName: 'Amount 2',
collection: collection2,
),
SizedBox(height: 10),
_buildBasket(
collectionName: 'Amount 3',
collection: collection3,
),
SizedBox(height: 10),
_buildTotal()
],
),
),
),
),
)),
));
}
void _updateTotal() {
setState(() {
total = collection1 + collection2 + collection3;
});
}
Row _buildBasket(
{#required String collectionName, #required double collection}) {
return Row(
children: <Widget>[
Expanded(
flex: 1,
child: Text(
collectionName,
style: TextStyle(fontSize: 16),
),
),
SizedBox(width: 10),
Expanded(
flex: 1,
child: Row(
children: <Widget>[
Text(
'£',
style: TextStyle(fontSize: 20),
),
SizedBox(width: 10),
Expanded(
child: numberFormField(
onChanged: (value) {
setState(() {
collection = double.parse(value);
_updateTotal();
});
},
textFieldKey: null),
),
],
),
),
],
);
}
Row _buildTotal() {
return Row(
children: <Widget>[
Expanded(
flex: 1,
child: Text(
'Total',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
),
SizedBox(width: 10),
Expanded(
flex: 1,
child: Row(
children: <Widget>[
Text(
'£',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
SizedBox(width: 10),
Expanded(
child: Container(
height: 50,
decoration: BoxDecoration(
color: AppColors.secondaryElement,
borderRadius: Radii.k25pxRadius,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
"${formatNumber(amount: total)}",
textAlign: TextAlign.center,
style: TextStyle(
fontWeight: FontWeight.bold, fontSize: 20),
),
],
),
),
),
],
),
),
],
);
}
}
Does this work for you?
class Home extends StatefulWidget{
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home>{
double firstFieldValue = 0;
double secondFieldValue = 0;
double thirdFieldValue = 0;
#override
Widget build(BuildContext context){
return Scaffold(
body: Center(
child: Column(
children: [
TextField(
onChanged: (value){
if(value.isEmpty){
setState(() => firstFieldValue = 0);
}else{
setState((){
firstFieldValue = double.parse(value);
});
}
}
),
TextField(
onChanged: (value){
if(value.isEmpty){
setState(() => secondFieldValue = 0);
}else{
setState((){
secondFieldValue = double.parse(value);
});
}
}
),
TextField(
onChanged: (value){
if(value.isEmpty){
setState(() => thirdFieldValue = 0);
}else{
setState((){
thirdFieldValue = double.parse(value);
});
}
}
),
Text(
"${firstFieldValue + secondFieldValue + thirdFieldValue}"
)
]
)
),
);
}
}

Scroll not working in vertical list created using ListView?

I've created a vertical list inside a scrollable container. But the issue I'm facing is that the list is not scrolling.
This is the component which creates the parent container.
class _MainPageState extends State<MainPage> {
SharedPreferences sharedPreferences;
String _date = "Today";
#override
void initState() {
super.initState();
this.checkLoginStatus();
}
checkLoginStatus() async {
sharedPreferences = await SharedPreferences.getInstance();
if (sharedPreferences.getString("token") == null) {
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(
builder: (BuildContext context) => Login(),
),
(Route<dynamic> route) => false,
);
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: loggedInBar(sharedPreferences, context),
drawer: appDrawer(sharedPreferences, context),
body: SingleChildScrollView(
child: Container(
decoration: BoxDecoration(
color: hexToColor("#FFFFFF"),
),
child: Column(
children: <Widget>[
hero(),
SizedBox(height: 10),
Container(
padding: const EdgeInsets.fromLTRB(30, 20, 30, 0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
customText(
'$_date',
"#000000",
"26.0",
TextAlign.center,
"Roboto Black",
FontWeight.w900,
),
OutlineButton(
child: Container(
alignment: Alignment.center,
height: 42.0,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Row(
children: <Widget>[
Container(
child: Row(
children: <Widget>[
customText(
"CHOOSE DAY",
"#EC2F3C",
"18",
TextAlign.center,
"Roboto Bold",
FontWeight.w800,
),
Icon(
Icons.date_range,
size: 22.0,
color: hexToColor("#EC2F3C"),
),
],
),
)
],
),
],
),
),
onPressed: () {
DatePicker.showDatePicker(context,
theme: DatePickerTheme(
containerHeight: 210.0,
),
showTitleActions: true,
minTime: DateTime(
DateTime.now().year - 100,
DateTime.now().month,
DateTime.now().day,
),
maxTime: DateTime(
DateTime.now().year - 17,
DateTime.now().month,
DateTime.now().day,
), onConfirm: (date) {
print('confirm $date');
var dateString = date;
var formattedDate = Jiffy(dateString).yMMMd;
setState(() {
_date = formattedDate;
});
}, currentTime: DateTime.now(), locale: LocaleType.en);
},
color: hexToColor("#efefef"),
splashColor: hexToColor("#efefef"),
highlightElevation: 2,
borderSide: BorderSide(
color: hexToColor("#EC2F3C"),
width: 2,
),
highlightedBorderColor: hexToColor("#EC2F3C"),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(3),
),
),
],
),
),
AllEvents(), // the widget which creates the list(mentioned below)
SizedBox(height: 30),
footer(),
],
),
),
),
);
}
}
The widget which creates the list is this.
class _AllEventsState extends State<AllEvents> {
final String url = "<api url>";
List data;
#override
void initState() {
super.initState();
this.getAllEvents();
}
createRoute(id) {
Navigator.pushNamed(context, '/eventdetail', arguments: id);
}
Future<String> getAllEvents() async {
var response = await http.get(
Uri.encodeFull(url),
headers: {"Accept": "application/json"},
);
setState(() {
var convertDataToJson = jsonDecode(response.body);
data = convertDataToJson["events"];
});
return "Success";
}
#override
Widget build(BuildContext context) {
ScrollController _controller = new ScrollController();
return Container(
child: ListView.builder(
scrollDirection: Axis.vertical,
physics: const AlwaysScrollableScrollPhysics(),
controller: _controller,
shrinkWrap: true,
itemCount: data == null ? 0 : data.length,
itemBuilder: (BuildContext cont, int index) {
// format date
var dateString = data[index]["eventDate"];
var eventDate = Jiffy(dateString).MMMEd;
if (data == null) {
return Center(
child: Container(
padding: const EdgeInsets.fromLTRB(30, 20, 30, 20),
child: CircularProgressIndicator(),
),
);
} else {
return Container(
padding: const EdgeInsets.fromLTRB(30, 7, 30, 7),
child: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
new InkWell(
onTap: () {
createRoute(data[index]['_id']);
},
child: Card(
child: Container(
decoration: BoxDecoration(
border: Border.all(
width: 3,
color: hexToColor("#EBEBEB"),
),
borderRadius: BorderRadius.circular(8.0),
),
padding: const EdgeInsets.fromLTRB(20, 20, 20, 20),
child: Column(
children: <Widget>[
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: <Widget>[
customText(
eventDate.toString(),
"#000000",
"20.0",
TextAlign.left,
"Roboto Black",
FontWeight.w900,
),
customText(
"10, 9",
"#000000",
"20.0",
TextAlign.right,
"Roboto Black",
FontWeight.w900,
),
],
),
SizedBox(height: 20),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Expanded(
child: customText(
"${data[index]['city']} | ${data[index]['arenaName']} | ${data[index]['categories'][0]['title']}",
"#000000",
"18.0",
TextAlign.left,
"Roboto Black",
FontWeight.w900,
),
),
],
),
],
),
),
),
),
],
),
),
);
}
},
),
);
}
}
The scroll is only working on touching outside the list area and once the list area covers the entire screen I'm unable to scroll the page further. I think I'm doing many mistakes here as I'm a noob in flutter. I'm unable to wrap my head around what I'm doing wrong as I don't think this is how it's supposed to work.
Please help me fix this issue. Any help would be great? Thank you
change the scroll physics of list to NeverScrollableScrollPhysics
ListView.builder(
scrollDirection: Axis.vertical,
physics: const NeverScrollableScrollPhysics(),
controller: _controller,
shrinkWrap: true,
itemCount: data == null ? 0 : data.length,
itemBuilder: (BuildContext cont, int index) {
// code for building list item
});