Skip to content

Vertical focus traversal leaning more on left widgets #115550

@iamsahilsonawane

Description

@iamsahilsonawane

This issue is regarding focus traversals in layout for the big screens, particularly Android TV.
Wherein, I've implemented this TV guide layout (I've explained the layout below).

Screen.Recording.2022-11-17.at.16.05.34.mov

Well, the problem is that, when navigating down the widgets, the focus is not traversing down to its immediate bottom widget, instead, leaning on to the bottom left ones.

Reproducible Sample

NOTE: This example is using Mac as the device.

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.dark().copyWith(
        scaffoldBackgroundColor: const Color(0xFF12202F),
      ),
      debugShowCheckedModeBanner: false,
      home: const Scaffold(
        body: MyWidget(),
      ),
    );
  }
}

class MyWidget extends StatelessWidget {
  const MyWidget({super.key});

  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
      scrollDirection: Axis.horizontal,
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: List.generate(
          5,
          (x) {
            return Row(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: List.generate(
                10,
                (i) {
                  return InkWell(
                    autofocus: x == 0 && i == 0,
                    onTap: () {},
                    child: Builder(builder: (context) {
                      final isFocused = Focus.of(context).hasPrimaryFocus;
                      return Program(
                        isFocused: isFocused,
                        text: 'Item $x,$i',
                        isBig: x == 3 && i == 0,
                      );
                    }),
                  );
                },
              ),
            );
          },
        ),
      ),
    );
  }
}

class Program extends StatelessWidget {
  const Program({
    Key? key,
    required this.isFocused,
    required this.text,
    this.isBig = false,
  }) : super(key: key);

  final bool isFocused;
  final String text;
  final bool isBig;

  @override
  Widget build(BuildContext context) {
    return Container(
      width: isBig ? 250 : 200,
      height: 50,
      color: isFocused ? Colors.white : Colors.transparent,
      child: Text(text, style: TextStyle(color: isFocused ? Colors.black : Colors.white)),
    );
  }
}
Sample - Explanation & Video Demo

Explanation: If you run the code or see the demo down, with the same widths, it will traverse down like expected, but when there's an element with long width beneath, then it leans to the left.

In this example: Item 2,1 traverses to Item 2,0 when pressed down.

I think it is expected, but it continues going in the back direction which makes the scrollable scroll to the left (not expected from UX POV). Is it possible, to either shift the focus to the right of it? In this case, the focus from Item 2,1 should go to Item 3,1 instead of Item 3,0.

Here's the video demo of the sample.

Screen.Recording.2022-11-18.at.11.51.42.mov
Logs
[✓] Flutter (Channel stable, 3.3.4, on macOS 12.4 21F79 darwin-x64, locale en-GB)
    • Flutter version 3.3.4 on channel stable at /Users/iamsahilsonawane/Development/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision eb6d86ee27 (6 weeks ago), 2022-10-04 22:31:45 -0700
    • Engine revision c08d7d5efc
    • Dart version 2.18.2
    • DevTools version 2.15.0

[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0)
    • Android SDK at /Users/iamsahilsonawane/Library/Android/sdk
    • Platform android-33, build-tools 33.0.0
    • Java binary at: /Applications/Android Studio.app/Contents/jre/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 11.0.12+0-b1504.28-7817840)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 13.4.1)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 13F100
    • CocoaPods version 1.11.3

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2021.2)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 11.0.12+0-b1504.28-7817840)

[✓] VS Code (version 1.73.1)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.52.0

[✓] Connected device (3 available)
    • sdk google atv x86 (mobile) • emulator-5554 • android-x86    • Android 9 (API 28) (emulator)
    • macOS (desktop)             • macos         • darwin-x64     • macOS 12.4 21F79 darwin-x64
    • Chrome (web)                • chrome        • web-javascript • Google Chrome 107.0.5304.110

[✓] HTTP Host Availability
    • All required HTTP hosts are available

• No issues found!

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3Issues that are less important to the Flutter projectf: focusFocus traversal, gaining or losing focusfound in release: 3.3Found to occur in 3.3found in release: 3.6Found to occur in 3.6frameworkflutter/packages/flutter repository. See also f: labels.has reproducible stepsThe issue has been confirmed reproducible and is ready to work onr: fixedIssue is closed as already fixed in a newer version

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions