A simple yet powerful D-pad navigation system that makes Flutter development for Android TV, Fire TV, and other TV platforms as easy as native Android development.
- ๐ฏ Simple Setup: Just 3 steps to get started
- ๐จ Customizable Effects: Built-in focus effects + custom builders
- ๐บ Platform Support: Android TV, Fire TV, Apple TV, and more
- โก Performance: Optimized for smooth navigation
- ๐ง Programmatic Control: Full API for programmatic navigation
- ๐ฎ Game Controller Support: Works with standard controllers
- ๐ Sequential Navigation: Previous/Next support for media and lists
dependencies:
dpad: anyimport 'package:dpad/dpad.dart';
void main() {
runApp(
DpadNavigator(
enabled: true,
child: MaterialApp(
home: MyApp(),
),
),
);
}class MyScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column(
children: [
DpadFocusable(
autofocus: true,
onFocus: () => print('Focused'),
onSelect: () => print('Selected'),
builder: (context, isFocused, child) {
return AnimatedContainer(
duration: Duration(milliseconds: 200),
decoration: BoxDecoration(
border: Border.all(
color: isFocused ? Colors.blue : Colors.transparent,
width: 3,
),
borderRadius: BorderRadius.circular(8),
),
child: child,
);
},
child: ElevatedButton(
onPressed: () => print('Pressed'),
child: Text('Button 1'),
),
),
DpadFocusable(
onSelect: () => print('Button 2 selected'),
child: ElevatedButton(
onPressed: () => print('Pressed'),
child: Text('Button 2'),
),
),
],
);
}
}// Border highlight
DpadFocusable(
builder: FocusEffects.border(color: Colors.blue),
child: MyWidget(),
)
// Glow effect
DpadFocusable(
builder: FocusEffects.glow(glowColor: Colors.blue),
child: MyWidget(),
)
// Scale effect
DpadFocusable(
builder: FocusEffects.scale(scale: 1.1),
child: MyWidget(),
)
// Gradient background
DpadFocusable(
builder: FocusEffects.gradient(
focusedColors: [Colors.blue, Colors.purple],
),
child: MyWidget(),
)
// Combine multiple effects
DpadFocusable(
builder: FocusEffects.combine([
FocusEffects.scale(scale: 1.05),
FocusEffects.border(color: Colors.blue),
]),
child: MyWidget(),
)DpadFocusable(
builder: (context, isFocused, child) {
return Transform.scale(
scale: isFocused ? 1.1 : 1.0,
child: AnimatedContainer(
duration: Duration(milliseconds: 300),
decoration: BoxDecoration(
boxShadow: isFocused ? [
BoxShadow(
color: Colors.blue.withValues(alpha: 0.6),
blurRadius: 20,
spreadRadius: 2,
),
] : null,
),
child: child,
),
);
},
child: Container(
child: Text('Custom Effect'),
),
)DpadNavigator(
customShortcuts: {
LogicalKeyboardKey.keyG: () => _showGridView(),
LogicalKeyboardKey.keyL: () => _showListView(),
LogicalKeyboardKey.keyR: () => _refreshData(),
LogicalKeyboardKey.keyS: () => _showSearch(),
},
onMenuPressed: () => _showMenu(),
onBackPressed: () => _handleBack(),
child: MyApp(),
)Default Keyboard Shortcuts (v1.1.0+):
- Arrow Keys: Directional navigation (up, down, left, right)
- Tab/Shift+Tab: Sequential navigation (next/previous)
- Media Track Next/Previous: Media control navigation
- Channel Up/Down: TV remote sequential navigation
- Enter/Select/Space: Trigger selection action
- Escape/Back: Navigate back
- ContextMenu: Show menu
// Navigate in directions
Dpad.navigateUp(context);
Dpad.navigateDown(context);
Dpad.navigateLeft(context);
Dpad.navigateRight(context);
// Sequential navigation (new in v1.1.0)
Dpad.navigateNext(context); // Tab / Media Track Next
Dpad.navigatePrevious(context); // Shift+Tab / Media Track Previous
// Focus management
final currentFocus = Dpad.currentFocus;
Dpad.requestFocus(myFocusNode);
Dpad.clearFocus();DpadNavigator(
onMenuPressed: () {
// Handle menu button on TV remotes
_showMenu();
},
onBackPressed: () {
// Handle back button
if (Navigator.canPop(context)) {
Navigator.pop(context);
}
},
child: MyApp(),
)- Android TV: Full native D-pad support
- Amazon Fire TV: Compatible with Fire TV remotes
- Apple TV: Works with Siri Remote (Flutter web)
- Game Controllers: Standard controller navigation
- Generic TV Platforms: Any D-pad compatible input
- Always set
autofocus: trueon one widget per screen for initial focus - Test with real D-pad hardware, not just keyboard arrows
- Consider focus order - arrange widgets logically for navigation
- Provide clear visual feedback - use prominent focus indicators
- Handle edge cases - what happens when navigation fails?
The system consists of three main components:
- DpadNavigator: Root widget that captures D-pad events
- DpadFocusable: Wrapper that makes widgets focusable
- Dpad: Utility class for programmatic control
All components work together seamlessly with Flutter's focus system.
Coming from other TV navigation libraries?
- โ No complex configuration needed
- โ Works with standard Flutter widgets
- โ No custom FocusNode management required
- โ Built-in support for all TV platforms
- โ Extensive customization options
Check out the example app for a complete implementation showing:
- Grid navigation
- List navigation
- Custom focus effects
- Programmatic navigation
- Platform-specific handling
Contributions are welcome! Please feel free to submit a Pull Request.
This project is licensed under the MIT License - see the LICENSE file for details.
