How to make Dependent DropdownButtonFormField in showDialog in flutter? - flutter

I make the Dependent DropdownButtonFormField in showDialog.
when i select the item of first dropdown the values not showing in second dropdown which is dependent on first dropdown.
But when i close the Dialog and reopen the dialog the values showing in second dropdown.
So here my Question is how to refresh second dropdown when first dropdown value is changed?
Future<bool> showDropDownDialog(title) async {
List<DropdownMenuItem<AllocationType>> items = [];
dropDownAllocationTypeModels.forEach((element) {
items.add(DropdownMenuItem(
child: Text(
element.allocationTypeName!,
style: Themes.getTextStyle(context),
),
value: element,
));
});
List<DropdownMenuItem<ServiceArea>> serviceAreaitems = [];
dropDownServiceAreaModels.forEach((element) {
serviceAreaitems.add(DropdownMenuItem(
child: Text(
element.serviceAreaName ?? "1",
style: Themes.getTextStyle(context),
),
value: element,
));
});
void onTeamChange(area) {
setState(() {
dropdownValueTeamType = null;
dropdownValueServiceArea = area;
dropDownTeamTypeModels = [];
});
ApiHelper()
.getTeamsByServiceArea(dropdownValueServiceArea!.id!)
.then((value) => {
setState(() {
dropDownTeamTypeModels = value;
})
});
}
return await showDialog(
context: context,
builder: (context) => Center(
child: Form(
key: _formKey,
child: Container(
padding: EdgeInsets.all(10),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Card(
color: Colors.blueGrey[100],
child: ClipRRect(
borderRadius: BorderRadius.circular(10),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ClipRRect(
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(15),
bottomRight: Radius.circular(15),
),
child: Container(
padding: EdgeInsets.all(10),
alignment: Alignment.center,
width: 300,
color:
Themes.getPrimaryDarkBackgroundColor(
context),
child: Text(
title,
style: Themes.getTitleTextStyleWhite(
context),
),
),
),
],
),
Padding(
padding: EdgeInsets.only(
left: Constants.APP_PADDING,
right: Constants.APP_PADDING,
top: Constants.APP_PADDING),
child: DropdownButtonFormField<ServiceArea>(
style: Themes.getTextFieldTextStyle(context),
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: AppLocalizations.of(context)
.hintSelectServiceArea,
),
value: dropdownValueServiceArea,
isExpanded: true,
items: serviceAreaitems,
onChanged: (value) {
setState(() {
dropdownValueServiceArea = value;
onTeamChange(value);
});
},
),
),
Padding(
padding: EdgeInsets.only(
left: Constants.APP_PADDING,
right: Constants.APP_PADDING,
top: Constants.APP_PADDING),
child: DropdownButtonFormField<dynamic>(
style: Themes.getTextFieldTextStyle(context),
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: AppLocalizations.of(context)
.hintSelectTeamType,
),
value: dropdownValueTeamType,
isExpanded: true,
items: dropDownTeamTypeModels.map((team) {
return DropdownMenuItem<dynamic>(
value: team,
child: Text(team),
);
}).toList(),
onChanged: (value) {
setState(() {
dropdownValueTeamType = value;
});
},
),
),
],
)),
elevation: 8,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10)),
),
],
),
),
),
),
) ??
false; //if showDialouge had returned null, then return false
}

As I see you use statefull widget approach.
So I believe you have to wrap parent dialog widget to statefull, declare variables (as dropdownValueServiceArea) in it, and change them inside dropdown callbacks with
setState(()=> dropdownValueServiceArea = newValue);

Related

Flutter || Checkbox on hover doesn't give on tap cursor permission

I am working on dropdownmenu items where in the drop-down menu item there are several checkboxes but any of the checkboxes on hover don't give on tap cursor permission.
This is a very strange thing I found out as I have already used the checkbox before but this type of error I didn't receive.
I think maybe the problem is in dropdownmenu.
I have also included the video for better understanding of my problem.
my code :-
Container(
width: 160,
//margin: const EdgeInsets.only(top: 10.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5), color: Colors.white),
child: ListTileTheme(
contentPadding: EdgeInsets.all(0),
dense: true,
horizontalTitleGap: 0.0,
minLeadingWidth: 0,
child: ExpansionTile(
iconColor: primaryBackgroundLightGrey,
title: Text(
listOFSelectedItem.isEmpty
? "Project type"
: listOFSelectedItem[0],
style: t5O40),
children: <Widget>[
Container(
height: 10,
color: primaryBackgroundLightGrey,
),
ListView.builder(
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: widget.listOFStrings.length,
itemBuilder: (BuildContext context, int index) {
return Column(
children: [
Container(
height: 10,
),
Container(
margin: const EdgeInsets.only(bottom: 8.0),
child: _ViewItem(
item: widget.listOFStrings[index],
selected: (val) {
selectedText = val;
if (listOFSelectedItem.contains(val)) {
listOFSelectedItem.remove(val);
} else {
listOFSelectedItem.add(val);
}
widget.selectedList(listOFSelectedItem);
setState(() {});
},
itemSelected: listOFSelectedItem
.contains(widget.listOFStrings[index])),
),
],
);
},
),
],
),
),
),
class _ViewItem extends StatelessWidget {
String item;
bool itemSelected;
final Function(String) selected;
_ViewItem(
{required this.item, required this.itemSelected, required this.selected});
#override
Widget build(BuildContext context) {
var size = MediaQuery.of(context).size;
return Padding(
padding: EdgeInsets.only(
left: size.width * .015,
),
child: Row(
children: [
SizedBox(
height: 2,
width: 2,
child: Checkbox(
value: itemSelected,
onChanged: (val) {
selected(item);
},
hoverColor: Colors.transparent,
checkColor: Colors.white,
activeColor: Colors.grey),
),
SizedBox(
width: size.width * .010,
),
Text(item, style: t3O60),
],
),
);
}
}
You can adapt the example to your own code
dropdownBuilder: _customDropDownExample,
popupItemBuilder: _customPopupItemBuilderExample,
Widget _customDropDownExample(
BuildContext context, UserModel? item, String itemDesignation) {
if (item == null) {
return Container();
}
return Container(
child: (item.avatar == null)
? ListTile(
contentPadding: EdgeInsets.all(0),
leading: CircleAvatar(),
title: Text("No item selected"),
)
: ListTile(
contentPadding: EdgeInsets.all(0),
leading: CircleAvatar(
// this does not work - throws 404 error
// backgroundImage: NetworkImage(item.avatar ?? ''),
),
title: Text(item.name),
subtitle: Text(
item.createdAt.toString(),
),
),
);
After that
Widget _customPopupItemBuilderExample(
BuildContext context, UserModel item, bool isSelected) {
return Container(
margin: EdgeInsets.symmetric(horizontal: 8),
decoration: !isSelected
? null
: BoxDecoration(
border: Border.all(color: Theme.of(context).primaryColor),
borderRadius: BorderRadius.circular(5),
color: Colors.white,
),
child: ListTile(
selected: isSelected,
title: Text(item.name),
subtitle: Text(item.createdAt.toString()),
leading: CircleAvatar(
// this does not work - throws 404 error
// backgroundImage: NetworkImage(item.avatar ?? ''),
),
),
);
I am using this package https://pub.dev/packages/dropdown_button2
Multiselect Dropdown with Checkboxes
final List<String> items = [
'Item1',
'Item2',
'Item3',
'Item4',
];
List<String> selectedItems = [];
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: DropdownButtonHideUnderline(
child: DropdownButton2(
isExpanded: true,
hint: Align(
alignment: AlignmentDirectional.center,
child: Text(
'Select Items',
style: TextStyle(
fontSize: 14,
color: Theme.of(context).hintColor,
),
),
),
items: items.map((item) {
return DropdownMenuItem<String>(
value: item,
//disable default onTap to avoid closing menu when selecting an item
enabled: false,
child: StatefulBuilder(
builder: (context, menuSetState) {
final _isSelected = selectedItems.contains(item);
return InkWell(
onTap: () {
_isSelected
? selectedItems.remove(item)
: selectedItems.add(item);
//This rebuilds the StatefulWidget to update the button's text
setState(() {});
//This rebuilds the dropdownMenu Widget to update the check mark
menuSetState(() {});
},
child: Container(
height: double.infinity,
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: Row(
children: [
_isSelected
? const Icon(Icons.check_box_outlined)
: const Icon(Icons.check_box_outline_blank),
const SizedBox(width: 16),
Text(
item,
style: const TextStyle(
fontSize: 14,
),
),
],
),
),
);
},
),
);
}).toList(),
//Use last selected item as the current value so if we've limited menu height, it scroll to last item.
value: selectedItems.isEmpty ? null : selectedItems.last,
onChanged: (value) {},
buttonHeight: 40,
buttonWidth: 140,
itemHeight: 40,
itemPadding: EdgeInsets.zero,
selectedItemBuilder: (context) {
return items.map(
(item) {
return Container(
alignment: AlignmentDirectional.center,
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: Text(
selectedItems.join(', '),
style: const TextStyle(
fontSize: 14,
overflow: TextOverflow.ellipsis,
),
maxLines: 1,
),
);
},
).toList();
},
),
),
),
);
}

Error on my UI using SingleChildScrollView when i try to run my firebase?

this is my first time using community to ask about my project. First thing first, english isn't my first language and I'm a very beginner in flutter world. I'm trying to build my first mobile application using flutter and now I'm trying to connect my project to firebase (I looked at youtube tutorial). I don't know if the firebase already connect because when I'm trying to run the application and go to registration page, there this error message.
And here is my code:
import 'package:dfu_check_application/common/auth_controller.dart';
import 'package:flutter/material.dart';
import 'package:dfu_check_application/common/theme_helper.dart';
import 'package:dfu_check_application/pages/widgets/header_widget.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:hexcolor/hexcolor.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'profile_page.dart';
class RegistrationPage extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return _RegistrationPageState();
}
}
class _RegistrationPageState extends State<RegistrationPage> {
final _formKey = GlobalKey<FormState>();
bool checkedValue = false;
bool checkboxValue = false;
#override
Widget build(BuildContext context) {
var nameController = TextEditingController();
var emailController = TextEditingController();
var passwordController = TextEditingController();
return Scaffold(
backgroundColor: Colors.white,
body: SingleChildScrollView(
child: Stack(children: [
Container(
height: 150,
child: HeaderWidget(150, false, Icons.person_add_alt_1_rounded),
),
Container(
margin: EdgeInsets.fromLTRB(25, 50, 25, 10),
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
alignment: Alignment.center,
child: Column(
children: [
Form(
key: _formKey,
child: Column(
children: [
GestureDetector(
child: Stack(
children: [
Container(
padding: EdgeInsets.all(10),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(100),
border:
Border.all(width: 5, color: Colors.white),
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colors.black12,
blurRadius: 20,
offset: const Offset(5, 5),
),
],
),
child: Icon(
Icons.person,
color: Colors.grey.shade300,
size: 80.0,
),
),
Container(
padding: EdgeInsets.fromLTRB(80, 80, 0, 0),
child: Icon(
Icons.add_circle,
color: Colors.grey.shade700,
size: 25.0,
),
),
],
),
),
SizedBox(
height: 30,
),
Container(
child: TextFormField(
controller: nameController,
decoration: ThemeHelper().textInputDecoration(
'Full Name', 'Enter your full name'),
),
decoration: ThemeHelper().inputBoxDecorationShaddow(),
),
SizedBox(
height: 30,
),
SizedBox(height: 20.0),
Container(
child: TextFormField(
controller: emailController,
decoration: ThemeHelper().textInputDecoration(
"E-mail address", "Enter your email"),
keyboardType: TextInputType.emailAddress,
validator: (val) {
// ignore: prefer_is_not_empty
if (!(val!.isEmpty) &&
!RegExp(r"^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+#[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,253}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,253}[a-zA-Z0-9])?)*$")
.hasMatch(val)) {
return "Enter a valid email address";
}
return null;
},
),
decoration: ThemeHelper().inputBoxDecorationShaddow(),
),
SizedBox(height: 20.0),
Container(
child: TextFormField(
obscureText: true,
controller: passwordController,
decoration: ThemeHelper().textInputDecoration(
"Password*", "Enter your password"),
validator: (val) {
if (val!.isEmpty) {
return "Please enter your password";
}
return null;
},
),
decoration: ThemeHelper().inputBoxDecorationShaddow(),
),
SizedBox(height: 15.0),
FormField<bool>(
builder: (state) {
return Column(
children: <Widget>[
Row(
children: <Widget>[
Checkbox(
value: checkboxValue,
onChanged: (value) {
setState(() {
checkboxValue = value!;
state.didChange(value);
});
}),
Text(
"I accept all terms and conditions.",
style: TextStyle(color: Colors.grey),
),
],
),
Container(
alignment: Alignment.centerLeft,
child: Text(
state.errorText ?? '',
textAlign: TextAlign.left,
style: TextStyle(
color: Theme.of(context).errorColor,
fontSize: 12,
),
),
)
],
);
},
validator: (value) {
if (!checkboxValue) {
return 'You need to accept terms and conditions';
} else {
return null;
}
},
),
SizedBox(height: 20.0),
GestureDetector(
onTap: () {
AuthController.instance.register(
nameController.text.trim(),
emailController.text.trim(),
passwordController.text.trim());
},
),
Container(
decoration: ThemeHelper().buttonBoxDecoration(context),
child: ElevatedButton(
style: ThemeHelper().buttonStyle(),
child: Padding(
padding: const EdgeInsets.fromLTRB(40, 10, 40, 10),
child: Text(
"Register".toUpperCase(),
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
),
onPressed: () {
if (_formKey.currentState!.validate()) {
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(
builder: (context) => ProfilePage()),
(Route<dynamic> route) => false);
}
},
),
),
SizedBox(height: 30.0),
Text(
"Or create account using social media",
style: TextStyle(color: Colors.grey),
),
SizedBox(height: 25.0),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
GestureDetector(
child: FaIcon(
FontAwesomeIcons.google,
size: 35,
color: HexColor("#EC2D2F"),
),
onTap: () {
setState(() {
showDialog(
context: context,
builder: (BuildContext context) {
return ThemeHelper().alartDialog(
"Google Account",
"You tap on Google icon.",
context);
},
);
});
},
),
],
),
],
),
),
],
),
),
]),
),
);
}
}
If you guys see more error on my code, please tell me because I'm very clueless about this. Thank you in advance!
The issue occurs from Stack the one inside
Column(
children: [
Form(
key: _formKey,
child: Column(
children: [
GestureDetector(
child: Stack( // this one
Can be fixed by providing hight
GestureDetector(
child: SizedBox(
height: MediaQuery.of(context).size.height, //this based on your need
child: Stack(
I think you can re struct the widget and don't need to use multi-Stack.
More about /ui/layout and Unbounded height / width

Getting the error "Null check operator used on a null value"

Whenever I click on any textfield of the form, I get the following error in the screen:
Null check operator used on a null value
See also https://flutter.dev/docs
Also, the console is showing the following error:
The following ArgumentError was thrown resolving an image codec:
Invalid argument(s): No host specified in URI file:///
Here is the code of the login form. I can't figure out why this error is showing up.
// .....
child: Form(
key: _formKey,
autovalidateMode: AutovalidateMode.disabled,
child: ListView.builder(
itemCount: 1,
shrinkWrap: false,
itemBuilder: (BuildContext context, int index) {
return Column(
children: [
SizedBox(height: 30),
HeroImage(),
SizedBox(height: 20),
Container(
child: Padding(
padding: const EdgeInsets.only(left: 20, right: 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
AppLableWidget(
title: Languages.of(context)!.labelEmail,
),
CardTextFieldWidget(
focus: (v) {
FocusScope.of(context).nextFocus();
},
textInputAction: TextInputAction.next,
hintText: Languages.of(context)!.labelEnterYourEmailID,
textInputType: TextInputType.emailAddress,
textEditingController: _textEmail,
validator: kvalidateEmail,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
AppLableWidget(
title: Languages.of(context)!.labelPassword,
),
],
),
CardPasswordTextFieldWidget(
textEditingController: _textPassword,
validator: kvalidatePassword,
hintText: Languages.of(context)!.labelEnterYourPassword,
isPasswordVisible: _passwordVisible),
Row(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
/* Row(
children: [
Padding(
padding: const EdgeInsets.all(10.0),
child: ClipRRect(
clipBehavior: Clip.hardEdge,
borderRadius: BorderRadius.all(Radius.circular(5)),
child: SizedBox(
width: 40.0,
height: ScreenUtil().setHeight(40),
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
child: Container(
child: Theme(
data: ThemeData(
unselectedWidgetColor: Colors.transparent,
),
child: Checkbox(
value: isRememberMe,
onChanged: (state) =>
setState(() => isRememberMe = !isRememberMe),
activeColor: Colors.transparent,
checkColor: Color(Constants.colorTheme),
materialTapTargetSize: MaterialTapTargetSize.padded,
),
),
),
),
),
),
),
Text(
Languages.of(context)!.labelRememberMe,
style: TextStyle(fontSize: 14.0, fontFamily: Constants.appFont),
),
],
),*/
Container(
padding: const EdgeInsets.all(10.0),
alignment: Alignment.centerRight,
child: GestureDetector(
onTap: () {
Navigator.of(context).push(Transitions(
transitionType: TransitionType.fade,
curve: Curves.bounceInOut,
reverseCurve: Curves.fastLinearToSlowEaseIn,
widget: ChangePassword()));
},
child: Text(
Languages.of(context)!.labelForgotPassword,
style: TextStyle(fontFamily: Constants.appFontBold,fontSize: ScreenUtil().setSp(16),),
),
),
),
],
),
Padding(
padding: EdgeInsets.only(left: 20.0, right: 20,top: 10, bottom: 10),
child: RoundedCornerAppButton(
onPressed: () {
if (
_formKey.currentState!.validate()) {
// if (SharedPreferenceUtil.getString(
// Constants
// .appPush_oneSingleToken)
// .isEmpty) {
// getOneSingleToken(SharedPreferenceUtil
// .getString(Constants
// .appSettingCustomerAppId));
// } else {
// }
Constants.checkNetwork().whenComplete(() => callUserLogin());
} else {
setState(() {
// validation error
//_autoValidate = true;
});
}
},
btnLabel: Languages.of(context)!.labelLogin,
),
),
SizedBox(
height: 10.0,
),
GestureDetector(
onTap: () {
Navigator.of(context).push(Transitions(
transitionType: TransitionType.slideUp,
curve: Curves.bounceInOut,
reverseCurve: Curves.fastLinearToSlowEaseIn,
widget: CreateNewAccount()));
},
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
Languages.of(context)!.labelDonthaveAcc,
style: TextStyle(fontFamily: Constants.appFont,fontSize: ScreenUtil().setSp(14),),
),
Text(
Languages.of(context)!.labelCreateNow,
style: TextStyle(fontFamily: Constants.appFontBold,fontSize: ScreenUtil().setSp(16),),
),
],
),
),
SizedBox(
height: 20,
),
InkWell(
onTap: () {
Navigator.of(context).push(Transitions(
transitionType: TransitionType.slideUp,
curve: Curves.bounceInOut,
reverseCurve: Curves.fastLinearToSlowEaseIn,
widget: DashboardScreen(0)));
},
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
Languages.of(context)!.labelSkipNow,
style: TextStyle(
color: Colors.black,
decoration: TextDecoration.underline,
decorationColor: Colors.black,
fontWeight: FontWeight.bold,
decorationThickness: 5,
fontSize: ScreenUtil().setSp(16),
fontFamily: Constants.appFontBold,),
),
],
),
),
],
),
),
),
],
);
},
),
),
//.....
String kvalidatePassword(String? value) {
Pattern pattern = r'^(?=.*?[a-z])(?=.*?[0-9]).{8,}$';
if (value!.isEmpty) return 'Username is Required.';
final RegExp nameExp = new RegExp(pattern as String);
if (!nameExp.hasMatch(value))
return 'Please enter only alphabetical characters.';
return value;
}
String kvalidatePassword(String? value) {
Pattern pattern = r'^(?=.*?[a-z])(?=.*?[0-9]).{8,}$';
if (value!.isEmpty) return 'Username is Required.';
final RegExp nameExp = new RegExp(pattern as String);
if (!nameExp.hasMatch(value))
return 'Please enter only alphabetical characters.';
return value;
}
Please help. New to Flutter and this is an old project I need to fix.
AppLableWidget(title: Languages.of(context)!.labelEmail),
Try This...
AppLableWidget(title: Languages.of(context)?.labelEmail ?? ''),
String value = 'Test String';
String? value1;
Text(value ?? ''), // output --> Test String
Text(value1 ?? ''), // output --> ''
// here manage if value are null then return ''(Blank Text) otherwise Text.
This error occurs when you use a bang operator (!) on a nullable instance which wasn't initialized.
For example:
String? foo; // Nullable String
void main() {
var len = foo!.length; // Runtime error: Null check operator used on a null value
}
Solution:
You need to find out where you're using the bang operator in your code. Once you are there, you can use any of the following solutions:
Use a local variable
var f = foo;
if (f != null) {
var len = f.length; // Safe
}
Use ?. and ??
var len = foo?.length ?? 0; // Provide a default value if foo was null.

How to return data from Flutter dialog?

I'm having a dialog which opens up when click of a button and having a Listtile which Radio as a child in order to make a selection. As the user makes the selection and accepts it, I'm trying to update the selected part in the UI but i'm getting a null response while the value is being returned.
This is my custom statefull dialog
class _CustomScannerSelectDialogState extends State<CustomScannerSelectDialog> {
int selectedRadio;
setSelectedRadio(int val) {
setState(() {
selectedRadio = val;
});
}
#override
Widget build(BuildContext context) {
return Expanded(
child: Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
elevation: 0,
backgroundColor: Colors.transparent,
child: Stack(
children: [
Container(
padding: EdgeInsets.only(left: 20, top: 40, right: 20, bottom: 20),
margin: EdgeInsets.only(top: 40),
decoration: BoxDecoration(
shape: BoxShape.rectangle,
color: Colors.white,
borderRadius: BorderRadius.circular(20),
boxShadow: [
BoxShadow(color: Colors.black, offset: Offset(0, 10), blurRadius: 10),
]),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
SizedBox(
height: 20,
),
Text(
'Select the Scanner type',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.w600),
),
SizedBox(
height: 15,
),
ListTile(
title: const Text('QR & Barcode scanner'),
leading: Radio(
activeColor: Color(0xFFCC0000),
value: 1,
groupValue: selectedRadio,
onChanged: (val) {
print("Radio $val");
setSelectedRadio(val);
},
),
),
ListTile(
title: const Text('Barras Scanner'),
leading: Radio(
activeColor: Color(0xFFCC0000),
value: 2,
groupValue: selectedRadio,
onChanged: (val) {
print("Radio $val");
setSelectedRadio(val);
},
),
),
SizedBox(
height: 20,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
CustomButton(
buttonText: 'CANCEL',
buttonFunction: () {
Navigator.pop(context);
return;
},
),
RaisedButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10), side: BorderSide(color: Colors.blueGrey)),
textColor: Color(0xFFCD853F),
color: Colors.white,
onPressed: () {
print("Selected radio is " + selectedRadio.toString());
Navigator.pop(context);
return selectedRadio.toString();
},
child: new Text(
'ACCEPT',
),
)
],
),
],
),
),
],
),
));
}
}
And on click of a button I'm calling a function as _showScannerSelectionDialog
_showScannerSelectionDialog() {
showDialog(
context: context,
builder: (BuildContext context) {
return CustomScannerSelectDialog();
},
).then((value) => print("Value is "+value.toString()));
}
Here the value I'm getting printed is null but i need the value of the selectedRadio
I think, you only need to simply use the following when closing the dialog:
var result = selectedRadio.toString(); // or any value.
Navigator.pop(context, result);

flutter bottom sheet freezes the app UI without showing any errors on the console

When I click on the button that should display my bottom sheet, The app UI freezes, and the console displays
that bottom sheet has been opened =>OPEN BOTTOMSHEET: 819031530 without any errors.
my bottom sheet widget is pretty complex.
I am using get package
Get.bottomSheet(
SearchBottomSheetWidget(),
)
The SearchBottomSheetWidget widget
class SearchBottomSheetWidget extends GetView<SearchDataService> {
#override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(22.0),
topRight: Radius.circular(22.0),
),
),
height: 500,
child: Obx(
() => controller.isSpecial.value == true
? Stack(
children: [
GeneralOffers(),
SpecialOffers(),
],
)
: Stack(
children: [
SpecialOffers(),
GeneralOffers(),
],
),
),
);
}
}
The GeneralOffers and SpecialOffers widgets
class GeneralOffers extends GetView<SearchDataService> {
#override
Widget build(BuildContext context) {
return SearchSide(
backColor: AppUi.colors.appWhite,
forgroundColor: AppUi.colors.appRed,
boolState: false,
mainAxisAlignment: controller.isSpecial.value == false
? MainAxisAlignment.start
: MainAxisAlignment.end,
headerButtons: Container(
child: Row(
children: [
Expanded(
child: Container(),
),
Expanded(
child: AppButton(
color: AppUi.colors.appWhite,
text: S.current.generalOffers,
fontSize: controller.isSpecial.value == false ? 60.sp : 50.sp,
titleColor: AppUi.colors.appRed,
borderRadius: BorderRadius.only(
topRight: Radius.circular(50.0),
topLeft: Radius.circular(50.0),
),
border: Border.all(
color: AppUi.colors.appWhite,
),
onTap: () => controller.isSpecial.value = false,
),
),
],
),
),
);
}
}
class SpecialOffers extends GetView<SearchDataService> {
#override
Widget build(BuildContext context) {
return SearchSide(
backColor: AppUi.colors.appRed,
forgroundColor: AppUi.colors.appWhite,
buttonText: S.current.speciallOffers,
boolState: true,
mainAxisAlignment: controller.isSpecial.value
? MainAxisAlignment.start
: MainAxisAlignment.end,
headerButtons: Row(
children: [
Expanded(
child: AppButton(
color: AppUi.colors.appRed,
text: S.current.speciallOffers,
fontSize: controller.isSpecial.value == true ? 60.sp : 50.sp,
titleColor: AppUi.colors.appWhite,
borderRadius: BorderRadius.only(
topRight: Radius.circular(50.0),
topLeft: Radius.circular(50.0),
),
border: Border.all(
color: AppUi.colors.appRed,
),
onTap: () => controller.isSpecial.value = true,
),
),
Expanded(
child: Container(),
),
],
),
);
}
}
finally, the widget that I think the problem is in it SearchSide
class SearchSide extends GetView<SearchDataService> {
final Color backColor;
final Color forgroundColor;
final MainAxisAlignment mainAxisAlignment;
final String buttonText;
final bool boolState;
final Widget headerButtons;
SearchSide({
this.backColor,
this.forgroundColor,
this.mainAxisAlignment,
this.buttonText,
this.boolState,
this.headerButtons,
});
#override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: mainAxisAlignment,
children: [
headerButtons,
Container(
width: Get.width,
height: controller.isSpecial.value == boolState
? Get.height * .5
: Get.height * .485,
padding: EdgeInsets.symmetric(horizontal: 12.0),
decoration: BoxDecoration(
color: backColor,
),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
SearchDropDown(
onChange: (val) => controller.assignCategoryValue(val),
value: controller.categories[0],
items: controller.categories,
itemColor: forgroundColor,
),
Row(
children: [
Expanded(
child: Padding(
padding: const EdgeInsets.only(right: 12.0),
child: SearchDropDown(
onChange: (val) => controller.assignBrandValue(val),
value: controller.brands[0],
items: controller.brands,
itemColor: forgroundColor,
),
),
),
Expanded(
child: Padding(
padding: const EdgeInsets.only(left: 12.0),
child: SearchDropDown(
onChange: (val) => controller.assignModelValue(val),
value: controller.models[0],
items: controller.models,
itemColor: forgroundColor,
),
),
),
],
),
Row(
children: [
Expanded(
child: Padding(
padding: const EdgeInsets.only(right: 12.0),
child: SearchDropDown(
items: controller.years,
value: controller.years[0],
onChange: (val) => controller.assignFromYearValue(val),
itemColor: forgroundColor,
),
),
),
Expanded(
child: Padding(
padding: const EdgeInsets.only(left: 12.0),
child: SearchDropDown(
items: controller.years,
value: controller.years[0],
onChange: (val) => controller.assignToYearValue(val),
itemColor: forgroundColor,
),
),
),
],
),
Row(
children: [
Expanded(
child: Padding(
padding: const EdgeInsets.only(right: 12.0),
child: SearchDropDown(
items: controller.prices,
value: controller.prices[0],
itemColor: forgroundColor,
onChange: (val) => controller.assignFromPriceValue(val),
),
),
),
Expanded(
child: Padding(
padding: const EdgeInsets.only(left: 12.0),
child: SearchDropDown(
value: controller.prices[0],
items: controller.prices,
itemColor: forgroundColor,
onChange: (val) => controller.assignToPriceValue(val),
),
),
),
],
),
NewOrUsed(forgroundColor),
SearchAndClear(
backColor,
forgroundColor,
),
],
),
),
],
);
}
}
Thanks to anyone who can help
I discovered the problem. The reason for the freezing of the UI wasn't an error in the widget tree, but because of a bad performance method that takes a long time.