I have tried to build a dropdown button and a menu with it, where the value will be selected from the dropdown menu. The code is as below:
String valueChoose;
List listItem = ["A", "B", "C", "D", "E"];
DropdownButton(
hint: Text('Associate'),
dropdownColor: Colors.white,
icon: Icon(Icons.arrow_drop_down),
iconSize: 20.0,
style: TextStyle(
fontSize: 22.0,
color: Colors.black,
),
value: valueChoose,
onChanged: (newValue) {
setState(() {
valueChoose = newValue;
});
},
items: listItem.map((valueItem){
return DropdownMenuItem(
value: valueItem,
child: Text(valueItem),
);
}).toList(),
),
The error I'm facing is in the set state, where I've assigned newValue to the valueChoose.
A value of type 'Object?' can't be assigned to a variable of type 'String'.
Try changing the type of the variable, or casting the right-hand type to 'String'.
That is the error showing up for the newValue assinged in the set state. Please help regarding this, thanks in advance!
Below is the code, including the AlertDailog:
class HomeScreen extends StatefulWidget {
#override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
String ? valueChoose;
List listItem = [
"A", "B", "C", "D", "E"
];
void assignPopup(BuildContext context) {
var alertDialog = AlertDialog(
content:
Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Row(
children:[
Container(
child: Text(
'Action',
),
),
]
),
Row(
children:[
Container(
child: Card(
elevation: 5.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
child: TextField(
decoration: InputDecoration(
labelText: 'Please add any comments',
),
),
),
),
]
),
Row(
children:[
Container(
child: Text(
'Assign To',
),
),
]
),
Row(
children: [
Container(
child: Card(
elevation: 5.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
child: DropdownButton<String>(
hint: Text('Associate'),
dropdownColor: Colors.white,
icon: Icon(Icons.arrow_drop_down),
iconSize: 40.0,
style: TextStyle(
fontSize: 18.0,
color: Colors.black,
),
value: valueChoose,
onChanged: (newValue) {
setState(() {
valueChoose = newValue;
});
},
items: listItem.map<DropdownMenuItem<String>>((valueItem){
return DropdownMenuItem(
value: valueItem,
child: Text(valueItem),
);
}).toList(),
),
),
),
],
),
],
),
);
showDialog(
context: context,
builder: (BuildContext context) {
return alertDialog;
}
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
...
...
Container(
child: TextButton(
onPressed: (){
assignPopup(context);
},
child: Text(
'Assign',
),
),
),
);
}
}
From the data that you provided I have created a example where I have used the alertdialog and inside it there is a drop down
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: HomeScreen(),
);
}
}
class HomeScreen extends StatefulWidget {
#override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
String valueChoose;
List listItem = ["A", "B", "C", "D", "E"];
void assignPopup(BuildContext context) {
showDialog(
context: context,
builder: (BuildContext context) {
return StatefulBuilder(builder: (context, setState) {
return AlertDialog(
content: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Row(children: [
Container(
child: Text(
'Action',
),
),
]),
Row(children: [
Expanded(
child: Container(
child: Card(
elevation: 5.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
child: TextField(
decoration: InputDecoration(
labelText: 'Please add any comments',
),
),
),
),
),
]),
Row(children: [
Container(
child: Text(
'Assign To',
),
),
]),
Row(
children: [
Container(
child: Card(
elevation: 5.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
child: DropdownButton<String>(
hint: Text('Associate'),
dropdownColor: Colors.white,
icon: Icon(Icons.arrow_drop_down),
iconSize: 40.0,
style: TextStyle(
fontSize: 18.0,
color: Colors.black,
),
value: valueChoose,
onChanged: (newValue) {
setState(() {
valueChoose = newValue;
});
},
items: listItem
.map<DropdownMenuItem<String>>((valueItem) {
return DropdownMenuItem(
value: valueItem,
child: Text(valueItem),
);
}).toList(),
),
),
),
],
),
],
),
);
});
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: TextButton(
onPressed: () {
assignPopup(context);
},
child: Text(
'Assign',
),
),
),
),
);
}
}
So here in order to change dropdown value you have to use the StatefulBuilder which will change your dropdown value. you can check the above example and make changes as per your needs.
Please run the code to check the desired output.
Let me know if it works.
Specify the types of DropdownButton and that map
String? valueChoose;
List listItem = ["A", "B", "C", "D", "E"];
DropdownButton<String>(
hint: Text('Associate'),
dropdownColor: Colors.white,
icon: Icon(Icons.arrow_drop_down),
iconSize: 20.0,
style: TextStyle(
fontSize: 22.0,
color: Colors.black,
),
value: valueChoose,
onChanged: (newValue) {
setState(() {
valueChoose = newValue;
});
},
items: listItem.map<DropdownMenuItem<String>>((valueItem) {
return DropdownMenuItem(
value: valueItem,
child: Text(valueItem),
);
}).toList(),
)
Declare variables outside the build method.
String? valueChoose;
List listItem = ["A", "B", "C", "D", "E"];
Inside the build method add the Dropdown widget, So the complete state class code would look like this,
class _DropdownViewState extends State<DropdownView> {
String? valueChoose;
List listItem = ["A", "B", "C", "D", "E"];
#override
Widget build(BuildContext context) {
return DropdownButton<String>(
hint: Text('Associate'),
dropdownColor: Colors.white,
icon: Icon(Icons.arrow_drop_down),
iconSize: 20.0,
style: TextStyle(
fontSize: 22.0,
color: Colors.black,
),
value: valueChoose,
onChanged: (String? newValue) {
setState(() {
valueChoose = newValue;
});
},
items: listItem.map<DropdownMenuItem<String>>((valueItem){
return DropdownMenuItem(
value: valueItem,
child: Text(valueItem),
);
}).toList(),
);
}
Related
I am making a Flutter application and I am making a settings page where I want to allow the user to choose the language they want. I have already tried many things but each time I have the same problem: I can only change the language once.
Here is my "settings" view:
class SettingViewState extends State<StatefulWidget> {
String _selectedLanguage = 'French';
#override
Widget build(BuildContext context) {
print('SettingViewState - build');
return Scaffold(
drawer: NavDrawableWidget(), // Hamburger menu
body: Column(
children: <Widget>[
Center(
child: Text('\n${AppSettings.strings.settingTitle}\n',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold
),
),
),
Container(
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
side: BorderSide(color: Colors.black12, width: 2),
),
child: ListTile(
title: Text(AppSettings.strings.languageTitle),
leading: Icon(Icons.language),
trailing: Theme(
data: Theme.of(context).copyWith(
canvasColor: Colors.blue[50],
),
child: DropdownButton<String>(
value: _selectedLanguage,
items: [
DropdownMenuItem(
value: 'French',
child: Row(
children: <Widget>[
Image.asset(AppSettings.APP_FRENCH_FLAG,width: 30, height: 20,),
SizedBox(width: 10),
Text(AppSettings.strings.frenchTitle),
],
),
),
DropdownMenuItem(
value: 'English',
child: Row(
children: <Widget>[
Image.asset(AppSettings.APP_ENGLISH_FLAG,width: 30, height: 20,),
SizedBox(width: 10),
Text(AppSettings.strings.englishTitle),
],
),
),
],
onChanged: (String? newValue) {
setState(() {
_selectedLanguage = newValue ?? _selectedLanguage;
AppSettings.changeLanguage(_selectedLanguage);
});
},
),
),
),
),
),
],
),
);
}
}
And here is my method in my config file to change the language:
static void changeLanguage(String newLanguage)
{
APP_LANGUAGE = newLanguage;
}
Thanks in advance if you take the time to answer me and help me
Is Riverpod an option for your state management?
https://riverpod.dev/
I believe you can achieve what you want similar to the following:
state_providers.dart
import 'package:flutter_riverpod/flutter_riverpod.dart';
final selectedLanguageProvider = StateProvider<String>((ref) => 'English');
setting_view.dart
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:yourapp/providers/state_providers.dart';
class SettingViewState extends ConsumerWidget {
const SettingViewState({
super.key,
});
#override
Widget build(BuildContext context, WidgetRef ref) {
final selectedLanguage = ref.watch(selectedLanguageProvider);
return Column(
children: <Widget>[
Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
side: const BorderSide(color: Colors.black12, width: 2),
),
child: ListTile(
title: const Text('Language'),
leading: const Icon(Icons.language),
trailing: Theme(
data: Theme.of(context).copyWith(
canvasColor: Colors.blue[50],
),
child: DropdownButton<String>(
value: selectedLanguage,
items: const [
DropdownMenuItem(
value: 'French',
child: Text('French'),
),
DropdownMenuItem(
value: 'English',
child: Text('English'),
),
],
onChanged: (String? newValue) {
ref.read(selectedLanguageProvider.notifier).state = newValue!;
},
),
),
),
),
],
);
}
}
It would also simplify accessing the state across Widgets as opposed to using a static settings file which I imagine you are doing. For example you can access the language state directly in an app bar widget
common_app_bar.dart
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:yourapp/providers/state_providers.dart';
class CommonAppBar extends ConsumerWidget implements PreferredSizeWidget {
const CommonAppBar({
Key? key,
}) : super(key: key);
#override
Size get preferredSize => const Size.fromHeight(kToolbarHeight);
#override
Widget build(BuildContext context, WidgetRef ref) {
final selectedLanguage = ref.watch(selectedLanguageProvider);
return AppBar(
backgroundColor: Colors.grey,
elevation: 0,
title: Text(selectedLanguage == 'English' ? 'Hello' : 'Bonjour'),
);
}
}
Hello Folks I am playing with Buttons to customize the buttons but I didn't find a way to approach the expected design. basically, I wanted to customize the 1) Multiple checkBoxes with Grey color Background and Black color Check Mark 2) RangeSlider Inactive bar with Grey color 3) Radio Button with black Color and I Want to unselect all, I understand that in Radio Button user cant Unselect all the buttons but I Want to unselect all with or without Radio Buttons(any different way is also fine) 4) same as 3rd point but Square Box with Grey color Background and Black color Check Mark. I attached a screenshot of my code and Expected design and also pasted my code. Please guys Help me to approach Expected Design, Please feel free to do comments for any clarity. Thanks in Advance.
What I want My expected Design My Result UI
Main File
import 'package:filters2/filter_screen.dart';
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Dialog',
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Filters'),
),
body: Center(
child: FlatButton(
onPressed: (){
filterBottomSheet();
},
color: Colors.green,
padding: EdgeInsets.fromLTRB(15, 15, 15, 15),
child: Text('Filters',style: TextStyle(fontSize: 16,color: Colors.white),),
),
),
);
}
filterBottomSheet(){
showModalBottomSheet(
context: context,
isScrollControlled: true,
isDismissible: true,
builder: (BuildContext context){
return Filters();
}
);
}
}
Filters Class
import 'package:filters2/Fruit_model_class.dart';
import 'package:filters2/color_model_class.dart';
import 'package:filters2/mobile_model_class.dart';
import 'package:flutter/material.dart';
class Filters extends StatefulWidget {
#override
_FiltersState createState() => _FiltersState();
}
class _FiltersState extends State<Filters> {
/*--------MobileList-multiple checklist-------*/
List<MobileList> availableMobiles = [
MobileList(id: 0, companyName: "Google", model: "Pixel 6 Pro"),
MobileList(id: 1, companyName: "Apple", model: "Iphone Xr"),
MobileList(id: 2, companyName: "Xiaomi", model: "Redmi note 10"),
];
List<MobileList> selectedMobiles = [];
/*------Price Range Selection-RangeSlider--------*/
RangeValues _currentRangeValues = const RangeValues(40000, 80000);
int minPrice = 20000;
int maxPrice = 90000;
/*Radio--fruits*/
String radioItem1 = 'Mango';
int fruitGroupId = 0;
List<FruitsList> fList = [
FruitsList(id: 0, name: "Mango",),
FruitsList(id: 1, name: "Apple",),
FruitsList(id: 2, name: "Banana",),
FruitsList(id: 3, name: "Cherry",),
];
/*Radio--Colors*/
String radioItem2 = 'Red';
int? colorGroupId ;
List<ColorsList> cList = [
ColorsList(id: 0, name: "Blue",),
ColorsList(id: 1, name: "Red",),
ColorsList(id: 2, name: "Green",),
ColorsList(id: 3, name: "Yellow",),
];
#override
Widget build(BuildContext context) {
return Container(
height: MediaQuery.of(context).size.height * 0.85,
decoration: BoxDecoration(
//olor: Colors.red,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10),
topRight: Radius.circular(10),
)
),
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: 10,),
Container(
child: Text("Filter",style: TextStyle(color: Colors.black, fontSize: 24,fontWeight: FontWeight.bold),),
),
SizedBox(height: 10,),
Container(
child: Text("Select Mobiles (multiple selection)",style: TextStyle(color: Colors.black, fontSize: 20,fontWeight: FontWeight.bold),),
),
SizedBox(height: 10,),
Divider(),
Container(
child: Row(
children: [
Expanded(
flex:1,
child: ListView.builder(
shrinkWrap: true,
itemCount: availableMobiles.length,
itemBuilder: (context, playerIndex){
return CheckboxListTile(
controlAffinity: ListTileControlAffinity.trailing,
contentPadding: EdgeInsets.zero,
title:Text(availableMobiles[playerIndex].companyName),
value: selectedMobiles.contains(availableMobiles[playerIndex]),
onChanged: (value) {
if(selectedMobiles.contains(availableMobiles[playerIndex])){
selectedMobiles.remove(availableMobiles[playerIndex]);
}
else {
selectedMobiles.add(availableMobiles[playerIndex]);
}
setState(() {
});
}
);
}
),
),
Expanded(
flex: 2,
child:Container(
color: Colors.white ,
) ),
],
),
),
SizedBox(height: 10,),
Divider(),
Container(
child: Text("Year",style: TextStyle(color: Colors.black, fontSize: 20,fontWeight: FontWeight.bold),),
),
SizedBox(height: 10,),
Divider(),
Container(
child: Row(
//mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Align(
alignment: Alignment.centerLeft,
child: Text("20000",style: TextStyle(color: Colors.black, fontSize: 20)),
),
Expanded(
child: RangeSlider(
values: _currentRangeValues,
min: minPrice.toDouble(),
max: maxPrice.toDouble(),
divisions: maxPrice - minPrice,
activeColor: Colors.black,
labels: RangeLabels(
_currentRangeValues.start.round().toString(),
_currentRangeValues.end.round().toString(),
),
onChanged: (RangeValues values) {
setState(() {
_currentRangeValues = values;
});
},
),
),
Align(
alignment: Alignment.centerRight,
child: Text("90000",style: TextStyle(color: Colors.black, fontSize: 20))),
],
),
),
SizedBox(height: 10,),
Divider(),
Container(
child: Row(
children: [
Expanded(
flex: 1,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("Fruits (Single selection)",style: TextStyle(color: Colors.black, fontSize: 20,fontWeight: FontWeight.bold),),
Column(
children:
fList.map((data) => RadioListTile(
controlAffinity: ListTileControlAffinity.trailing,
contentPadding: EdgeInsets.zero,
title: Text("${data.name}"),
groupValue: fruitGroupId,
value: data.id,
onChanged: (val){
setState(() {
radioItem1 = data.name;
fruitGroupId = data.id;
});
},
)).toList(),
),
],
),
),
Expanded(
flex:2,
child: Container(
//width: 5,
color: Colors.white,
)),
],
),
),
Container(
child: Row(
children: [
Expanded(
flex: 1,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("Colors",style: TextStyle(color: Colors.black, fontSize: 20,fontWeight: FontWeight.bold),),
Column(
children:
cList.map((colorData) => RadioListTile(
controlAffinity: ListTileControlAffinity.trailing,
contentPadding: EdgeInsets.zero,
title: Text("${colorData.name}"),
groupValue: colorGroupId,
value: colorData.id,
onChanged: (val){
setState(() {
radioItem2 = colorData.name;
colorGroupId = colorData.id;
});
},
)).toList(),
),
],
),
),
Expanded(
flex: 2,
child:Container(
color: Colors.white ,
) ),
],
),
),
],
),
),
);
}
}
mobile_model_class
class MobileList {
int id;
String companyName;
String model;
MobileList({required this.id, required this.companyName, required this.model});
}
Fruit_model_class
class MobileList {
int id;
String companyName;
String model;
MobileList({required this.id, required this.companyName, required this.model});
}
color_model_class
class ColorsList {
String name;
int id;
ColorsList({required this.name,required this.id});
}
To change color of checkbox you can use
Checkbox(
value: isCheck,
checkColor: Colors.black, // change color here
activeColor: Colors.grey,
onChanged: (bool value) {
setState(() {
isCheck = value;
});
}),
To change color of radio button try
Theme(
data: ThemeData(
//Change color here
unselectedWidgetColor: Colors.grey,
),
child: Row(
children: <Widget>[
Radio(),
Radio()
],
),
);
You can use SliderTheme class to customize your slider color and shape.
SliderTheme(
data: SliderThemeData(
this.trackHeight,
activeTrackColor:Colors.grey,
inactiveTrackColor:Colors.black,
thumbColor: Colors.green,
thumbShape: RoundSliderThumbShape(enabledThumbRadius: 20)),
child: Slider(
value: _value,
onChanged: (val) {
_value = val;
setState(() {});
},
),
),
Hope the answer is helpful to you.
I am making a shopping cart app in flutter with Change Notifier Provider. It is working fast and well at first. But it takes the more memory, the more I use it. I am adding and removing clearing items from list. Nothing complicated. Cannot know why it is working like this. It is slowing down gradually. This is main.dart:
class Main extends StatelessWidget {
#override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (context) => Cart(),
child: MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: swatchColor,
primaryColor: primaryColor,
accentColor: tertiaryColor,
textSelectionTheme: TextSelectionThemeData(
cursorColor: Colors.black,
selectionColor: primaryColor,
selectionHandleColor: primaryColor,
),
),
initialRoute: '/login',
routes: {
'/home': (context) => Home(),
'/login': (context) => Login(),
'/tableReview': (context) => TableReview(),
'/createOrder': (context) => CreateOrder(),
'/orderReview': (context) => OrderReview(),
},
),
);
}
}
This is main cart_model.dart
import 'package:counter/data/models/cart_item.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
class Cart extends ChangeNotifier {
List<Item> cart = [];
addItemToCart({#required item}) {
Item newItem = Item(
id: item.id,
price: item.price is int ? item.price : int.parse(item.price),
title: item.title,
);
int i = cart.indexWhere((previousItem) => previousItem.id == newItem.id);
if (i > -1) {
cart[i].count++;
} else {
cart.add(newItem);
}
notifyListeners();
}
removeItemFromCart({#required item}) {
int index = cart.indexWhere((element) => element.id == item.id);
if (index > -1) {
if (cart[index].count > 1) {
cart[index].count--;
} else {
cart.removeWhere((element) => element.id == item.id);
}
}
notifyListeners();
}
clearCart() {
cart.clear();
notifyListeners();
}
int get totalPrice =>
cart.fold(0, (total, current) => total + (current.price * current.count));
}
This is menuitem.dart
class MenuItem extends StatelessWidget {
final dynamic foodItem;
MenuItem({#required this.foodItem});
void _showSecondPage(BuildContext context) {
Navigator.of(context).push(
MaterialPageRoute(
builder: (ctx) => Scaffold(
backgroundColor: Colors.black45,
body: Center(
child: Hero(
tag: foodItem.imgPath,
child: Image(image: NetworkImage(base_url + foodItem.imgPath)),
),
),
),
),
);
}
#override
Widget build(BuildContext context) {
int itemIndex = Provider.of<Cart>(context, listen: false)
.cart
.indexWhere((item) => item.id == foodItem.id);
return Container(
height: 80,
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
GestureDetector(
onTap: () => _showSecondPage(context),
child: Hero(
tag: foodItem.imgPath,
child: CircleAvatar(
backgroundImage: NetworkImage(base_url + foodItem.imgPath),
),
),
),
SizedBox(
width: 15,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text(
foodItem.title,
style: TextStyle(
fontWeight: FontWeight.w700,
fontSize: 17,
),
),
Text('${foodItem.price.toString()} сум'),
],
)
],
),
Container(
width: 160,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
IconButton(
icon:
Icon(Icons.remove, color: Theme.of(context).primaryColor),
onPressed: () {
Provider.of<Cart>(context, listen: false)
.addItemToCart(item: foodItem);
},
),
Text(
itemIndex > -1
? '${Provider.of<Cart>(context).cart[itemIndex].count}'
: '0',
style: TextStyle(fontSize: 18),
),
IconButton(
icon: Icon(Icons.add, color: Theme.of(context).primaryColor),
onPressed: () {
Provider.of<Cart>(context, listen: false)
.addItemToCart(item: foodItem);
},
),
],
),
),
],
),
);
}
}
This is consumer part:
import 'package:counter/common/socketio.dart';
import 'package:counter/data/models/cart_model.dart';
import 'package:counter/presentation/widgets/empty_cart.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
class OrderReview extends StatefulWidget {
#override
_OrderReviewState createState() => _OrderReviewState();
}
class _OrderReviewState extends State<OrderReview> {
bool isCommentEnabled = false;
String guestCount;
String comment = '';
final _formKey = GlobalKey<FormState>();
#override
Widget build(BuildContext context) {
final myCart = context.watch<Cart>();
return Scaffold(
resizeToAvoidBottomInset: true,
appBar: AppBar(
title: Text('Проверка заказа'),
),
body: Builder(
builder: (context) {
if (myCart.cart.length > 0) {
handleOrderCreate() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
String userId = prefs.getString('userId');
String tableNum = prefs.getString('tableNum');
String status = 'accepted';
print('$userId, $tableNum, $status');
Map orderToCreate = {
'tableNum': tableNum,
'status': 'accepted',
'userId': userId,
'guestCount': guestCount,
'comment': comment,
'foodList': myCart.cart
};
socketIO.emit('createOrder', json.encode(orderToCreate));
Navigator.of(context).pushNamed('/home');
Provider.of<Cart>(context, listen: false).clearCart();
}
return GestureDetector(
onTap: () => FocusScope.of(context).requestFocus(new FocusNode()),
child: LayoutBuilder(
builder:
(BuildContext context, BoxConstraints viewportConstraints) {
return SingleChildScrollView(
child: ConstrainedBox(
constraints: BoxConstraints(
minHeight: viewportConstraints.maxHeight,
),
child: IntrinsicHeight(
child: Container(
padding: const EdgeInsets.symmetric(
horizontal: 8.0, vertical: 8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Form(
key: _formKey,
child: Column(
children: [
Container(
height: 350,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10),
topRight: Radius.circular(10),
bottomLeft: Radius.circular(10),
bottomRight: Radius.circular(10)),
boxShadow: [
BoxShadow(
color:
Colors.grey.withOpacity(0.5),
spreadRadius: 5,
blurRadius: 7,
offset: Offset(0,
3), // changes position of shadow
),
]),
child: ListView.separated(
itemBuilder:
(BuildContext context, int i) {
return ListTile(
title: Text(myCart.cart[i].title),
trailing: Container(
width: 160,
child: Row(
crossAxisAlignment:
CrossAxisAlignment.center,
mainAxisAlignment:
MainAxisAlignment
.spaceBetween,
children: <Widget>[
IconButton(
icon: Icon(
Icons.remove,
color: Theme.of(context)
.primaryColor,
),
onPressed: () {
Provider.of<Cart>(context,
listen: false)
.removeItemFromCart(
item: myCart
.cart[i]);
},
),
Text(
'${myCart.cart[i].count}',
style:
TextStyle(fontSize: 18),
),
IconButton(
icon: Icon(
Icons.add,
color: Theme.of(context)
.primaryColor,
),
onPressed: () {
Provider.of<Cart>(context,
listen: false)
.addItemToCart(
item: myCart
.cart[i]);
},
),
],
),
),
);
},
separatorBuilder:
(BuildContext context, int) {
return Divider(
height: 2,
color: Colors.grey,
);
},
itemCount: myCart.cart.length,
),
),
SizedBox(height: 20),
Container(
child: TextFormField(
keyboardType: TextInputType.number,
decoration: InputDecoration(
border: OutlineInputBorder(),
hintText: 'Количество гостей',
),
onChanged: (newValue) {
setState(() => guestCount = newValue);
},
validator: (value) {
if (value == null || value.isEmpty) {
return 'Пожалуйста, введите количество гостей!';
}
return null;
},
),
),
SizedBox(height: 20),
Container(
child: TextFormField(
onChanged: (newValue) {
setState(() => comment = newValue);
},
enabled: isCommentEnabled,
decoration: InputDecoration(
border: OutlineInputBorder(),
hintText:
'Лаваш острый, хот дог без майонеза и т.д.',
// labelText: 'Комментарий',
),
maxLines: 2,
),
),
Row(
children: [
Text('Комментарий'),
Switch(
value: isCommentEnabled,
onChanged: (bool value) {
setState(() =>
this.isCommentEnabled = value);
},
),
],
)
],
),
),
SizedBox(height: 20),
Row(
children: [
Text(
'Общая цена: ',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.w500,
),
),
SizedBox(width: 20),
Text(
'${myCart.totalPrice} сум',
style: TextStyle(fontSize: 18),
),
],
),
Container(
height: 50,
width: 170,
child: ElevatedButton(
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.resolveWith(
(states) =>
Theme.of(context).primaryColor),
),
onPressed: () {
if (_formKey.currentState.validate()) {
handleOrderCreate();
}
},
child: Text(
'Отправить',
style: TextStyle(
color: Colors.white, fontSize: 18),
),
),
),
],
),
),
),
),
);
},
),
);
} else {
print('111');
return EmptyCart();
}
},
),
);
}
}
Is there something wrong with my code?
I have multiple line items in the dropdown menu in flutter like this :
It is shown perfectly fine in the dropdown pop up but in dropdown button it shows bottomoverflow like this :
Here is code for the same :
DropdownButtonHideUnderline(
child: DropdownButton(
items: addresses.map((String value) {
return new DropdownMenuItem<String>(
value: value,
child: SizedBox(
height: 10 * SizeConfig.heightMultiplier,
child: Column(
children: [
SizedBox(height: 1.5 * SizeConfig.heightMultiplier),
new Text(value, overflow: TextOverflow.clip),
SizedBox(height: 1.5 * SizeConfig.heightMultiplier),
],
),
),
);
}).toList(),
onChanged: (String newValue) {
setState(() {
_selectedShippingAddress = newValue;
});
},
hint: Text("Select address"),
selectedItemBuilder: (BuildContext context) {
return addresses.map<Widget>((String item) {
return Container(
child: Text(item),
);
}).toList();
},
style: TextStyle(
fontSize: 1.9 *
SizeConfig.textMultiplier,
color:
Theme.of(context).accentColor,
fontFamily: 'Montserrat'),
value: _selectedShippingAddress,
isExpanded: true,
underline: Container(
height: 1,
color: Theme.of(context)
.textSelectionColor,
),
icon: Icon(Icons.arrow_drop_down),
isDense: true,
),
)
So what is a solution for this? Can anyone help on this?
From the example that you provided I replicated it and there is a problem in the blow code
DropdownMenuItem<String>(
value: value,
child: SizedBox(
height: 10 * SizeConfig.heightMultiplier,
Maybe the height is doing some problem just added a sample example below to let you know the things work.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: SampleApp(),
debugShowCheckedModeBanner: false,
);
}
}
class SampleApp extends StatefulWidget {
#override
_SampleAppState createState() => _SampleAppState();
}
class _SampleAppState extends State<SampleApp> {
String _selectedShippingAddress;
List addresses = ['sample1', 'sample 2'];
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Your heading'),
),
body: DropdownButtonHideUnderline(
child: DropdownButton<String>(
items: addresses.map((value) {
return new DropdownMenuItem<String>(
value: value,
child: SizedBox(
child: Column(
children: [
SizedBox(height: 5),
new Text(value, overflow: TextOverflow.clip),
SizedBox(height: 5),
],
),
),
);
}).toList(),
onChanged: (String newValue) {
setState(() {
_selectedShippingAddress = newValue;
});
},
hint: Text("Select address"),
selectedItemBuilder: (BuildContext context) {
return addresses.map<Widget>((item) {
return Container(
child: Text(item),
);
}).toList();
},
style: TextStyle(
fontSize: 14,
color: Theme.of(context).accentColor,
fontFamily: 'Montserrat'),
value: _selectedShippingAddress,
isExpanded: true,
underline: Container(
height: 1,
color: Theme.of(context).textSelectionColor,
),
icon: Icon(Icons.arrow_drop_down),
isDense: true,
),
));
}
}
I am new to flutter and this is my first application. I have been trying to create a form modal with dropdown select would receive its data from the server. but for now I am using the values in array I created but it not setting the value after I select an item. I tried to add a setState() but is showing error. Please can someone help me?
Here is my code blow
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:erg_app/ProfilePage.dart';
void main() => runApp(
MaterialApp(
debugShowCheckedModeBanner: false,
home: StockPage(),
)
);
class StockPage extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Inventory Data',
theme: ThemeData(
primarySwatch: Colors.green,
),
home: StockInventory(),
);
}
}
class StockInventory extends StatefulWidget {
StockInventory({Key key}) : super(key: key); //Find out meaning
#override
_StockInventoryState createState() => _StockInventoryState();
}
class _StockInventoryState extends State<StockInventory> {
List<Products> products;
List<Products> selectedProducts;
bool sort;
#override
void initState() {
sort = false;
selectedProducts = [];
products = Products.getProducts();
super.initState();
}
onSortColum(int columnIndex, bool ascending) {
if (columnIndex == 0) {
if (ascending) {
products.sort((a, b) => a.name.compareTo(b.name));
} else {
products.sort((a, b) => b.name.compareTo(a.name));
}
}
}
#override
Widget build(BuildContext context){
return Scaffold(
appBar: AppBar(
title: new Center(child: new Text('Daily Stock Taking', textAlign: TextAlign.center)),
automaticallyImplyLeading: false,
iconTheme: IconThemeData(color: Colors.white),
backgroundColor: Colors.green,),
body: Container(
child: ListView(
children: <Widget>[
Container(
margin: const EdgeInsets.only(right: 20, top: 20),
child: Align(
alignment: Alignment.bottomRight,
child: RaisedButton(
padding: EdgeInsets.fromLTRB(14, 10, 14, 10),
color: Colors.green,
child: Text("Take Inventory", style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: 14), ),
onPressed: () {
// Navigator.of(context).push(MaterialPageRoute(builder: (context) => ProfilePage()));
showSimpleCustomDialog(context);
},
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(50),
),
),
),
),
Container(
padding: EdgeInsets.only(top: 30, bottom: 30),
child: DataTable(
sortAscending: sort,
sortColumnIndex: 0,
columns: [
DataColumn(
label: Text("S/No", style: TextStyle(fontSize: 16)),
numeric: false,
),
DataColumn(
label: Text("Item", style: TextStyle(fontSize: 16)),
numeric: false,
onSort: (columnIndex, ascending) {
setState(() {
sort = !sort;
});
onSortColum(columnIndex, ascending);
}),
DataColumn(
label: Text("QtyInStock", style: TextStyle(fontSize: 16)),
numeric: false,
),
DataColumn(
label: Text("Unit", style: TextStyle(fontSize: 16)),
numeric: false,
),
],
rows: products
.map(
(product) => DataRow(
selected: selectedProducts.contains(product),
cells: [
DataCell(
Text(product.count),
onTap: () {
print('Selected ${product.count}');
},
),
DataCell(
Text(product.name),
onTap: () {
print('Selected ${product.name}');
},
),
DataCell(
Text(product.itemqty),
onTap: () {
print('Selected ${product.itemqty}');
},
),
DataCell(
Text(product.itemqty),
onTap: () {
print('Selected ${product.itemqty}');
},
),
]),
).toList(),
),
),
Container(
child: Center(
child: RaisedButton(
padding: EdgeInsets.fromLTRB(80, 10, 80, 10),
color: Colors.green,
child: Text("Post Inventory", style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: 14), ),
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(builder: (context) => ProfilePage()));
},
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(50),
),
),
),
),
],
),
),
);
}
}
class Products {
String count;
String name;
String measuringunit;
String itemqty;
Products({this.count, this.name, this.itemqty, this.measuringunit});
static List<Products> getProducts() {
return <Products>[
Products(count:"1", name: "NPK Fertilizer", itemqty: "50", measuringunit: "bag",),
Products(count:"2", name: "Urea Fertilizer", itemqty: "560", measuringunit: "bag",),
Products(count:"3", name: "Spray", itemqty: "150", measuringunit: "bottles",),
];
}
}
void showSimpleCustomDialog(BuildContext context) {
String dropdownValue = 'SelectItem';
// TextEditingController _controller = TextEditingController(text: dropdownValue);
Dialog simpleDialog = Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12.0),
),
child: Container(
height: 300.0,
width: 300.0,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: EdgeInsets.only(top:20, bottom: 20, left: 30, right: 10),
child: Row(
children: <Widget>[
Expanded(child:
Text(
'Item',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold, ),
),
),
Container(width: 2,),
Container(
child:DropdownButton<String>(
value: dropdownValue,
onChanged: (String newValue) {
// This set state is trowing an error
setState((){
dropdownValue = newValue;
});
},
items: <String>['Fertilizers', 'Bags', 'Spray', 'Equipments']
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: new Text(value),
);
})
.toList(),
),
),
],
)),
Padding(
padding: EdgeInsets.only(top:5, bottom: 5, left: 30, right: 10),
child: Row(
children: <Widget>[
Expanded(child:
Text(
'Quantity',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold, ),
),
),
Container(width: 2,),
Expanded(child: TextField(
keyboardType: TextInputType.number,
decoration: InputDecoration(
labelText: 'Quantity',
hintText: 'Enter Cost Quantity',
border:OutlineInputBorder(borderRadius: BorderRadius.circular(5.0))
),
)),
],
)),
Padding(
padding: const EdgeInsets.only(left: 10, right: 10, top: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
RaisedButton(
color: Colors.blue,
onPressed: () {
Navigator.of(context).pop();
},
child: Text(
'Add',
style: TextStyle(fontSize: 18.0, color: Colors.white),
),
),
SizedBox(
width: 20,
),
RaisedButton(
color: Colors.red,
onPressed: () {
Navigator.pop(context);
// Navigator.of(context).push(MaterialPageRoute(builder: (context) => StockPage()));
},
child: Text(
'Cancel!',
style: TextStyle(fontSize: 18.0, color: Colors.white),
),
)
],
),
),
],
),
),
);
showDialog(context: context, builder: (BuildContext context) => simpleDialog);
}
// Dropdown Menu Class below
Maybe I think that using the Statefulbuilder for the dialog. So you can change the state there just check the sample example.
Change as per you needs :
import 'package:flutter/material.dart';
void main() => runApp(MaterialApp(
debugShowCheckedModeBanner: false,
home: StockPage(),
));
class StockPage extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Inventory Data',
theme: ThemeData(
primarySwatch: Colors.green,
),
home: StockInventory(),
);
}
}
class StockInventory extends StatefulWidget {
StockInventory({Key key}) : super(key: key); //Find out meaning
#override
_StockInventoryState createState() => _StockInventoryState();
}
class _StockInventoryState extends State<StockInventory> {
List<Products> products;
List<Products> selectedProducts;
bool sort;
#override
void initState() {
super.initState();
sort = false;
selectedProducts = [];
products = Products.getProducts();
}
onSortColum(int columnIndex, bool ascending) {
if (columnIndex == 0) {
if (ascending) {
products.sort((a, b) => a.name.compareTo(b.name));
} else {
products.sort((a, b) => b.name.compareTo(a.name));
}
}
}
void showSimpleCustomDialog(BuildContext context) {
String dropdownValue ;
// TextEditingController _controller = TextEditingController(text: dropdownValue);
AlertDialog simpleDialog1 = AlertDialog(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(10.0))),
content: StatefulBuilder(
builder :(BuildContext context, StateSetter setState) {
return Container(
height: 300.0,
width: 300.0,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding:
EdgeInsets.only(top: 20, bottom: 20, left: 30, right: 10),
child: Row(
children: <Widget>[
Expanded(
child: Text(
'Item',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
Container(
width: 2,
),
Container(
child: DropdownButton<String>(
hint: Text('Enter value'),
value: dropdownValue,
onChanged: (String newValue) {
// This set state is trowing an error
setState(() {
dropdownValue = newValue;
});
},
items: <String>[
'Fertilizers',
'Bags',
'Spray',
'Equipments'
].map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: new Text(value),
);
}).toList(),
),
),
],
)),
Padding(
padding:
EdgeInsets.only(top: 5, bottom: 5, left: 30, right: 10),
child: Row(
children: <Widget>[
Expanded(
child: Text(
'Quantity',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
Container(
width: 2,
),
Expanded(
child: TextField(
keyboardType: TextInputType.number,
decoration: InputDecoration(
labelText: 'Quantity',
hintText: 'Enter Cost Quantity',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(5.0))),
)),
],
)),
Padding(
padding: const EdgeInsets.only(left: 10, right: 10, top: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
RaisedButton(
color: Colors.blue,
onPressed: () {
Navigator.of(context).pop();
},
child: Text(
'Add',
style: TextStyle(fontSize: 18.0, color: Colors.white),
),
),
SizedBox(
width: 20,
),
RaisedButton(
color: Colors.red,
onPressed: () {
Navigator.pop(context);
// Navigator.of(context).push(MaterialPageRoute(builder: (context) => StockPage()));
},
child: Text(
'Cancel!',
style: TextStyle(fontSize: 18.0, color: Colors.white),
),
)
],
),
),
],
),
);
}
),
);
/* Dialog simpleDialog = Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12.0),
),
child:
); */
showDialog(
context: context, builder: (BuildContext context) => simpleDialog1);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: new Center(
child: new Text('Daily Stock Taking', textAlign: TextAlign.center)),
automaticallyImplyLeading: false,
iconTheme: IconThemeData(color: Colors.white),
backgroundColor: Colors.green,
),
body: Container(
child: ListView(
children: <Widget>[
Container(
margin: const EdgeInsets.only(right: 20, top: 20),
child: Align(
alignment: Alignment.bottomRight,
child: RaisedButton(
padding: EdgeInsets.fromLTRB(14, 10, 14, 10),
color: Colors.green,
child: Text(
"Take Inventory",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 14),
),
onPressed: () {
// Navigator.of(context).push(MaterialPageRoute(builder: (context) => ProfilePage()));
showSimpleCustomDialog(context);
},
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(50),
),
),
),
),
Container(
padding: EdgeInsets.only(top: 30, bottom: 30),
child: DataTable(
sortAscending: sort,
sortColumnIndex: 0,
columns: [
DataColumn(
label: Text("S/No", style: TextStyle(fontSize: 16)),
numeric: false,
),
DataColumn(
label: Text("Item", style: TextStyle(fontSize: 16)),
numeric: false,
onSort: (columnIndex, ascending) {
setState(() {
sort = !sort;
});
onSortColum(columnIndex, ascending);
}),
DataColumn(
label: Text("QtyInStock", style: TextStyle(fontSize: 16)),
numeric: false,
),
DataColumn(
label: Text("Unit", style: TextStyle(fontSize: 16)),
numeric: false,
),
],
rows: products
.map(
(product) => DataRow(
selected: selectedProducts.contains(product),
cells: [
DataCell(
Text(product.count),
onTap: () {
print('Selected ${product.count}');
},
),
DataCell(
Text(product.name),
onTap: () {
print('Selected ${product.name}');
},
),
DataCell(
Text(product.itemqty),
onTap: () {
print('Selected ${product.itemqty}');
},
),
DataCell(
Text(product.itemqty),
onTap: () {
print('Selected ${product.itemqty}');
},
),
]),
)
.toList(),
),
),
Container(
child: Center(
child: RaisedButton(
padding: EdgeInsets.fromLTRB(80, 10, 80, 10),
color: Colors.green,
child: Text(
"Post Inventory",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 14),
),
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => ProfilePage()));
},
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(50),
),
),
),
),
],
),
),
);
}
}
class Products {
String count;
String name;
String measuringunit;
String itemqty;
Products({this.count, this.name, this.itemqty, this.measuringunit});
static List<Products> getProducts() {
return <Products>[
Products(
count: "1",
name: "NPK Fertilizer",
itemqty: "50",
measuringunit: "bag",
),
Products(
count: "2",
name: "Urea Fertilizer",
itemqty: "560",
measuringunit: "bag",
),
Products(
count: "3",
name: "Spray",
itemqty: "150",
measuringunit: "bottles",
),
];
}
}
class ProfilePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Container();
}
}
Just check the code.
Let me know if it works