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')
),
),
)
);
},
),
),
),
),
),
// ),
);
}
}