Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🐛 Unexpected focus behavior with NavigationView and ListView #913

Closed
loic-sharma opened this issue Aug 12, 2023 · 0 comments
Closed

🐛 Unexpected focus behavior with NavigationView and ListView #913

loic-sharma opened this issue Aug 12, 2023 · 0 comments
Labels
bug Something isn't working

Comments

@loic-sharma
Copy link
Contributor

loic-sharma commented Aug 12, 2023

Describe the bug
My app has a ListView with ListTiles and a Delete key shortcut to delete the currently focused ListTile. The app's focus behaves unexpectedly if it has a NavigationView.

Fluent UI version: 4.7.2
Flutter version: 3.10.6 (stable channel, framework revision f468f3366c)

Examples

❌ Fluent app with NavigationView

Code...
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:fluent_ui/fluent_ui.dart' as fluent;

void main() {
  debugFocusChanges = true;
  runApp(const App3());
}

class App3 extends StatefulWidget {
  const App3({super.key});

  @override
  State<App3> createState() => _App3State();
}

class _App3State extends State<App3> {
  List<String> _items = List.generate(5, (index) => 'Item: $index');

  void _removeItem(String value) {
    setState(() => _items = _items.where((item) => item != value).toList());
  }

  @override
  Widget build(BuildContext context) {
    return fluent.FluentApp(
      title: 'Remove list tile',
      home: fluent.NavigationView(
        pane: fluent.NavigationPane(
          selected: 0,
          items: [
            fluent.PaneItem(
              icon: const Icon(fluent.FluentIcons.mail),
              title: const Text('Home'),
              body: Focus(
                autofocus: true,
                child: ListView.builder(
                  itemCount: _items.length,
                  itemBuilder: (context, index) {
                    final item = _items[index];
                    return CallbackShortcuts(
                      bindings: {   
                        const SingleActivator(LogicalKeyboardKey.delete): () => _removeItem(item),
                      },
                      child: fluent.ListTile(
                        title: Text('Item $item'),
                        onPressed: () {
                          debugPrint('Item $item tapped');
                        },
                      ),
                    );
                  },
                ),
              ),
            ),
          ]
        )
      ),
    );
  }
}

Notice:

  1. Tabbing past the first ListTile loses focus. I have to press Tab to regain the focus.
  2. Deleting a ListTile using the Delete shortcut loses the focus. I have to press Tab to regain the focus.

fluent_list_delete_bug

✅ Fluent app without NavigationView

Code...
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:fluent_ui/fluent_ui.dart' as fluent;

void main() {
  debugFocusChanges = true;
  runApp(const App2());
}

class App2 extends StatefulWidget {
  const App2({super.key});

  @override
  State<App2> createState() => _App2State();
}

class _App2State extends State<App2> {
  List<String> _items = List.generate(5, (index) => 'Item: $index');

  void _removeItem(String value) {
    setState(() => _items = _items.where((item) => item != value).toList());
  }

  @override
  Widget build(BuildContext context) {
    return fluent.FluentApp(
      home: Container(
        color: Colors.white,
        child: ListView.builder(
          itemCount: _items.length,
          itemBuilder: (context, index) {
            final item = _items[index];
            return CallbackShortcuts(
              bindings: {   
                const SingleActivator(LogicalKeyboardKey.delete): () => _removeItem(item),
              },
              child: fluent.ListTile(
                title: Text(item),
                onPressed: () => debugPrint('Item $item tapped'),
              ),
            );
          },
        ),
      ),
    );
  }
}

This app works as expected (though with some minor focus highlight flashing):

fluent_list_delete_base

✅ Material app

Code...
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

void main() {
  debugFocusChanges = true;
  runApp(const App1());
}

class App1 extends StatefulWidget {
  const App1({super.key});

  @override
  State<App1> createState() => _App1State();
}

class _App1State extends State<App1> {
  List<String> _items = List.generate(5, (index) => 'Item: $index');

  void _removeItem(String value) {
    setState(() => _items = _items.where((item) => item != value).toList());
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: ListView.builder(
          itemCount: _items.length,
          itemBuilder: (context, index) {
            final item = _items[index];
            return CallbackShortcuts(
              bindings: {   
                const SingleActivator(LogicalKeyboardKey.delete): () => _removeItem(item),
              },
              child: ListTile(
                title: Text('Item $item'),
                onTap: () =>  debugPrint('Item $item tapped'),
              ),
            );
          },
        ),
      ),
    );
  }
}

The app works as expected:

material_list_delete

@bdlukaa bdlukaa added the bug Something isn't working label Aug 12, 2023
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants