Hide keyboard upon tapping on radio button in Flutter - flutter

I am trying to find a way to dismiss the keyboard upon tapping on the radio buttons. I found some answers like this tutorial (https://flutterigniter.com/dismiss-keyboard-form-lose-focus/) but this will only hide the keyboard upon clicking outside the text field on an empty spot not tapping the radio button.
Here is a simple code if you would like to try. Any thoughts will be highly appreciated. Thanks
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(),
),
),
);
}
}
enum SingingCharacter { lafayette, jefferson }
class MyStatefulWidget extends StatefulWidget {
MyStatefulWidget({Key key}) : super(key: key);
#override
_MyStatefulWidgetState createState() => _MyStatefulWidgetState();
}
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
SingingCharacter _character = SingingCharacter.lafayette;
Widget build(BuildContext context) {
return Column(
children: <Widget>[
TextField(
autofocus: true,
),
ListTile(
title: const Text('Lafayette'),
leading: Radio(
value: SingingCharacter.lafayette,
groupValue: _character,
onChanged: (SingingCharacter value) {
setState(() {
_character = value;
});
},
),
),
ListTile(
title: const Text('Thomas Jefferson'),
leading: Radio(
value: SingingCharacter.jefferson,
groupValue: _character,
onChanged: (SingingCharacter value) {
setState(() {
_character = value;
});
},
),
),
],
);
}
}

in onChange Function write this line of code FocusScope.of(context).unfocus();

A couple of Solutions
Using SystemChannels
import 'package:flutter/services.dart';
SystemChannels.textInput.invokeMethod('TextInput.hide');
Using FocusScope
FocusScope.of(context).unfocus();

Add this line in onChange Function
FocusScope.of(context).requestFocus(new FocusNode());

Related

I want to make dropdown in expandable in all time in flutter,

I want to make this dropdown all time expandable state, don't need to un-expandable state. i want to hide or remove un-expandable state in dropdown and i want to show all time expandable to make true, its possible, is have any idea about it, please add it.
for exapmple, user click the dropdown right icon, don;t need to hide the dropdown items. how to do this
to achieve that design you can made a custom design for it. from what you explain the result should be done like this
and here is the custom code that I've created
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
final fieldText = TextEditingController();
MyApp({Key? key}) : super(key: key);
void clearText() {
fieldText.clear();
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(body: SafeArea(child: ListviewWithCheckBox()))
);
}
}
class ListviewWithCheckBox extends StatefulWidget {
#override
_ListviewWithCheckBoxState createState() => _ListviewWithCheckBoxState();
}
class _ListviewWithCheckBoxState extends State<ListviewWithCheckBox> {
List<String> _texts = [
"T-701 - ZONE 1/2/3",
"Slide Valves on 1st deck",
"F-301 - South side",
"Regen - 13th floor",
];
late List<bool> _isChecked;
#override
void initState() {
super.initState();
_isChecked = List<bool>.filled(_texts.length, false);
}
#override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Column(
children: [
CheckboxListTile(
controlAffinity: ListTileControlAffinity.leading,
title: Text('Oil_and_gas'),
value: false,
onChanged: (val) {
setState(
() {
// ....
},
);
},
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 30.0),
child: ListView.builder(
shrinkWrap: true,
primary: false,
itemCount: _texts.length,
itemBuilder: (context, index) {
return CheckboxListTile(
controlAffinity: ListTileControlAffinity.leading,
title: Text(_texts[index]),
value: _isChecked[index],
onChanged: (val) {
setState(
() {
// .....
},
);
},
);
},
),
),
],
),
);
}
}
that should work like a charm now

Flutter desktop listview move by up/down key

I am creating a flutter windows app. One page has listview in a scaffold widget. There is an action button on app bar. When I move the up/down key on listview. The focus item jumps from item 2 to say item 7, instead of next item, item 3. This occurs when I use up key moves to app bar button, then down key into listview. This does not occur if I move up and down within listview. This is an example code snippet I created for illustration. I found that the Focus widget enclosing Scaffold widget causes this problem. Removing the Focus widget can solve the problem. If I replace the whole Shortcuts-Actions-Focus widget chain by FocusActionDetector, this problem also exists. As I am still confusing about flutter's focus system, this may be incorrect.
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
static const String _title = 'Flutter Code Sample';
#override
Widget build(BuildContext context) {
return const MaterialApp(
title: _title,
home: MyStatefulWidget(),
);
}
}
class MyStatefulWidget extends StatefulWidget {
const MyStatefulWidget({Key? key}) : super(key: key);
#override
State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
}
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
final int nItems = 20;
late List<FocusNode> _fnList;
int idxFocus = 0;
#override
void initState() {
super.initState();
_fnList = List.generate(nItems, (i) => FocusNode());
}
#override
void dispose() {
super.dispose();
for (FocusNode fn in _fnList) {
fn.dispose();
}
}
#override
Widget build(BuildContext context) {
return Shortcuts(
shortcuts: <ShortcutActivator, Intent>{
LogicalKeySet(LogicalKeyboardKey.escape): const DismissIntent(),
},
child: Actions(
actions: <Type, Action<Intent>>{
DismissIntent: CallbackAction<DismissIntent>(
onInvoke: (DismissIntent intent) => debugPrint('escape pressed'),
),
},
child: Focus(
child: Scaffold(
appBar: AppBar(
title: const Text('ListView Focus Action Example'),
actions: [
IconButton(
icon: const Icon(Icons.done),
onPressed: (){},
),
]
),
body: Center(
child: ListView.builder(
itemCount: nItems,
itemBuilder: (BuildContext context, int index) {
return Focus(
focusNode: _fnList[index],
onFocusChange: (bool focused) {
debugPrint('Focus Change: $index - $focused');
},
debugLabel: 'index: $index',
child: Card(
child: ListTile(
title: Text('item $index'),
trailing: TextButton(
onPressed: () {},
child: const Text('OK')
),
),
)
);
},
),
),
),
),
),
// ),
);
}
}

How to disable a TextField by clicking a button

How can a button disable a TextField, so when I click the button I can't change the TextField's value?
You should change the TextField enabled property to false when the button is pressed. Here is an example:
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
/// This is the main application widget.
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
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 {
#override
_State createState() => _State();
}
class _State extends State<MyStatefulWidget> {
bool isTextFieldEnabled = true;
#override
Widget build(BuildContext context) {
return Container(
child: Column(children: [
TextField(enabled: isTextFieldEnabled,),
ElevatedButton(child: Text('Press Me To Disable TextField'),
onPressed: () {
setState(() {
isTextFieldEnabled = false;
});
},),
],)
);
}
}
you can use enabled false on text field:
TextField(
keyboardType: TextInputType.number,
enabled: false,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Current Miles',
),
),
but if you still want to handle a click on your text field you should use follow:
TextField(
readOnly: true,
enableInteractiveSelection: true,
onTap: () {
do_something(),
},
),
you need to use 'setState' on you button 'onPressed' and put any of the above needed flags in a variable and set accordingly.
Both TextField and TextFormField has a property called enabled, it's a bool, also you need to add a controller, and this can be achieved controlled by :
bool? enabled;
TextFormField(
enabled:enabled
)
//for the button
GestureDetector(onTap: () {
setState(() {
enabled = false;
});
})

Selecting a single CheckboxListTile item selects multiple ones?

On the code below, selecting "Option A" automatically selects "Option B" aswell.
This code is basically a copy paste from CheckboxListTile class documentation example, twice.
class Alergias extends StatefulWidget {
#override
_AlergiasState createState() => _AlergiasState();
}
class _AlergiasState extends State<Alergias> {
#override
Widget build(BuildContext context) {
return Scaffold(
...
body: Column(
CheckboxListTile(
title: const Text("Option A"),
value: timeDilation != 1.0,
controlAffinity: ListTileControlAffinity.leading,
onChanged: (bool value) {
setState(() {
timeDilation = value ? 2.0 : 1.0;
});
},
),
CheckboxListTile(
title: const Text("Option B"),
value: timeDilation != 1.0,
controlAffinity: ListTileControlAffinity.leading,
onChanged: (bool value) {
setState(() {
timeDilation = value ? 2.0 : 1.0;
});
},
),
],
),
);
}
}
I don't understand why this happens or if it has something to do with the StatefulWidget State. Can anyone help me?
The problem is arising due to the Same timeDilation variable used in both the CheckboxListTile.
Check out the code below,
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart' show timeDilation;
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> {
var value1 = timeDilation.abs();
var value2 = timeDilation.abs();
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children : <Widget>[
CheckboxListTile(
title: const Text("Option A"),
value: value1 != 1.0,
controlAffinity: ListTileControlAffinity.leading,
onChanged: (bool value) {
setState(() {
value1 = value ? 2.0 : 1.0;
});
},
),
CheckboxListTile(
title: const Text("Option B"),
value: value2 != 1.0,
controlAffinity: ListTileControlAffinity.leading,
onChanged: (bool value) {
setState(() {
value2 = value ? 2.0 : 1.0;
});
},
),
],
),
);
}
}
It seems like you are new to Flutter. Welcome to the Flutter community! The reason why both of your CheckBoxListTile are selecting at the same time is that because you are using the same value for both of them. You've set the value of the CheckBoxListTile to timeDilation, changing the value of timeDilation will result to selecting both CheckBoxListTile at once.
If you only have to options, I would suggest using a boolean to hold the value:
bool _first;
CheckboxListTile(
title: const Text("Option B"),
value: _first??false,
controlAffinity: ListTileControlAffinity.leading,
onChanged: (bool value) {
setState(() {
_first=true;
});
},
),
CheckboxListTile(
title: const Text("Option B"),
value: _first??true?false:true,
controlAffinity: ListTileControlAffinity.leading,
onChanged: (bool value) {
setState(() {
_first=false;
});
},
),

How to update child dropdown after parent dropdown's selection changes?

So I have a column of dropdowns, each dropdown a prerequisite of the dropdown below. When Dropdown A changes its value, I'd make an API call and populate Dropdown B, Dropdown C's options are dependent on the value of B, and so on...
I accomplished this scenario fine, but the problem I'm having is when Dropdowns A to D have been selected, and I change the value of Dropdown B, Dropdowns C and D doesn't change its value.
SOS & TY
Refer the given example:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
/// This 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(),
),
),
);
}
}
/// This is the stateful widget that the main application instantiates.
class MyStatefulWidget extends StatefulWidget {
MyStatefulWidget({Key key}) : super(key: key);
#override
_MyStatefulWidgetState createState() => _MyStatefulWidgetState();
}
/// This is the private State class that goes with MyStatefulWidget.
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', 'Free', 'Four']
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
);
}
}