Flutter: DropdownButton's incorrect popup position - flutter

My dropdown button's popup position is incorrect. I don't get what's causing this issue, popup moves in the right side of the button, its somewhat related to the Row widget and builder. I am on the master branch. Check the sample code here
DartPad Sample
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,
),
builder: (context, child) => Scaffold(
body: Row(
children: [
Container(
width: 200,
color: Colors.blue,
child: Column(children: [
Text("Side Menu"),
])
),
Expanded(child: child),
],
),
),
initialRoute: "/",
onGenerateRoute: (_) => MaterialPageRoute(
builder: (BuildContext context) => Center(
child: DropdownButton(
hint: Text("test"),
value: 0,
items: [
DropdownMenuItem(child: Text("test 1"), value: 0),
DropdownMenuItem(child: Text("test 2"), value: 1),
DropdownMenuItem(child: Text("test 3"), value: 2),
],
onChanged: (value) {},
),
),
),
);
}
}

Try implementing this code, it will definitely work Good luck :)
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
/// This Widget is the main application widget.
class MyApp extends StatelessWidget {
static const String _title = 'Flutter Code Sample';
#override
Widget build(BuildContext context) {
return MaterialApp(
title: _title,
home: Scaffold(
appBar: AppBar(title: const Text(_title)),
body: Center(
child: MyStatefulWidget(),
),
),
);
}
}
class MyStatefulWidget extends StatefulWidget {
MyStatefulWidget({Key key}) : super(key: key);
#override
_MyStatefulWidgetState createState() => _MyStatefulWidgetState();
}
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
String dropdownValue = 'One';
#override
Widget build(BuildContext context) {
return DropdownButton<String>(
value: dropdownValue,
icon: Icon(Icons.arrow_downward),
iconSize: 24,
elevation: 16,
style: TextStyle(color: Colors.deepPurple),
underline: Container(
height: 2,
color: Colors.deepPurpleAccent,
),
onChanged: (String newValue) {
setState(() {
dropdownValue = newValue;
});
},
items: <String>['One', 'Two', 'three', 'Four']
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
);
}
}

Related

Flutter: Dismissible in PopupMenuButton does not risize while displayed

I want to use a Dismissible Widget in a PopupMenuButton to delete items in the popup list.
My example code (see the example main() code below) works for deleting an item (String) in the PopupMenuButton, but the list is not refreshed and resized letting a blank space in the list while the popup is still displayed.
The list is only displayed resized after the popup is closed and then reopened.
I remove the item from the list in a setState in the onDismissed callback so the widget tree should be rebuild.
How can I update and resize the displayed list in the popup without having to close and reopen it?
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter PopupMenuButton sample',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
String dropdownValue = 'Orange';
final _items = [
'Orange',
'Banana',
'Grapes',
'Apple',
'watermelon',
'Pineapple'
];
#override
Widget build(BuildContext context) {
print("build Scaffold");
return Scaffold(
appBar: AppBar(
title: Text("DropDownList Example"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text("$dropdownValue"),
const Spacer(),
PopupMenuButton<String>(
icon: Icon(Icons.bookmarks_outlined),
onSelected: (String value) {
setState(() {
dropdownValue = value;
});
print(value);
},
itemBuilder: (BuildContext context) {
return _items.map<PopupMenuItem<String>>((String _value) {
return PopupMenuItem(
value: _value,
child: Dismissible(
key: UniqueKey(),
direction: DismissDirection.endToStart,
onDismissed: (i) {
print("onDismissed $_value");
setState(() {
_items.remove(_value);
});
},
child: ListTile(
title: Text(_value),
trailing: const Icon(Icons.arrow_back),
),
background: Container(
color: Colors.red,
margin: const EdgeInsets.symmetric(horizontal: 15),
alignment: Alignment.centerRight,
child: const Icon(
Icons.delete,
color: Colors.white,
),
),
),
);
}).toList();
},
),
const Spacer(
flex: 10,
),
],
),
),
);
}
}

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;
});
},
),
));
}

How to force show text selection controls?

I need to show text selection controls on:
setState( () {
textController.selection = TextSelection(baseOffset: 0, extentOffset: textController.text.length);
});
But it did not appear on the screen. So, how to force flutter show the cut/copy/paste menu?
I hope it helps you.
You can use Selectable Widget.
https://www.youtube.com/watch?v=ZSU3ZXOs6hc&list=PLjxrf2q8roU23XGwz3Km7sQZFTdB996iG&index=56
Second suggestion
When I test with below code, it works well.
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: "App",
theme: new ThemeData(primarySwatch: Colors.amber),
home: Test(),
);
}
}
class Test extends StatefulWidget {
#override
_TestState createState() => _TestState();
}
class _TestState extends State<Test> {
TextEditingController controller = new TextEditingController(text: 'Kevin A');
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: "Title",
theme: new ThemeData(primarySwatch: Colors.amber),
home: Scaffold(
body: SafeArea(
child: TextField(
controller: controller,
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
controller.selection = new TextSelection(
baseOffset: 0,
extentOffset: controller.text.length,
);
showMenu(
context: context,
// TODO: Position dynamically based on cursor or textfield
position: RelativeRect.fromLTRB(0.0, 300.0, 300.0, 0.0),
items: [
PopupMenuItem(
child: Row(
children: <Widget>[
// TODO: Dynamic items / handle click
PopupMenuItem(
child: Text(
"Paste",
style: Theme.of(context)
.textTheme
.body2
.copyWith(color: Colors.red),
),
),
PopupMenuItem(
child: Text("Select All"),
),
],
),
),
],
);
},
child: Icon(Icons.navigation),
backgroundColor: Colors.green,
),
),
);
}
}

Flutter DropdownButtonFormField setState does not work outside of onChanged method

I just created a simple flutter app with two DropdownButtonFormField widgets.
And I want to update both widgets if first one is selected.
Expectation:
select number from the first dropdown menu
same number appears in the second dropdown
Result:
- select number from the first dropdown menu
- only the first dropdown menu is updated
Can somebody please tell me what I am doing wrong when calling setState onChaged method of the first dropdown menu widget?
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;
List<int> myList = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
int currentNumber = 1;
int anotherNumber = 9;
void _incrementCounter() {
setState(() {
_counter++;
});
}
#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:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
DropdownButtonFormField<int>(
value: currentNumber,
items: myList.map((int value) {
return DropdownMenuItem<int>(
value: value,
child: Container(
width: 200,
child: Text(
value.toString(),
),
),
);
}).toList(),
onChanged: (int newValue) {
setState(() {
currentNumber = newValue;
anotherNumber = newValue;
});
},
),
DropdownButtonFormField<int>(
value: anotherNumber,
items: myList.map((int value) {
return DropdownMenuItem<int>(
value: value,
child: Container(
width: 200,
child: Text(
value.toString(),
),
),
);
}).toList(),
onChanged: (int newValue) {
setState(() {
anotherNumber = newValue;
});
},
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}}

In flutter, can you set the appbar backgorund to change base on the value of a dropdown box?

my drop down box cycles through 5 strings
['blue','red','yellow','orange','grey']
I want my appbar title to be that dropdown box and for the value in the dropdown to determine the appbar color
DropDownWidget ddw = DropDownWidget();
var color = {
"blue": Colors.blue,
"red": Colors.red,
"yellow": Colors.yellow,
"orange": Colors.orange,
"grey": Colors.grey,
};
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: ddw,
backgroundColor: color[ddw],
),
}
The dropdown (ddw) shows up as the title, no problem.
I made a dictionary with those strings as the keys and the corresponding color as the value, but I am not able to use the string value of the dropdown to change the background.
Any suggestions?
You can copy paste run full code below
You can call setState in onChanged of DropdownButton
code snippet
appBar: AppBar(
backgroundColor: _appbarColor,
...
DropdownButton<Item>(
hint: Text("Select item"),
value: selectedColor,
onChanged: (Item Value) {
setState(() {
selectedColor = Value;
_appbarColor = selectedColor.color;
});
},
working demo
full code
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: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class Item {
const Item(this.name, this.color);
final String name;
final Color color;
}
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;
Color _appbarColor = Colors.blue;
Item selectedColor;
List<Item> colorList = <Item>[
const Item('blue', Colors.blue),
const Item('red', Colors.red),
const Item('yellow', Colors.yellow),
];
void _incrementCounter() {
setState(() {
_counter++;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: _appbarColor,
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
DropdownButton<Item>(
hint: Text("Select item"),
value: selectedColor,
onChanged: (Item Value) {
setState(() {
selectedColor = Value;
_appbarColor = selectedColor.color;
});
},
items: colorList.map((Item item) {
return DropdownMenuItem<Item>(
value: item,
child: Row(
children: <Widget>[
Container(
height: 15,
width: 15,
color: item.color,
),
SizedBox(
width: 10,
),
Text(
item.name,
style: TextStyle(color: Colors.black),
),
],
),
);
}).toList()),
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}