1

I would like to focus on a DropdownButtonFormField from a TextFormField in Form using FocusScope.of(context).nextFocus() or FocusScope.of(context).requestFocus(_myNextNode).

The problem is that DropdownButtonFormField does not provide focusNode attribute.

I saw that focusNode is available in DropdownButton yet.

SampleApp 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: 'ListeTile Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: HomeScreen(),
    );
  }
}

class HomeScreen extends StatefulWidget {
  @override
  HomeScreenState createState() {
    return HomeScreenState();
  }
}

class HomeScreenState extends State<HomeScreen> {
  var _formKey = GlobalKey<FormState>();
  String dropdownValue = 'One';

  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: 3,
      child: Scaffold(
        appBar: AppBar(),
        body: Form(
            key: _formKey,
            child: Column(children: <Widget>[
              TextFormField(
                onFieldSubmitted: (_) => FocusScope.of(context).nextFocus(),
              ),
              DropdownButtonFormField(
                value: dropdownValue,
                items: <String>['One', 'Two', 'Free', 'Four']
                    .map<DropdownMenuItem<String>>((String value) {
                  return DropdownMenuItem<String>(
                    value: value,
                    child: Text(value),
                  );
                }).toList(),
                onChanged: (String newValue) {
                  setState(() {
                    dropdownValue = newValue;
                  });
                },
              )
            ])),
      ),
    );
  }
}

Do you know how to do it?

Adrien Arcuri
  • 1,962
  • 1
  • 16
  • 30

1 Answers1

0

Although DropdownButtonFormField widget doesn't have focusNode property, you can wrap this widget with Focus and a Listener to achieve the desired result. Sample working code below:

FocusNode _node = new FocusNode();

  @override
  Widget build(BuildContext context) {

    return DefaultTabController(
        length: 3,
        child: Scaffold(
            appBar: AppBar(),
            body: Form(
                key: _formKey,
                child: Column(children: <Widget>[
                  TextFormField(
                    onFieldSubmitted: (_) => FocusScope.of(context).nextFocus(),
                  ),
                  Focus(
                      focusNode: _node,
                      onFocusChange: (bool focus) {
                        setState((){});
                      },
                      child: Listener(
                          onPointerDown: (_) {
                            FocusScope.of(context).requestFocus(_node);
                          },
                          child: DropdownButtonFormField(
                            value: dropdownValue,
                            items: <String>['One', 'Two', 'Free', 'Four']
                                .map<DropdownMenuItem<String>>((String value) {
                              return DropdownMenuItem<String>(
                                value: value,
                                child: Text(value),
                              );
                            }).toList(),
                            onChanged: (String newValue) {
                              setState(() {
                                dropdownValue = newValue;
                              });
                            },
                            iconSize: 50,
                            style: TextStyle(color: _node.hasFocus ? Colors.black : Colors.white70, fontSize: 24),

                            hint: Text('Select',
                              style: TextStyle(color: _node.hasFocus ? Colors.white : Colors.white70),
                            ),

                          )

                      )
                  )]))));

This results in : when you enter some text in textfield and hit tab then it shifts the focuses on first item in the dropdownbuttonformfield. Then you can navigate through other items in it using keyboard's tab key. Hitting enter on the highlighted item will make that item selected in the dropdown.

enter image description here

This solution is derived from this discussion.

Hope this answers your question.

Darshan
  • 10,550
  • 5
  • 49
  • 61
  • Thank youn @Darshan for your answer. I tried your proposition which help a little and allow me to discover `Focus()` but is sounds like a trade-off. The thing is that it would be fine that it opens the menu items on focused. This issue may be related to this post [https://stackoverflow.com/questions/57529394/how-to-open-dropdownbutton-when-other-widget-is-tapped-in-flutter](https://stackoverflow.com/questions/57529394/how-to-open-dropdownbutton-when-other-widget-is-tapped-in-flutter). As written, it seems to not have an easy issue without modifying the SDK. – Adrien Arcuri Apr 06 '20 at 08:50