reorderable_tree_list_view 0.0.1
reorderable_tree_list_view: ^0.0.1 copied to clipboard
A high-performance Flutter tree view widget with drag-and-drop reordering, automatic tree generation from URI paths, keyboard navigation, and comprehensive accessibility support.
ReorderableTreeListView #
A high-performance Flutter widget that displays hierarchical data in a tree structure with drag-and-drop reordering capabilities. Built on top of Flutter's ReorderableListView, it provides a smooth and intuitive user experience.
Visit our interactive Storybook demo to see all features in action.
β¨ Features #
- π³ Automatic Tree Generation - Just provide URI paths, the widget builds the tree
- π Drag & Drop Reordering - Intuitive drag-and-drop with visual feedback
- π Expand/Collapse - Animated folder expansion with state management
- π― Selection Modes - Support for none, single, and multiple selection
- β¨οΈ Keyboard Navigation - Full keyboard support with customizable shortcuts
- βΏ Accessibility - Screen reader support and ARIA compliance
- π¨ Highly Customizable - Flexible builders and extensive theming options
- β‘ Performance Optimized - Efficient rendering for large datasets
- π Actions & Intents - Integration with Flutter's Actions system
- π± Platform Adaptive - Works on iOS, Android, Web, and Desktop
π Quick Start #
Installation #
Add this to your package's pubspec.yaml file:
dependencies:
reorderable_tree_list_view: ^0.0.1
Basic Usage #
import 'package:flutter/material.dart';
import 'package:reorderable_tree_list_view/reorderable_tree_list_view.dart';
class MyTreeView extends StatefulWidget {
@override
State<MyTreeView> createState() => _MyTreeViewState();
}
class _MyTreeViewState extends State<MyTreeView> {
List<Uri> paths = [
Uri.parse('file:///documents/report.pdf'),
Uri.parse('file:///documents/images/photo1.jpg'),
Uri.parse('file:///documents/images/photo2.jpg'),
Uri.parse('file:///downloads/app.zip'),
Uri.parse('file:///downloads/music/song.mp3'),
];
@override
Widget build(BuildContext context) {
return ReorderableTreeListView(
paths: paths,
itemBuilder: (context, path) => Row(
children: [
Icon(Icons.insert_drive_file, size: 20),
SizedBox(width: 8),
Text(TreePath.getDisplayName(path)),
],
),
folderBuilder: (context, path) => Row(
children: [
Icon(Icons.folder, size: 20, color: Colors.amber),
SizedBox(width: 8),
Text(
TreePath.getDisplayName(path),
style: TextStyle(fontWeight: FontWeight.bold),
),
],
),
onReorder: (oldPath, newPath) {
setState(() {
paths.remove(oldPath);
paths.add(newPath);
});
},
);
}
}
π Documentation #
Core Concepts #
ReorderableTreeListView uses URI-based paths to automatically generate a tree structure. You don't need to manually create parent-child relationships - just provide paths and the widget handles the rest.
Key Properties #
| Property | Type | Description |
|---|---|---|
paths |
List<Uri> |
The list of URI paths to display |
itemBuilder |
Widget Function(BuildContext, Uri) |
Builder for leaf nodes (files) |
folderBuilder |
Widget Function(BuildContext, Uri)? |
Builder for folder nodes |
onReorder |
void Function(Uri, Uri)? |
Called when an item is reordered |
theme |
TreeTheme? |
Visual customization options |
selectionMode |
SelectionMode |
None, single, or multiple selection |
expandedByDefault |
bool |
Whether folders start expanded |
Advanced Features #
Selection Management
ReorderableTreeListView(
paths: paths,
selectionMode: SelectionMode.multiple,
initialSelection: {selectedPaths},
onSelectionChanged: (Set<Uri> selection) {
print('Selected: ${selection.length} items');
},
itemBuilder: (context, path) => Text(path.toString()),
)
Custom Themes
ReorderableTreeListView(
paths: paths,
theme: TreeTheme(
indentSize: 40.0,
showConnectors: true,
connectorColor: Colors.grey,
itemPadding: EdgeInsets.symmetric(horizontal: 16, vertical: 8),
borderRadius: BorderRadius.circular(8),
),
itemBuilder: (context, path) => Text(path.toString()),
)
Keyboard Navigation
ReorderableTreeListView(
paths: paths,
enableKeyboardNavigation: true,
itemBuilder: (context, path) => Text(path.toString()),
)
Supported keyboard shortcuts:
- Arrow Keys - Navigate through tree
- Enter/Space - Activate/Select item
- Right Arrow - Expand folder
- Left Arrow - Collapse folder
- Ctrl+A - Select all (when multiple selection enabled)
Validation Callbacks
ReorderableTreeListView(
paths: paths,
canDrag: (path) => !path.toString().contains('locked'),
canDrop: (draggedPath, targetPath) => isValidDrop(draggedPath, targetPath),
onWillAcceptDrop: (draggedPath, targetPath) {
// Additional validation
return true;
},
itemBuilder: (context, path) => Text(path.toString()),
)
Actions & Intents Integration #
The widget integrates with Flutter's Actions and Intents system:
Actions(
actions: <Type, Action<Intent>>{
ExpandNodeIntent: CallbackAction<ExpandNodeIntent>(
onInvoke: (intent) {
print('Expanding: ${intent.path}');
return null;
},
),
},
child: ReorderableTreeListView(
paths: paths,
itemBuilder: (context, path) => Text(path.toString()),
),
)
π― Examples #
Check out the example directory for complete examples:
- Simple Example - Basic usage with minimal configuration
- Storybook - Interactive showcase of all features
- Advanced Examples - Complex integrations
π§ Performance #
ReorderableTreeListView is optimized for large datasets:
- Viewport Optimization - Only visible items are rendered
- Efficient State Management - Minimal rebuilds on state changes
- Lazy Loading - Tree nodes are built on-demand
- Key-based Reconciliation - Smooth animations and transitions
Benchmarks #
| Dataset Size | Initial Render | Scroll Performance | Expand/Collapse |
|---|---|---|---|
| 100 items | <100ms | 60 FPS | <50ms |
| 1,000 items | <200ms | 60 FPS | <50ms |
| 10,000 items | <500ms | 58 FPS | <100ms |
π€ Contributing #
We welcome contributions! Please see our Contributing Guide for details.
Development Setup #
- Clone the repository
- Run
flutter pub get - Run tests with
flutter test - Run the example with
flutter run -d chrome
Running Tests #
# Run all tests
flutter test
# Run with coverage
flutter test --coverage
# Run specific test file
flutter test test/core/tree_builder_test.dart
π Comparison with Alternatives #
| Feature | ReorderableTreeListView | flutter_treeview | fancy_tree_view |
|---|---|---|---|
| Drag & Drop | β Built-in | β Manual | β οΈ Limited |
| Performance | β‘ Excellent | π Good | π Good |
| Accessibility | β Full | β οΈ Partial | β οΈ Partial |
| Actions/Intents | β Yes | β No | β No |
| URI-based | β Yes | β No | β No |
| Auto Tree Generation | β Yes | β No | β No |
π Migration Guide #
From flutter_treeview #
// Before (flutter_treeview)
TreeView(
controller: _treeViewController,
children: _nodes,
)
// After (reorderable_tree_list_view)
ReorderableTreeListView(
paths: _convertNodesToUris(_nodes),
itemBuilder: (context, path) => Text(path.toString()),
)
From fancy_tree_view #
// Before (fancy_tree_view)
AnimatedTreeView(
treeController: treeController,
nodeBuilder: (context, entry) => TreeTile(entry: entry),
)
// After (reorderable_tree_list_view)
ReorderableTreeListView(
paths: paths,
itemBuilder: (context, path) => Text(path.toString()),
animateExpansion: true,
)
π Troubleshooting #
Common Issues #
Q: Items are not reordering
- Ensure
onReordercallback is provided - Check that paths are being updated in setState
Q: Keyboard navigation not working
- Set
enableKeyboardNavigation: true - Ensure the widget has focus
Q: Performance issues with large datasets
- Use
expandedByDefault: false - Implement virtualization for extreme cases
- Consider paginating data
See our Troubleshooting Guide for more solutions.
π License #
This project is licensed under the MIT License - see the LICENSE file for details.
π Acknowledgments #
- Flutter team for the amazing framework
- Contributors and users of this package
- Inspired by VS Code's file explorer
π Support #
- π Issues: GitHub Issues
- π Docs: Full Documentation
Made with β€οΈ by the Flutter community