1

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')
                             ),
                          ),
                        )
                    );
                  },
                ),
              ),
            ),
          ),
        ),
      // ),
    );
  }
}
Jimmy
  • 21
  • 2
  • did you found any solution for this ? I am also looking for this solution. this is not solution proper way. I want to show user interaction where user can see his/her current cursor position.... – Kishan Oct 11 '22 at 04:28

0 Answers0