flutterdartautocompleteaccessibilityusability

Keep Keyboard Focus after selecting value in Autocomplete


I use an Autocomplete in a Flutter Web-App (using web-renderer html, but this should not matter). There is an issue with keyboard navigation: If I flip though my UI (multiple textfields/autocompletes + a button) and select an item in an Autocomplete through the pulldown list, the focus is not returned to the textfield.

Take the following Column:

return Column(
    children: [
      ElevatedButton(
          onPressed: () {  },
          child: Text("Button1")
      ),
      Autocomplete<String>(
          optionsBuilder: (TextEditingValue value) {
            return ["ABC", "DEF"];
          }
      ),
      ElevatedButton(
        onPressed: () {  },
        child: Text("Button2")
      )
    ]
);

Using TAB I navigate first to Button1, then to the Autocomplete. I select some entry by hitting Enter and then focus seems to be lost so that the next TAB starts again at Button1. This has been a complaint by some visually impaired users btw.


Solution

  • I had that problem once, I solved it with fieldViewBuilder of Autocomplete widget to regain focus after an option is selected. I am not sure this is a perfect solution but it worked for me:

    import 'package:flutter/material.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            body: Center(
              child: MyWidget(),
            ),
          ),
        );
      }
    }
    
    class MyWidget extends StatelessWidget {
      FocusNode? _focusNode;
      final GlobalKey _key = GlobalKey();
      @override
      Widget build(BuildContext context) {
        return Column(children: [
          ElevatedButton(onPressed: () {}, child: const Text("Button1")),
          Autocomplete<String>(
            onSelected: (value) {
              _focusNode?.requestFocus();
            },
            fieldViewBuilder: (context, controller, focusNode, onFieldSubmitted) {
              _focusNode = focusNode;
              return TextField(
                key: _key,
                controller: controller,
                focusNode: focusNode,
                onSubmitted: (value) => onFieldSubmitted(),             
              );
            },
            optionsBuilder: (TextEditingValue value) {
            return ["ABC", "DEF"];
          }),
          ElevatedButton(onPressed: () {}, child: const Text("Button2"))
        ]);
      }
    }