add inputt textfield when selected item dropdown in flutter - android

is it possible to add widget input text field when I selected item 'other' dropdown in flutter?
this is for flutter mobile android
my code
List <String> klasifikasi = [
'Fatality',
'Lainnya'];
DropdownButton<String>(
focusColor:Colors.white,
value: _chosenValue,
//elevation: 5,
style: TextStyle(color: Colors.white),
iconEnabledColor:Colors.blue,
items: klasifikasi.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value,style:TextStyle(color:Colors.black),),
);
}).toList(),
hint:Text(
"Klasifikasi Insiden",
style: TextStyle(
color: Colors.black,
fontSize: 14,
fontWeight: FontWeight.w400),
),
onChanged: (String value) {
setState(() {
_chosenValue = value;
if (_chosenValue == klasifikasi){
return Scaffold(
appBar: AppBar(),
body: Center(
child: Container(
color: Colors.grey,
child: _buildTextField(
labelText: 'Lainnya',
controller: _lainCtrl,
),
),
),
);
}
});
},
),
when I selected 'lainnya' showing textfield to input value

Maybe you can try this,
bool _showTextField = false;
Column(
children: [
DropdownButton<String>(
focusColor: Colors.white,
value: _chosenValue,
//elevation: 5,
style: TextStyle(color: Colors.white),
iconEnabledColor: Colors.blue,
items: klasifikasi.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(
value,
style: TextStyle(color: Colors.black),
),
);
}).toList(),
hint: Text(
"Klasifikasi Insiden",
style: TextStyle(
color: Colors.black,
fontSize: 14,
fontWeight: FontWeight.w400),
),
onChanged: (String value) {
setState(() {
_chosenValue = value;
if (_chosenValue == klasifikasi.last) {
_showTextField = true;
} else {
_showTextField = false;
}
});
}),
Visibility(
visible: _showTextField,
child: //Your textfield here,
),
],
);
i hope that will be help you ^_^

Put you dropdown button in a column,
bool addtextfield = false;
if (_chosenValue == klasifikasi){
setState((){
addtextfield = true;
});
}
addtextfield == true?
//Show ur input field
:Container(),

Related

How to prevent TextFormField redirecting to previous screen?

I am trying to create form.
I managed to create every widget in it, but every time I try to open TextFormField I get redirected back to my MainMenuScreen without any error.
I am using BLoC and routes. I think that issue might be related with using named routes.
Issue was not spotted before changing to named routes
MainMenuScreen fragment:
CategoryCard(
categoryName: 'Main dishes',
assetPath: 'assets/images/main_dish.png',
onPressed: () => Navigator.pushReplacement(context,
MaterialPageRoute(builder: (BuildContext context) {
return BlocProvider.value(
value: BlocProvider.of<RecipesBloc>(context)
..add(LoadRecipesEvent())
..category = 'main_dish',
child: RecipesScreen(),
);
})),
),
From MainMenuScreen I redirect to RecipesScreen
Fragment of RecipesScreen with redirect to RecipeCreateForm:
floatingActionButton: FloatingActionButton(
onPressed: () => Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (BuildContext context) {
return RecipeCreateForm();
}),
),
and then I redirect to RecipeCreateForm where I'm using TextFormFields.
Whenever I try to use TextFormField I get redirected back to MainMenuScreen.
class RecipeCreateForm extends StatefulWidget {
#override
_RecipeCreateFormState createState() => _RecipeCreateFormState();
}
class _RecipeCreateFormState extends State<RecipeCreateForm> {
final _recipeNameController = TextEditingController();
final _imageUrl = TextEditingController();
String? _difficultyValue;
late int _ingredientsQuantity;
late int _preparationStepsQuantity;
late List<Ingredient> _ingredientsValues;
late List<PreparationStep> _preparationStepsValues;
late double _preparationTime;
String? _portions;
#override
void initState() {
_ingredientsQuantity = 1;
_preparationStepsQuantity = 1;
_ingredientsValues = [];
_preparationStepsValues = [];
_preparationTime = 0;
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: true,
appBar: AppBar(
leading: IconButton(
onPressed: () {
Navigator.of(context).pop();
},
icon: Icon(
Icons.arrow_back,
color: Colors.white,
),
),
),
body: Scrollbar(
thickness: 10,
hoverThickness: 2,
child: SingleChildScrollView(
child: Container(
color: Colors.lightGreen.shade100,
child: Column(
children: <Widget>[
Padding(
padding: EdgeInsets.only(top: 15),
),
Text(
'Recipe name',
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20),
),
TextFormField(
style: TextStyle(
color: Colors.black,
fontSize: 18,
fontStyle: FontStyle.italic),
controller: _recipeNameController,
),
Padding(
padding: EdgeInsets.only(top: 15),
),
Text(
'Image',
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20),
),
TextFormField(
style: TextStyle(
color: Colors.black,
fontSize: 18,
fontStyle: FontStyle.italic),
controller: _imageUrl,
),
Padding(
padding: EdgeInsets.only(top: 15),
),
Text(
'Difficulty',
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20),
),
DropdownButton(
hint: _difficultyValue == null
? Text(
'Select difficulty',
style: TextStyle(
color: Colors.black,
fontSize: 18,
fontStyle: FontStyle.italic),
)
: Text(
_difficultyValue!,
style: TextStyle(
color: Colors.black,
fontSize: 18,
fontStyle: FontStyle.italic),
),
isExpanded: true,
iconSize: 30.0,
style: TextStyle(
color: Colors.black,
fontSize: 18,
fontStyle: FontStyle.italic),
items: ['Easy', 'Medium', 'Hard'].map(
(val) {
return DropdownMenuItem<String>(
value: val,
child: Text(val),
);
},
).toList(),
onChanged: (val) {
setState(
() {
_difficultyValue = val as String;
},
);
},
),
Padding(
padding: EdgeInsets.only(top: 15),
),
Text(
'Preparation time',
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20),
),
Slider(
value: _preparationTime,
onChanged: (newPreparationTime) {
setState(() => _preparationTime = newPreparationTime);
},
label: _preparationTime.toStringAsFixed(0),
min: 0,
max: 360,
divisions: 24,
),
Padding(
padding: EdgeInsets.only(top: 15),
),
Text(
'Ingredients',
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20),
),
SizedBox(
height: 175,
child: Scrollbar(
child: ListView.builder(
itemCount: _ingredientsQuantity,
itemBuilder: (context, index) {
return _ingredientRow(index);
}),
),
),
Row(
children: [
IconButton(
icon: Icon(Icons.add),
onPressed: () async {
setState(() {
_ingredientsQuantity++;
});
}),
IconButton(
icon: Icon(Icons.delete),
onPressed: () async {
setState(() {
_ingredientsQuantity = 1;
_ingredientsValues.clear();
});
})
],
),
Padding(
padding: EdgeInsets.only(top: 15),
),
Text(
'Preparation steps',
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20),
),
Scrollbar(
child: SizedBox(
height: 100,
child: ListView.builder(
shrinkWrap: true,
itemCount: _preparationStepsQuantity,
itemBuilder: (context, index) {
return _preparationStepRow(index);
}),
),
),
Row(
children: [
IconButton(
icon: Icon(Icons.add),
onPressed: () async {
setState(() {
_preparationStepsQuantity++;
});
}),
IconButton(
icon: Icon(Icons.delete),
onPressed: () async {
setState(() {
_preparationStepsQuantity = 1;
_preparationStepsValues.clear();
});
}),
],
),
Padding(
padding: EdgeInsets.only(top: 15),
),
Text(
'Portions',
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20),
),
DropdownButton(
hint: _portions == null
? Text(
'Select number of portions',
style: TextStyle(
color: Colors.black,
fontSize: 18,
fontStyle: FontStyle.italic),
)
: Text(
_portions!,
style: TextStyle(
color: Colors.black,
fontSize: 18,
fontStyle: FontStyle.italic),
),
isExpanded: true,
iconSize: 30.0,
style: TextStyle(
color: Colors.black,
fontSize: 18,
fontStyle: FontStyle.italic),
items: ['1', '2', '3', '4', '5', '6', '7'].map(
(val) {
return DropdownMenuItem<String>(
value: val,
child: Text(val),
);
},
).toList(),
onChanged: (val) {
setState(
() {
_portions = val as String;
},
);
},
),
ElevatedButton(
onPressed: () {
BlocProvider.of<RecipesBloc>(context).add(
AddRecipeEvent(
Recipe(
name: _recipeNameController.text,
image:
'https://www.thespruceeats.com/thmb/dA8o8EZpjJyeocYZNpzfknoKh2s=/4351x3263/smart/filters:no_upscale()/baked-stuffed-potatoes-482217-hero-01-850f2d87fe80403f923e140dbf5f1bf3.jpg',
ingredients: _ingredientsValues,
difficulty: _difficultyValue,
preparationTime: _preparationTime,
preparationSteps: _preparationStepsValues,
type: BlocProvider.of<RecipesBloc>(context)
.category
.toString(),
portions: _portions,
),
),
);
Navigator.of(context).pop();
},
child: Text('Submit'),
),
],
),
),
),
),
);
}
_ingredientRow(int key) {
return IntrinsicHeight(
child: Row(
children: [
Padding(padding: EdgeInsets.only(left: 10)),
SizedBox(
width: 225,
child: TextFormField(
maxLength: 35,
onChanged: (val) {
setState(() {
_onIngredientUpdate(key,name: val);
});
},
),
),
VerticalDivider(
width: 20,
thickness: 1,
color: Colors.black,
indent: 30,
endIndent: 10,
),
SizedBox(
width: 55,
child: TextFormField(
maxLength: 7,
initialValue: '0',
onChanged: (val) {
setState(() {
_onIngredientUpdate(key, quantity: val);
});
},
),
),
Padding(padding: EdgeInsets.only(left: 10)),
DropdownButton(
hint: Text('pcs'),
items: ['pcs', 'ml', 'g'].map(
(val) {
return DropdownMenuItem<String>(
value: val,
child: Text(val),
);
},
).toList(),
onChanged: (val) {
setState(() {
_onIngredientUpdate(key,measurement: val.toString());
});
},
)
],
),
);
}
_onIngredientUpdate(int key, {String? name, String? measurement, String? quantity}) {
int foundKey = -1;
_ingredientsValues.forEach((element) {
if (element.id.contains(key.toString())) {
foundKey = key;
}
});
if (-1 != foundKey) {
_ingredientsValues.removeWhere((map) {
return map.id == foundKey.toString();
});
}
Map<String, dynamic> json = {'id': key, 'name': name, 'measurement': measurement, 'quantity':quantity};
_ingredientsValues.add(json as Ingredient);
}
_preparationStepRow(int key) {
return IntrinsicHeight(
child: Row(
children: [
Padding(padding: EdgeInsets.only(left: 10)),
SizedBox(
width: 225,
height: 50,
child: TextFormField(
maxLength: 35,
onChanged: (val) => {
_onPreparationUpdate(key,val)
},
),
),
],
),
);
}
_onPreparationUpdate(int key, String val) {
int foundKey = -1;
_preparationStepsValues.forEach((element) {
if (element.id.contains(key.toString())) {
foundKey = key;
}
});
if (-1 != foundKey) {
_preparationStepsValues.removeWhere((map) {
return map.id == foundKey.toString();
});
}
Map<String, dynamic> json = {'id': key, 'step': val};
_preparationStepsValues.add(json as PreparationStep);
}
}
Issue GIF:
EDIT:
Issue is not related with form. I have replaced whole form with only one field without any logic and issue remains.
It is probably related to named routes.
As I was thinking, issue was related with usage of named routes.
I managed to bypass this issue with using Future.delayed and pushNamedAndRemoveUntil
In main_menu_screen I have created method which I later used to redirect to categories.
void redirectToCategory(BuildContext context, String categoryName) {
Future.delayed(Duration.zero, () {
Navigator.pushNamedAndRemoveUntil(
context,
'/recipeScreen',
(_) => false,
arguments: BlocProvider.value(
value: BlocProvider.of<RecipesBloc>(context)
..add(LoadRecipesEvent())
..category = categoryName,
child: RecipesScreen(),
),
);
});

how to make dropdown list#flutter

how to make dropdown list when on tap on button with out using dropdown button #flutterenter image description here
new DropdownButton(
value: _selectedLocation,
onChanged: (String newValue) {
setState(() {
_selectedLocation = newValue;
});
},
items: _locations.map((String location) {
return new DropdownMenuItem<String>(
child: new Text(location),
);
}).toList(),
Try below code hope its helpful to you . you must used dropdown_below from here, Refer my answer here also for same
Create your list:
List mobileList = [
{'no': 1, 'mobile': 'Apple'},
{'no': 2, 'mobile': 'Google'},
{'no': 3, 'mobile': 'Samsung'},
{'no': 4, 'mobile': 'Sony'},
{'no': 5, 'mobile': 'LG'},
];
One varibale and list our value
List<DropdownMenuItem<Object?>> _dropdownTestItems = [];
var selectedmobile;
Create initState() and dispose() method:
#override
void initState() {
_dropdownTestItems = buildDropdownTestItems(mobileList);
super.initState();
}
#override
void dispose() {
super.dispose();
}
Add your selected gender value in dropdown
List<DropdownMenuItem<Object?>> buildDropdownTestItems(List mobileList) {
List<DropdownMenuItem<Object?>> items = [];
for (var i in mobileList) {
items.add(
DropdownMenuItem(
value: i,
child: Text(
i['mobile'],
style: TextStyle(color: Colors.black),
),
),
);
}
return items;
}
Your Widget:
Padding(
padding: const EdgeInsets.all(8.0),
child: DropdownBelow(
itemWidth: 150,
itemTextstyle: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w400,
color: Colors.black),
boxTextstyle: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w400,
color: Colors.white54),
boxPadding: EdgeInsets.fromLTRB(13, 12, 13, 12),
boxWidth: 150,
boxHeight: 45,
boxDecoration: BoxDecoration(
color: Colors.transparent,
border: Border.all(
width: 1,
color: Colors.black,
),
),
icon: Icon(
Icons.arrow_downward,
color: Colors.black,
),
hint: Text(
'Select Mobile',
style: TextStyle(
color: Colors.black,
),
),
value: selectedmobile,
items: _dropdownTestItems,
onChanged: (selectedTest) {
setState(() {
selectedmobile = selectedTest;
});
},
),
),
Your Result Screen->

how to create dual checkbox in flutter

I want to create two checkbox next to each other and when one of them is checked, the other one be unchecked but I don`t know how to do that in flutter, so I'll be wonderful if someone could help me.
here is my codes:
bool isMan = false;
bool isWoman = false;
Padding(
padding: EdgeInsets.only(right: 10),
child: Text(
"Man:",
style: TextStyle(color: Colors.white, fontSize: 20),
),
),
Theme(
data: ThemeData(unselectedWidgetColor: Colors.white),
child: Checkbox(
value: isMan,
checkColor: Color(0xfff44336),
activeColor: Colors.white,
onChanged: (value) {
setState(
() {
isMan = value!;
},
);
},
),
),
Text(
"Woman:",
style: TextStyle(color: Colors.white, fontSize: 20),
),
Theme(
data: ThemeData(unselectedWidgetColor: Colors.white),
child: Checkbox(
value: isWoman,
checkColor: Color(0xfff44336),
activeColor: Colors.white,
onChanged: (value) {
setState(
() {
isWoman = value!;
},
);
},
),
),
Here is the solution.
bool isMan = false;
bool isWoman = false;
Center(
child: Row(
children: [
Padding(
padding: EdgeInsets.only(right: 10),
child: Text(
"Man:",
style: TextStyle(color: Colors.white, fontSize: 20),
),
),
Theme(
data: ThemeData(unselectedWidgetColor: Colors.white),
child: Checkbox(
value: isMan,
checkColor: Color(0xfff44336),
activeColor: Colors.white,
onChanged: (value) {
setState(
() {
isMan = value!;
isWoman = false;
},
);
},
),
),
Text(
"Woman:",
style: TextStyle(color: Colors.white, fontSize: 20),
),
Theme(
data: ThemeData(unselectedWidgetColor: Colors.white),
child: Checkbox(
value: isWoman,
checkColor: Color(0xfff44336),
activeColor: Colors.white,
onChanged: (value) {
setState(
() {
isWoman = value!;
isMan = false;
},
);
},
),
),
],
),
)
When checkbox is un/checked - change other checkbox value
bool isMan = false;
bool isWoman = false;
#override
Widget build(BuildContext context) {
return Row(children: [
Text("Man:"),
Checkbox(
value: isMan,
onChanged: (value) {
setState(() {
isMan = value!;
isWoman = !value; # or set it to false
});
}),
Text("Woman:"),
Checkbox(
value: isWoman,
onChanged: (value) {
setState(() {
isWoman = value!;
isMan = !value; # or set it to false
});
})
]);
}

How to put a button next to a RadioListTile ? - Flutter

I want to put an information button that works just like an AlertDialog() but I'm having problems to put it next to the checkbox text since they're organized inside a Column() and I cannot just put a Row() inside of it.
Here is the code of the checkboxes:
Column (
// ...
RadioListTile(
title: Text('Pelagens de camundongos',
style: TextStyle(
fontSize: 17.0, color: Colors.white)),
value: 1,
groupValue: id,
onChanged: (val) {
setState(() {
predominant = 'recessiva_aa';
id = 1;
});
},
),
const SizedBox(
height: 5.0,
),
RadioListTile(
title: Text('Pelagem em cães labradores',
style: TextStyle(
fontSize: 17.0, color: Colors.white)),
value: 2,
groupValue: id,
onChanged: (val) {
setState(() {
predominant = 'recessiva_ee';
id = 2;
});
},
),
),
Inside of the title of your RadioListTile instead of putting a text widget you can put a row and inside of that row have Text and an IconButton that will pop up your alert dialog when pressed like this
Column(
children: [
RadioListTile(
title: Row(
children: [
Text('Pelagens de camundongos',
style: TextStyle(fontSize: 17.0, color: Colors.white)),
IconButton(
icon: Icon(
Icons.info_outline,
),
onPressed: () {
// code to pop up alert dialog
},
),
],
),
value: 1,
groupValue: id,
onChanged: (val) {
setState(() {
predominant = 'recessiva_aa';
id = 1;
});
},
),
const SizedBox(
height: 5.0,
),
RadioListTile(
title: Row(
children: [
Text('Pelagem em cães labradores',
style: TextStyle(fontSize: 17.0, color: Colors.white)),
IconButton(
icon: Icon(
Icons.info_outline,
),
onPressed: () {
// code to pop up alert dialog
},
),
],
),
value: 2,
groupValue: id,
onChanged: (val) {
setState(() {
predominant = 'recessiva_ee';
id = 2;
});
},
),
],
)

Flutter dart: How to separate the space between Text and TextField and also bring together RadioListTile?

I'm learning Flutter. I have a problem (see image below). I would like to separate the space between Text "sex" and TextField "name". I would also like to bring together RadioListTile, they are very separate. Is it possible to do that? Follow my code
class _AlertDialogWidgetState extends State<AlertDialogWidget> {
#override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: ListBody(
children: <Widget>[
TextField(
autofocus: true,
decoration: InputDecoration(
contentPadding: new EdgeInsets.symmetric(vertical: 10.0, horizontal: 10.0),
border: OutlineInputBorder(), hintText: "New user"),
onChanged: (text) => widget.name = text,
),
Text(
'Sex',
textAlign: TextAlign.left,
overflow: TextOverflow.ellipsis,
style: TextStyle(fontWeight: FontWeight.bold),
),
RadioListTile(
title: Text("Female"),
value: "female",
groupValue: widget.sex,
onChanged: (String value) {
setState(() {
widget.sex = value;
});
},
),
RadioListTile(
title: Text("Male"),
value: "male",
groupValue: widget.sex,
onChanged: (String value) {
setState(() {
widget.sex = value;
});
},
),
RadioListTile(
title: Text("Other"),
value: "other",
groupValue: widget.sex,
onChanged: (String value) {
setState(() {
widget.sex = value;
});
},
),
],
),
);
}
}
Wrap your TextField with Padding to put more space between TextField and Text like this:
Padding(
padding: EdgeInsets.only(top: 15),
child: Text(
'Sex',
textAlign: TextAlign.left,
overflow: TextOverflow.ellipsis,
style: TextStyle(fontWeight: FontWeight.bold),
),
),
For RadioListTile, you cannot change the padding of radio, but you could use Radio wrapped with ListTile and set its alignment to have it closer to the title:
ListTile(
title: Align(
child: new Text("Female"),
alignment: Alignment(-1.2, 0),
),
leading: Radio(
value: "female",
groupValue: 'F',
onChanged: (String value) {
setState(() {
widget.sex = value;
});
},
),
)

Categories

Resources