searchable_tree 0.0.2
searchable_tree: ^0.0.2 copied to clipboard
A highly customizable Flutter tree view widget with built-in search support, expand/collapse functionality, and beautiful UI.
Searchable Tree #
A highly customizable Flutter tree view widget with built-in search support, expand/collapse functionality, and beautiful UI. Perfect for displaying hierarchical data structures with a great user experience.
Features #
- π Built-in Search: Instant search functionality with automatic match highlighting
- π¨ Highly Customizable: Customize colors, text styles, icons, and more to match your app's design
- π± Responsive Design: Auto-wrap text for long titles, smooth animations, and touch-friendly interactions
- π Hierarchy Visualization: Indentation guide lines to clearly show tree structure
- β‘ Performance Optimized: Efficient rendering even for large tree structures
- π§ Flexible Configuration: Enable/disable features as needed
- π― Node Selection: Selectable nodes with visual feedback and auto-scroll
- β Add Button: Built-in add button for creating new nodes
- π± Context Menu: Support for node context menus with custom positioning
- π― Initial Selection: Set initial selected node on widget load
Demo #

Getting started #
Add the package to your pubspec.yaml:
dependencies:
searchable_tree: ^0.0.2
Import the package in your Dart code:
import 'package:searchable_tree/searchable_tree.dart';
Usage #
Basic Example #
// Create tree nodes
final List<TreeNode> nodes = [
TreeNode(
id: '1',
title: 'Parent Node 1',
children: [
TreeNode(id: '1-1', title: 'Child Node 1-1'),
TreeNode(
id: '1-2',
title: 'Parent Node 1-2',
children: [
TreeNode(id: '1-2-1', title: 'Child Node 1-2-1'),
TreeNode(id: '1-2-2', title: 'Child Node 1-2-2'),
],
),
],
),
TreeNode(id: '2', title: 'Parent Node 2'),
];
// Use the widget
SearchableTree(
nodes: nodes,
onNodeTap: (node) {
print('Tapped node: ${node.title}');
},
onExpandToggle: (node, isExpanded) {
print('Node ${node.title} is now ${isExpanded ? 'expanded' : 'collapsed'}');
},
)
Customized Example #
SearchableTree(
nodes: nodes,
showSearchField: true,
showExpandIcon: true,
indentation: 32.0,
expandIconColor: Colors.blue,
highlightColor: Colors.yellowAccent,
selectedColor: Colors.blue.withValues(alpha: 0.2),
titleStyle: TextStyle(
fontSize: 16,
color: Colors.grey[800],
),
searchFieldStyle: TextStyle(
fontSize: 14,
),
searchDecoration: InputDecoration(
hintText: 'Search nodes...',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
),
),
onNodeTap: (node) {
// Handle node tap
},
onExpandToggle: (node, isExpanded) {
// Handle expand/collapse
},
onNodeSelected: (node, isSelected) {
// Handle node selection
},
onAddButtonTap: () {
// Handle add button tap
},
onNodeShowMenu: (node, position) {
// Show context menu at position
},
)
Without Search Field #
SearchableTree(
nodes: nodes,
showSearchField: false,
onNodeTap: (node) {
print('Tapped: ${node.title}');
},
)
With Initial Selection #
SearchableTree(
nodes: nodes,
initialSelectedNodeId: '1-2',
onNodeSelected: (node, isSelected) {
print('Selected: ${node.title}');
},
)
Parameters #
| Parameter | Type | Default | Description |
|---|---|---|---|
nodes |
List<TreeNode> |
required | List of tree nodes to display |
titleStyle |
TextStyle? |
null | Custom style for node titles |
searchFieldStyle |
TextStyle? |
null | Custom style for search input text |
searchDecoration |
InputDecoration? |
null | Custom decoration for search field |
expandIconColor |
Color? |
null | Color for expand/collapse icons |
indentation |
double? |
24.0 | Indentation width for each tree level |
showExpandIcon |
bool |
true | Whether to show expand/collapse icons |
showSearchField |
bool |
true | Whether to show the search input field |
highlightSearchMatches |
bool |
true | Whether to highlight search matches |
highlightColor |
Color? |
Colors.yellow | Color for search match highlights |
selectedColor |
Color? |
null | Color for selected node highlight |
allowNodeSelection |
bool |
true | Whether to allow node selection |
onNodeTap |
void Function(TreeNode node)? |
null | Callback when a node is tapped |
onExpandToggle |
void Function(TreeNode node, bool isExpanded)? |
null | Callback when node expand state changes |
onNodeSelected |
void Function(TreeNode node, bool isSelected)? |
null | Callback when a node is selected |
onAddButtonTap |
VoidCallback? |
null | Callback when add button is tapped |
onNodeShowMenu |
void Function(TreeNode node, Offset position)? |
null | Callback when node menu icon is tapped |
initialSelectedNodeId |
String? |
null | Initial selected node ID |
TreeNode Class #
TreeNode({
required this.id, // Unique identifier for the node
required this.title,
this.children = const [],
this.data, // Custom data you can attach to the node
this.isExpanded = false,
});
Additional information #
- GitHub: https://github.com/lyj-514328/searchable_tree
- License: BSD 3-Clause
- Changelog: See CHANGELOG.md for version history
- Issues: Please file issues on the GitHub repository
- Contributions: Pull requests are welcome!
- Example: Check the
/examplefolder for a complete working example
Platform Support #
- β Android
- β iOS
- β Web
- β Windows
- β macOS
- β Linux