Flutter space icons evenly in DropDownButton uniformally and equidistant - flutter

I'm building a Flutter Web App and am hacking the appbar for my navigation. I'm creating a dropdown menu to give some more options, only I want the arrow icons to be uniform and not change the spacing. This is an example of what I want:
And this is what I have:
It's subtle but also annoying me. This is the code I have for each dropdownbutton:
return DropdownButtonHideUnderline(
child: DropdownButton<String>(
isExpanded: false,
alignment: Alignment.center,
iconSize: 15,
value: dropdownValue,
icon: const Icon(Icons.arrow_downward),
// elevation: 16,
style: TextStyle(
color: Theme.of(context).colorScheme.primary,
fontFamily: GoogleFonts.lora().fontFamily,
),
onChanged: (String? value) {
// This is called when the user selects an item.
setState(() {
dropdownValue = value!;
});
},
I tried wrapping them in a sized box with equal height and width, but that also didn't work, this is the closest I've gotten them.

Related

Flutter RadioListTile Radio(icon) Size

After searching and several attempts, I did not find a way to increase the RadioListTile Radio(icon) Size in width, height and thickness
Is there a way to do that?
you could use the dense property like this:
RadioListTile(
dense: false, // Set to true for a smaller widget
contentPadding: EdgeInsets.symmetric(horizontal: 24.0, vertical: 8.0), // Increase or decrease the padding as needed
title: Text('RadioListTile'),
value: 1,
groupValue: 1,
onChanged: (value) {},
);
You can use ListTile instead of RadioListTile for increase size of Radio button as below code
ListTile(
leading: Transform.scale(
scale: 1.5,
child: Radio(
value: false,
groupValue: 0,
onChanged: (value) {},
),
),
title: Text('RadioListTile'),
),
Otherwise you have to make custom Radio button as per your requirement

Flutter: Width of DropDown menu independent of Button size

I have two DropDownButtons in one Row.
DropdownButtonHideUnderline(
child: DropdownButton(
isExpanded: true,
value: item,
items: widget.items.map((item) {
return DropdownMenuItem(
value: item,
child: Text(
item.toString(),
);
}).toList(),
onChanged: widget.onChanged,
selectedItemBuilder: (context) {
return widget.items.map((item) {
return Align(
child: Text(
item.toString(),
),
alignment: Alignment.centerLeft,
);
}).toList();
}
)
)
)
Is there a way to stretch the width of the menu instead of keeping it the size of the button?
Edit:
Example: Dart pad (Thanks to #Diwyansh; Dropdown only uses half the width of the UI, not entire)
I've fixed this and added more customization in DropdownButton2. By default dropdown menu will take button width but you can change it too if you want. Dropdownbutton2 is based on Flutter's core DropdownButton with more options you can customize to your needs.

Flutter: DropDownButton items below button

I want to create a pretty DropDownButton. Unfortunately, this seems to be pretty hard. While the design is fine, whenever I want to select a different item the list drops above the selection in a very ugly way. Below is a picture of the current version.
and after:
Below is my code:
var _repeats = ["Einmalig", "Wiederholen:"];
String _initRepeat = "Einmalig";
FormField<String>(
builder: (FormFieldState<String> state) {
return Container(
decoration: BoxDecoration(
color: Color.fromRGBO(204, 204, 204, 1.0),
border: Border.all(color: Colors.black),
borderRadius: BorderRadius.circular(15),
),
child: Padding(
padding: const EdgeInsets.only(left: 8.0, right: 8.0,),
child: DropdownButton<String>(
dropdownColor:
Color.fromRGBO(204, 204, 204, 1.0),
alignment: AlignmentDirectional.center,
value: _initRepeat,
isDense: true,
onChanged: (String? newValue) {
setState(() {
_initRepeat = newValue!;
state.didChange(newValue);
});
},
items: _repeats.map((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(
value,
style: TextStyle(
color: Colors.black,
fontSize: 12.0,
),
),
);
}).toList(),
),
),
);
},
),
Does anyone have advice on how to improve this? I basically want a selection that is smooth below the currently selected value.
Thank you very much!!
I've created a custom DropdownButton from current version of Flutter's DropdownButton and made it more customizable. It's easy, simple and you can have steady dropdown menu below the button "As long as it's possible" without any issues and many other features described with the package. Also, I've added the same functionality to DropdownButtonFormField2 and added a feature of using the button as a popup menu button and the ability of adding dividers after items. I've tested it very well and it works like a charm!
You can use the package or use the source file on GitHub directly. Also, I've Added custom widget with the package you can customize default DropdownButton2 widget for your entire app and use it with few lines as shown in the examples.
Package: DropdownButton2
Repository (GitHub): DropdownButton2
This package should be your way to go: dropdown_below. It offers exactly what you are looking for.
Or you check out this answer: DropdownButton under Button itself
Basically, it gives you a complete code example of a custom DropdownButton where the Dropdown is always "under" the button itself.

Reduce space between checkbox and title in flutter

I need to remove the space between checkbox and title but i cant able to reduce the space
here is my code
Expanded(
//width: 30,
child: CheckboxListTile(
checkColor: Colors.white,
activeColor: PRIMARY_COLOR,
title: Text('Select All',
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold,
color: Colors.black)),
value: _selectAll,
dense: true,
contentPadding: EdgeInsets.fromLTRB(0, 0, 0, 0),
controlAffinity: ListTileControlAffinity.leading,
onChanged: (bool value) {
}
}
setState(() {});
}),
),
here is the image how it is coming
How to reduce the space
You need to create a custom widget in order to resolve your problem, because if you're using the CheckboxListTile the way it is, you're gonna have to add more contentPadding to your widget in order to make the gap smaller and by default, I see that it has a default padding between the actual checkbox and the text widget ... I personally, don't know why you're trying to squeeze more space from this thing, because in documentation it says clearly that CheckboxListTile acts just like a ListTile, which in my knowledge it takes all the space available in a row and the padding between items in your widget will be a little bit bigger. Also your widget is wrapped in an Expanded widget which also take the whole space available. So in conclusion you either use it as the way it is intended, or you can create a custom widget that will bennefit your problems.

How to fix "BoxConstraints forces an infinite width" and how to delete an item from a list?

I am a beginner in Flutter and I can not get the result I want because I have a "layout problem". I tried several things for hours...
Technical problem:
When I click on "add player button" to add a new TextField to set more play name, I have an error: "BoxConstraints forces an infinite width". So, the TextField isn't displayed.
Other features that I do not know how to realize:
- I have a "dropdownmenu' to choose difficulty game. Why the default text isn't displayed (Difficulty: normal)?
- How to do this: When the user clicks on the icon "remove" (see suffixIcon on TextField), then the corresponding fieldText is deleted?
- How to do this: When user click to add player the default HintText is incremented (Player 2, Player 3, Player 4, ....)?
- Why my background gradient doesn't fix when user scroll page? (like in HTML/CSS 'background-attachment: fixed') ?
import 'package:flutter/material.dart';
/// Styles
///
class Homepage extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return _MyHomePageState();
}
}
class _MyHomePageState extends State<Homepage> {
String dropdownValue = 'Normal';
List<TextField> _playerList = new List(); //_playerList is my List name
int playerListIndex = 0; //Count the number of times "Add" button clicked
#override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(children: <Widget>[
// To have a gradient background
new Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
decoration: new BoxDecoration(
gradient: new LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
stops: [0.1, 1],
colors: [
Colors.redAccent[200],
Colors.red[300],
],
tileMode:
TileMode.repeated,
),
),
//I need SingleChildScrollView to haven't "Overflow yellow bar on bottom screen"
child: SingleChildScrollView(
child: Container(
padding: EdgeInsets.fromLTRB(20, 0, 20, 0),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
// Box to add big image
SizedBox(
height: 450,
),
// DROP DOWN MENU to choose difficulty modes
InputDecorator(
decoration: InputDecoration(
prefixIcon: const Icon(Icons.games),
filled: true,
),
child: DropdownButtonHideUnderline(
child: new DropdownButton<String>(
value: dropdownValue,
hint: Text('Difficulty normal'),
isDense: true,
items: <String>['Normal', 'Easy', 'Hard']
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
onChanged: (String newValue) {
setState(() {
dropdownValue = newValue;
});
},
),
),
),
//Field player name 1. At least I need 1 player
new TextField(
maxLength: 20,
decoration: InputDecoration(
prefixIcon: const Icon(Icons.person),
filled: true,
hintText:"Player 1",
counterText: "",
),
),
//Field for other player name 2, 3, 4, ...
new ListView.builder(
padding: EdgeInsets.all(0),
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemCount: _playerList.length,
itemBuilder: (context, index) {
TextField widget = _playerList.elementAt(index);
return widget;
}),
//Button to add other field text to set player name. The user can delete a player on click on "clear icon button"
new Align(
alignment: Alignment.centerRight,
child: FlatButton.icon(
color: Colors.black,
icon: Icon(
Icons.add,
color: Colors.white,
size: 18,
),
label: Text('Add player',
style:
TextStyle(fontSize: 12, color: Colors.white)),
onPressed: () {
setState(() {
playerListIndex++;
_playerList.add(
new TextField(
maxLength: 20,
decoration: InputDecoration(
prefixIcon: const Icon(Icons.person),
suffixIcon: new IconButton(
icon: Icon(Icons.clear),
onPressed: () {
_playerList.removeAt(playerListIndex); //Doesn't work
}),
filled: true,
hintText: "Player $playerListIndex", //Doesn't work i would like Player 2, Player 3, ...
counterText: "",
),
),
);
print(playerListIndex);
print(_playerList);
print(_playerList[0]);
});
}),
),
new ButtonTheme(
minWidth: 350,
height: 45,
child: FlatButton(
color: Colors.black,
child: Text('Play',
style:
TextStyle(fontSize: 18, color: Colors.white)),
onPressed: () {
// Perform some action
},
),
),
],
),
),
),
),
),
]),
);
}
}
I think that I understood what's going on. Let's begin:
First. Your TextField is not showing up and you're getting an error because you didn't set a width and a height for it, so, it's trying to get the maximum size as it can get. Solution for this? Wrap it in a Container widget (or SizedBox) and give it a width and a height. That should fix the first problem.
Second. Your DropDownMenu's hint text (Difficulty Normal) is not showing because you're not passing the parameter "hint" in the DropDown widget, See the hint propierty below.
Third. You want to clear the TextField string when click on a suffix, right? To achieve this, pass a GestureDetector or an IconButton as your suffix component, create a TextEditingController and pass it in the TextField, in the controller section, then, on the onPressed/onTap method (depending on which Widget you'll set) set this: _textController.text.clear() method, inside the setState function. This should fix the problem.
Forth. You want the list of player's string to increase as you add more players right? You have many ways to achieve this, one of them is creating an empty list, you can mock to test it, and then, everytime you click the "Add player" button, you'll add a String corresponding to the value inside a for loop passing the for's index as int value in the "Player $index". Again, the for method will receive a setState method, and inside the setState, your logic to add one more Player.
And finally, your gradient does not keep fixed? Hmm, I think you can pass a proprierty in the Scaffold widget called resizeToAvoidBottomInset and set it to false.
If something did not work as you expected, reply it and I'll help you out.