I have a text field and a drop-down menu, both controlled by a Bloc. The problem I have is that as soon as the text field gets selected, it won't give up the focus if the user then tries to select something from the dropdown menu. The menu appears and then disappears an instant later and the focus is still on the text field.
Here is a basic app that demonstrates the problem:
import 'dart:async';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Textfield Focus Example',
home: HomePage(),
);
}
}
class HomePage extends StatelessWidget {
FormBloc formBloc = FormBloc();
final List<DropdownMenuItem> userMenuItems = ['Bob', 'Frank']
.map((String name) => DropdownMenuItem(
value: name,
child: Text(name),
))
.toList();
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
// user - drop down menu
Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('To: '),
StreamBuilder<String>(
stream: formBloc.selectedUser,
builder: (context, snapshot) {
return DropdownButton(
items: userMenuItems,
value: snapshot.data,
onChanged: formBloc.selectUser);
}),
],
),
// amount - text field
Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('Amount: '),
Container(
width: 100.0,
child: StreamBuilder<double>(
stream: formBloc.billAmount,
builder: (context, snapshot) {
return TextField(
keyboardType: TextInputType.number,
onChanged: formBloc.newBillAmount,
);
})),
],
),
],
),
),
);
}
}
class FormBloc {
StreamController<String> _selectedUserController = StreamController<String>();
Stream<String> get selectedUser =>
_selectedUserController.stream;
Function get selectUser => _selectedUserController.sink.add;
//Amount
StreamController<double> _billAmountController = StreamController<double>();
Stream<double> get billAmount =>
_billAmountController.stream;
void newBillAmount(String amt) =>
_billAmountController.sink.add(double.parse(amt));
void dispose() {
_selectedUserController.close();
_billAmountController.close();
}
}
Do I manually need to declare the FocusNode for the textField and tell it when to give up focus? Or is there some other reason that the text field is hogging all the attention?