simple_tv_navigation 0.0.1+13 copy "simple_tv_navigation: ^0.0.1+13" to clipboard
simple_tv_navigation: ^0.0.1+13 copied to clipboard

A highly optimized TV navigation system for Flutter applications, providing efficient ID-based focus management for TVs, set-top boxes, and game consoles.

Simple TV Navigation #

A highly optimized and efficient TV navigation system for Flutter applications. This package provides an ID-based approach to TV navigation, where elements are connected through explicit ID references rather than relying on position or automatic detection.

Features #

  • ID-based Navigation: Each navigable element has explicit references to its neighbors in all directions (left, right, up, down)
  • Optimized Rendering: Focus updates only trigger re-renders of affected elements
  • Smart Fallback: Automatically finds the best element to focus if explicit IDs are missing
  • Focus History: Tracks navigation history for handling back navigation
  • Custom Focus Appearance: Highly customizable focus indicators and transitions
  • Spatial Awareness: Intelligent navigation based on element positions when explicit connections are missing
  • Memory Management: Efficient storage of the navigation graph and cleanup of unused elements
  • Debugging Tools: Navigation path analysis and validation
  • Input Handling: Support for keyboard, remote controls, and gamepads
  • Enable/Disable: Easily toggle the entire navigation system on or off
  • Flexible Styling: Control focus decoration with options for default, custom, or no decoration
  • Accessibility: Built-in support for screen readers and accessibility tools
  • Flexible Widget Creation: Build focusable elements from scratch with the builder parameter

Installation #

Add the package to your pubspec.yaml:

dependencies:
  simple_tv_navigation: ^0.0.1+13

Basic Usage #

Wrap your application (or a section of it) with TVNavigationProvider:

TVNavigationProvider(
  initialFocusId: 'firstItem',
  enabled: true, // Can be toggled to disable navigation
  child: Scaffold(
    body: YourAppContent(),
  ),
)

Make any widget navigable by wrapping it with TVFocusable:

TVFocusable(
  id: 'item1',
  leftId: null, // No element to the left
  rightId: 'item2', // ID of element to the right
  upId: null, // No element above
  downId: 'item3', // ID of element below
  onSelect: () {
    // Handle selection (e.g., when user presses Enter/OK)
    print('Item 1 selected!');
  },
  onFocus: () {
    // Handle focus (e.g., for analytics or pre-loading)
    print('Item 1 focused!');
  },
  child: YourWidget(),
)

Advanced Features #

Custom Focus Appearance #

Use the focusBuilder parameter to customize the appearance when an element is focused:

TVFocusable(
  id: 'customItem',
  // ... other parameters
  focusBuilder: (context, isFocused, isSelected, child) {
    return AnimatedContainer(
      duration: const Duration(milliseconds: 200),
      transform: isFocused 
          ? (Matrix4.identity()..scale(1.1))
          : Matrix4.identity(),
      decoration: BoxDecoration(
        border: isFocused
            ? Border.all(color: Colors.blue, width: 3)
            : null,
        borderRadius: BorderRadius.circular(8),
      ),
      child: child,
    );
  },
  child: YourWidget(),
)

Complete Widget Customization #

Use the builder parameter for complete control over the widget rendering:

TVFocusable(
  id: 'customItem',
  // Child is optional when using builder
  builder: (context, isFocused, isSelected, child) {
    return Container(
      padding: EdgeInsets.all(16),
      decoration: BoxDecoration(
        color: isFocused ? Colors.blue.withOpacity(0.2) : Colors.transparent,
        borderRadius: BorderRadius.circular(8),
        boxShadow: isFocused 
            ? [BoxShadow(color: Colors.blue, blurRadius: 8)]
            : null,
      ),
      child: Column(
        children: [
          if (isFocused) Icon(Icons.check),
          Text('Custom Built Widget'),
          if (isSelected) Text('Selected!'),
        ],
      ),
    );
  },
)

Enabling/Disabling Navigation #

You can easily toggle the entire navigation system on or off:

TVNavigationProvider(
  enabled: shouldEnableNavigation, // Dynamic flag
  child: YourApp(),
)

This is useful for:

  • Developing apps that work on both TV and mobile platforms
  • Temporarily disabling navigation during animations or loading states
  • A/B testing navigation systems
  • Creating a "desktop mode" vs "TV mode" in your application

Programmatic Navigation #

You can control the navigation programmatically using the extension methods:

// Move focus in a direction
context.moveFocus(FocusDirection.right);

// Set focus to a specific element by ID
context.setFocus('item3');

// Select the currently focused element
context.selectFocused();

// Navigate back to the previous element
context.navigateBack();

Nested Navigation Contexts #

You can create nested navigation contexts (e.g., for dialogs or modals):

showDialog(
  context: context,
  builder: (dialogContext) {
    return TVNavigationProvider(
      initialFocusId: 'dialogButton1',
      child: AlertDialog(
        // ... dialog content
        actions: [
          TVFocusable(
            id: 'dialogButton1',
            rightId: 'dialogButton2',
            child: TextButton(
              onPressed: () { /* ... */ },
              child: Text('OK'),
            ),
          ),
          TVFocusable(
            id: 'dialogButton2',
            leftId: 'dialogButton1',
            child: TextButton(
              onPressed: () { /* ... */ },
              child: Text('Cancel'),
            ),
          ),
        ],
      ),
    );
  },
);

Analyzing Navigation Paths #

Focus Decoration Options #

You can control how focus is visually indicated:

// No decoration (default)
TVFocusable(
  id: 'item1',
  child: Text('No decoration'),
  // showDefaultFocusDecoration defaults to false
)

// Default decoration (blue border)
TVFocusable(
  id: 'item2',
  child: Text('Default decoration'),
  showDefaultFocusDecoration: true,
)

// Custom decoration
TVFocusable(
  id: 'item3',
  child: Text('Custom styling'),
  focusBuilder: (context, isFocused, isSelected, child) {
    return Container(
      transform: isFocused 
          ? Matrix4.identity()..scale(1.1)
          : Matrix4.identity(),
      child: child,
    );
  },
)

Additional Information #

Contributing #

We welcome contributions! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.

Issues and Support #

If you encounter any issues or have questions, please file an issue on our GitHub repository.

Response Time #

We aim to respond to issues and pull requests within 48 hours. For critical issues, we'll try to respond as quickly as possible.

Documentation #

For more detailed documentation and examples, please visit our documentation site.

License #

This project is licensed under the MIT License - see the LICENSE file for details.

5
likes
0
points
7
downloads

Publisher

verified publisherflutterwithakmaljon.uz

Weekly Downloads

A highly optimized TV navigation system for Flutter applications, providing efficient ID-based focus management for TVs, set-top boxes, and game consoles.

Repository (GitHub)
View/report issues

Documentation

Documentation

License

unknown (license)

Dependencies

bloc, equatable, flutter, flutter_bloc

More

Packages that depend on simple_tv_navigation