DropdownButtonFormField assertion fails where DropdownButtonHideUnderline doesn't - flutter

This works with DropdownButtonHideUnderline, but does not work with DropdownButtonFormField. I want the inputDecoration that I get with DropdownButtonFormField, but this code fails at runtime when I change the project.
I either need to fix it to run with DropdownButtonFormField or I should find a way to get the inputDecoration added to the DropdownButtonHideUnderline;
At runtime the error that comes out is:
Either zero or 2 or more [DropdownMenuItem]s were detected with the same value
'package:flutter/src/material/dropdown.dart':
Failed assertion: line 827 pos 15: 'items == null || items.isEmpty || value == null ||
items.where((DropdownMenuItem<T> item) {
return item.value == value;
}).length == 1'
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
Map data = {
'Project 1': ['Entrance', 'Main Hallway', 'Kitchen'],
'Project 2': ['Patio', 'Dining Room'],
};
class _MyHomePageState extends State<MyHomePage> {
String _project;
String _room;
List<String> _roomList = [];
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
children: <Widget>[
DropdownButtonFormField(
decoration: InputDecoration(labelText: 'Project'),
value: _project,
onChanged: (value) {
setState(() {
_project = value;
_room = null;
_roomList = data[_project];
});
},
items: data.keys.map((item) {
return DropdownMenuItem(
child: Text(item),
value: item,
);
})?.toList() ??
[],
),
DropdownButtonFormField(
decoration: InputDecoration(labelText: 'Room'),
value: _room,
onChanged: (value) {
setState(() {
_room = value;
print(_project);
print(_room);
});
},
items: _roomList.map((item) {
return DropdownMenuItem(
child: Text(item),
value: item,
);
})?.toList() ??
[],
),
],
),
));
}
}

You can copy paste run full code below
When Dropdown list data is totally different will trigger this error
For Room DropdownButtonFormField You can use key: UniqueKey() and widget will recreate
code snippet
DropdownButtonFormField(
key: UniqueKey(),
decoration: InputDecoration(labelText: 'Room'),
working demo
full code
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
Map data = {
'Project 1': ['Entrance', 'Main Hallway', 'Kitchen'],
'Project 2': ['Patio', 'Dining Room'],
};
class _MyHomePageState extends State<MyHomePage> {
String _project;
String _room;
List<String> _roomList = [];
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
children: <Widget>[
DropdownButtonFormField(
decoration: InputDecoration(labelText: 'Project'),
value: _project,
onChanged: (value) {
setState(() {
_project = value;
_room = null;
_roomList = data[_project];
});
},
items: data.keys.map((item) {
return DropdownMenuItem(
child: Text(item),
value: item,
);
})?.toList() ??
[],
),
DropdownButtonFormField(
key: UniqueKey(),
decoration: InputDecoration(labelText: 'Room'),
value: _room,
onChanged: (value) {
setState(() {
_room = value;
print(_project);
print(_room);
});
},
items: _roomList.map((item) {
return DropdownMenuItem(
child: Text(item),
value: item,
);
})?.toList() ??
[],
),
],
),
));
}
}

Related

How to change value on DropdownButton in onChange in Flutter

I am a beginner in the flutter I'm just learning flutter and I am stuck in this code how to solve this please help me?
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget{
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'My Application',
home: book(),
);
}
}
class book extends StatefulWidget{
#override
State<StatefulWidget> createState() {
return _bookstate();
}
}
class _bookstate extends State<book>{
String namebook = "";
var writter = ['A','B','C'];
var _currentItemSelected = 'A';
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Stateful Widget'),
),
body: Container(
margin: EdgeInsets.all(20.0),
child: Column(
children:<Widget> [
TextField(
onChanged: (String userInput){
setState(() {
namebook=userInput;
});
},
),
DropdownButton<String>(
items: writter.map((String dropDownStringItem){
return DropdownMenuItem<String>(
value: dropDownStringItem,
child: Text(dropDownStringItem),
);
}).toList(),
onChanged: (String newValueSelected){
setState(() {
this._currentItemSelected = newValueSelected;
});
},
value: _currentItemSelected,
),
Text("Enter book name id $namebook",style: TextStyle(fontSize:20.0),),
],
),
),
);
}
}
and error show this message:
Error: The argument type 'void Function(String)' can't be assigned to the parameter type 'void Function(String?)?' because 'String?' is nullable and 'String' isn't.
You need to follow null safety rules, because your version supports null safety.
Simply change your code;
onChanged: (String? newValueSelected) {
setState(() {
this._currentItemSelected = newValueSelected!;
});
},
And I suggest check and learn what null safety is.
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const Book(),
);
}
}
class Book extends StatefulWidget {
const Book({Key? key}) : super(key: key);
#override
State<StatefulWidget> createState() {
return _Bookstate();
}
}
class _Bookstate extends State<Book> {
String namebook = "";
var writter = ['A', 'B', 'C'];
var _currentItemSelected = 'A';
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Stateful Widget'),
),
body: Container(
margin: const EdgeInsets.all(20.0),
child: Column(
children: <Widget>[
TextField(
onChanged: (String userInput) {
setState(() {
namebook = userInput;
});
},
),
DropdownButton<String>(
items: writter.map((String dropDownStringItem) {
return DropdownMenuItem<String>(
value: dropDownStringItem,
child: Text(dropDownStringItem),
);
}).toList(),
onChanged: (String? newValueSelected) {
setState(() {
_currentItemSelected = newValueSelected!;
});
},
value: _currentItemSelected,
),
Text(
"Enter book name id $namebook",
style: const TextStyle(fontSize: 20.0),
),
],
),
),
);
}
}

Why can't I display a list in rows in dropdown button in Flutter?

I want to show an icon and text as each item in a dropdown menu.
According to this answer https://stackoverflow.com/a/65831827/7870443 I tried. But my code is not working. I see an underline and dropdown button. But not clickable.
This is what I got.
I see an underline and dropdown button. But not clickable.
Below is the code I tried from that link
import 'package:flutter/material.dart';
import 'package:flutter_html/flutter_html.dart';
import 'package:flutter_html/html_parser.dart';
import 'package:flutter_html/style.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
String dropdownValue = 'Hillary';
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: DropdownButton<String>(
items: <String>['Hillary', 'Joe', 'Felix', 'Monica'].map((name) {
return DropdownMenuItem<String>(
value: name,
// Your row here:
child: Row(
children: [
Icon(Icons.person),
Text(name),
],
),
);
}).toList(),
onChanged: (selectedName) {
setState(() {
dropdownValue = selectedName;
});
},
),
)
);
}
}
just set value for DropdownButton like code below:
String dropdownValue = 'Hillary';
#override
Widget build(BuildContext context) {
SizeConfig().init(context);
return Scaffold(
appBar: AppBar(
title: Text('widget.title'),
),
body: Center(
child: DropdownButton<String>(
value: dropdownValue,
items: <String>['Hillary', 'Joe', 'Felix', 'Monica'].map((name) {
return DropdownMenuItem<String>(
value: name,
// Your row here:
child: Row(
children: [
Icon(Icons.person),
Text(name),
],
),
);
}).toList(),
onChanged: (selectedName) {
setState(() {
dropdownValue = selectedName;
});
},
),
));
}
for Change icon one way is using Map like code below:
String dropdownValue = 'Hillary';
Map<String, IconData> map = {
'Hillary': Icons.language,
'Joe': Icons.person,
'Felix': Icons.print,
'Monica': Icons.title
};
#override
Widget build(BuildContext context) {
SizeConfig().init(context);
return Scaffold(
appBar: AppBar(
title: Text('widget.title'),
),
body: Center(
child: DropdownButton<String>(
value: dropdownValue,
items: <String>['Hillary', 'Joe', 'Felix', 'Monica'].map((name) {
return DropdownMenuItem<String>(
value: name,
// Your row here:
child: Row(
children: [
Icon(map[name]),
Text(name),
],
),
);
}).toList(),
onChanged: (selectedName) {
setState(() {
dropdownValue = selectedName;
});
},
),
));
}

FormatException: Unexpected character (at character 1) in Flutterinsta Package

I am using FlutterInsta package. I am getting some information after entering username in textfield. But i am getting this kind of exception after some time.
This is the error :-
I/flutter ( 8708): FormatException: Unexpected character (at character 1)
I/flutter ( 8708):
I/flutter ( 8708): ^
Here is the code :-
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Instainfo'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
FlutterInsta flutterInsta = new FlutterInsta();
var text;
String url,followers,following,bio,username,website;
List<String> feed = [];
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body:ListView(
shrinkWrap: true,
children: [
TextField(
onChanged: (val) {
text = val;
},
decoration: InputDecoration(
suffixIcon: IconButton(
icon: Icon(Icons.send),
onPressed: () async {
try {
await flutterInsta.getProfileData(text);
setState(() {
followers = flutterInsta.followers;
following = flutterInsta.following;
});
} catch (e) {
print(e);
}
},
),
hintText: "Enter Username",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(20.0),
),
),
),
),
Column(
children: [
Text("Followers :- $followers"),
Text("Following :- $following")
],
),
),
],
),
),
);
}
}
Is there any limit to request this package ?

Flutter change Textstyle

I have a list and when I press the checkbox, I need the text to be stroken.
This is my method for checking the checkbox.
Any idea how I can implement the change of new textStyle here?
my method:
void toggleDone(TodoTask task, bool newValue) {
print("Status before processing");
task.status = newValue;
notifyListeners();
}
}
If u want to change sth depending on the state you can do it like that with tenary operator:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
bool change = false;
void _incrementCounter() {
setState(() {
_counter++;
change = !change;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
style: TextStyle(color: change ? Colors.red :Colors.black87),
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
In this example text color will change when u click the button. So you need to change this 'control variable' inside your function and widget will rebuild.
You can use TextDecoration.lineThrough property of TextStyle to put a line through or strike through text. There are several examples of how to use TextStyle in Flutter docs. The code shows how to change the TextStyle when Checkbox value is changed.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
bool _value = false;
//void toggleDone(TodoTask task, bool newValue) {
void toggleDone(bool newValue) {
print("Status before processing");
_value = newValue;
//task.status = newValue;
//notifyListeners();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Flutter Demo Home Page"),
),
body: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Checkbox(
value: _value,
onChanged: (val) => setState(() => toggleDone(val))),
Text('TextDecoration LineThrough Demo',
style: _value
? TextStyle(
decoration: TextDecoration.lineThrough, fontSize: 25)
: TextStyle(fontSize: 25)),
],
),
),
);
}
}

In Flutter check a checkbox -> disabled checkbox and text field should be enabled in checkbox check

I am new to Flutter.
If I click a check box action should be performed.
Eg: Click a checkbox, enable the other checkbox and enable a text field
disable or enable widget only for button click is available.
I don't know how to do it in flutter
The idea is to use ternary operator ( ? : ) this works same as if does. Most basic explanation about code below when the checkbox is triggered checkBox1 changes and widget rebuilds with checkBox1 equals true now so instead of empty Container currently we are building new CheckBox.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
bool checkBox1 = false;
bool checkBox2 = false;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Column(
children: [
CheckboxListTile(
title: Text("title text"),
value: checkBox1,
onChanged: (newValue) {
setState(() {
checkBox1 = newValue;
});
},
),
checkBox1
? CheckboxListTile(
title: Text("title text2"),
value: checkBox2,
onChanged: (newValue) {
setState(() {
checkBox2 = newValue;
});
},
)
: Container(),
],
),
);
}
}
final TextEditingController _controllerTE =
TextEditingController();
bool cbFlag = false;
TextField(
readOnly: !cbFlag,
controller: _controllerTE,
decoration: InputDecoration(
labelText: 'TE disabled till CB checked',
prefixIcon: Checkbox(
value: cbFlag,
onChanged: (bool? value) {
setState(() {
cbFlag = value!;
});
},
),
),
),