패키지, 저장소 및 앱 카테고리 검색

list_treeview 표지
패키지 상세v0.4.2

list_treeview

Flutter용 트리뷰입니다. 리스트뷰 기반으로, 자식 레벨과 자식 노드가 무한히 증가합니다.

AndroidiOSmacOSWindowsLinux
30일 다운로드
486
좋아요
37
Pub 점수
150

패키지 설치

flutter pub add list_treeview

패키지 개요

공개 정보를 바탕으로 생성한 선택 가이드입니다.

ListTreeView는 ListView 기반의 트리 뷰 UI 컴포넌트를 제공하는 Flutter 패키지로, 자식 레벨과 노드의 무한 중첩을 지원합니다. 분기의 동적 확장 및 축소를 지원하여 파일 시스템, 조직도 또는 중첩된 카테고리와 같은 계층적 데이터를 표시하는 데 이상적입니다. 이 패키지는 가볍고 기존의 Flutter 앱과 원활하게 통합됩니다. Android, iOS, macOS, Windows, Linux 등 주요 플랫폼에서 모두 작동합니다.

사용 사례

  • 계층적 데이터 표시
  • 파일 시스템 탐색
  • 조직도
  • 중첩 카테고리 브라우징
  • 동적 트리 구조

주요 기능

  • 무한한 자식 레벨 지원
  • 성능을 위해 ListView 기반으로 구축됨
  • 확장 가능/접을 수 있는 노드
  • 크로스 플랫폼 호환성
  • 경량이며 통합이 쉬움

적합한 대상

  • 중첩된 데이터를 가진 앱
  • 파일 탐색기
  • 그룹화된 옵션을 가진 설정
  • 데이터 시각화 도구
  • 사용자 지정 트리 기반 UI

고려 사항

  • 매우 큰 트리에서 성능에 영향을 미칠 수 있습니다
  • 노드 상태의 수동 관리가 필요합니다
  • 제한된 내장 스타일 옵션
  • 매우 깊은 계층 구조에 최적화되지 않음
  • 내장된 검색 또는 필터링 없음

원본 README

연결된 소스 저장소의 README 원문 스냅샷입니다. 최신 내용은 저장소에서 확인하세요.

English | 简体中文

ListTreeView

pub package License: MIT Platform

A tree view for Flutter, built on top of ListView. It manages the tree structure of your data and leaves the UI entirely to you.

Features

  • Bring your own UI. The widget only manages the tree structure of the data — you design every row yourself in an itemBuilder.
  • Efficient. Rows are recycled through ListView's builder, so only visible nodes are built.
  • Unlimited depth. Child levels and child nodes can grow infinitely.
  • Imperative control. Insert, remove, expand/collapse, and select nodes through a controller.
  • Flutter 3.0+ / Dart 3.

Preview

ListTreeView demo animation ListTreeView example overview

Basic & Expand All Insert & Remove Selection Async Lazy Load
Basic and expand-all example Insert and remove example Selection example Async lazy-load example

Installation

Run this command:

flutter pub add list_treeview

This adds a line like the following to your package's pubspec.yaml (and runs an implicit flutter pub get):

dependencies:
  list_treeview: ^0.4.0

Then import it in your Dart code:

import 'package:list_treeview/list_treeview.dart';

Quick start

1. Initialize the controller

The controller must be created before the tree view is built — usually in initState.

class _TreePageState extends State<TreePage> {
  late TreeViewController _controller;

  @override
  void initState() {
    super.initState();
    _controller = TreeViewController();
  }
}
2. Define your data model

Your data class must extend NodeData. Beyond that you can add any properties you like. Make your own fields nullable (or give them defaults) so they remain optional.

/// The data bound to each node.
/// You must extend [NodeData]; everything else is up to you.
class TreeNodeData extends NodeData {
  TreeNodeData({this.label, this.color}) : super();

  final String? label;
  final Color? color;
}
3. Provide the data

Build your node hierarchy with addChild and hand the root-level nodes to the controller via treeData. Data can be loaded synchronously or asynchronously.

Future<void> loadData() async {
  // Data may be fetched asynchronously.
  await Future.delayed(const Duration(seconds: 1));

  final colors = TreeNodeData(label: 'Colors');
  colors.addChild(TreeNodeData(
      label: 'rgb(0,139,69)', color: const Color.fromARGB(255, 0, 139, 69)));
  colors.addChild(TreeNodeData(
      label: 'rgb(0,191,255)', color: const Color.fromARGB(255, 0, 191, 255)));

  final shapes = TreeNodeData(label: 'Shapes');
  shapes.addChild(TreeNodeData(label: 'Circle'));
  shapes.addChild(TreeNodeData(label: 'Square'));

  // Set the root-level nodes.
  _controller.treeData([colors, shapes]);

  setState(() {});
}
4. Build the tree

Render the tree with ListTreeView. Inside itemBuilder, cast the NodeData back to your own type and use level to indent each row.

ListTreeView(
  controller: _controller,
  itemBuilder: (BuildContext context, NodeData data) {
    final item = data as TreeNodeData;
    return Padding(
      padding: EdgeInsets.only(left: item.level * 16.0),
      child: ListTile(
        title: Text(item.label ?? ''),
        // Show a chevron only for nodes that have children.
        trailing: item.children.isNotEmpty
            ? Icon(item.isExpand ? Icons.expand_less : Icons.expand_more)
            : null,
      ),
    );
  },
  onTap: (NodeData item) => debugPrint('tapped index ${item.index}'),
  onLongPress: (NodeData item) => _controller.removeItem(item),
);

By default, tapping a row automatically expands or collapses it (toggleNodeOnTap is true). Set toggleNodeOnTap: false to drive expansion yourself with expandOrCollapse.

Operations

Insert
// Insert as the first child of [parent].
_controller.insertAtFront(parent, newNode);

// Append as the last child.
_controller.insertAtRear(parent, newNode);

// Insert at a specific index.
_controller.insertAtIndex(1, parent, newNode);

// Insert several nodes at the front in one call.
_controller.insertAllAtFront(parent, [nodeA, nodeB]);

Pass null as parent to insert at the root level:

_controller.insertAtFront(null, newNode);   // prepend a root node
_controller.insertAtRear(null, newNode);    // append a root node
_controller.insertAtIndex(1, null, newNode); // insert at root index 1

By default a node is inserted only when its parent is expanded. Pass closeCanInsert: true to insert even when the parent is collapsed:

_controller.insertAtFront(parent, newNode, closeCanInsert: true);
Remove
_controller.removeItem(item);
Expand / collapse
/// Toggle the node at a visible [index] (e.g. `item.index`).
_controller.expandOrCollapse(item.index);

/// Expand or collapse the whole tree at once.
_controller.expandAll();
_controller.collapseAll();

/// Query the current state.
final expanded = _controller.isExpanded(item);

Lazy loading note: child controllers are created only when a parent expands, so expandAll() expands every node whose children are already loaded. Nodes that fetch their children asynchronously are skipped until they have been loaded.

Select
/// Select / deselect a single node.
_controller.selectItem(item);

/// Select / deselect a node together with all of its descendants.
_controller.selectAllChild(item);

Read the result via item.isSelected inside your itemBuilder.

API reference

ListTreeView
Property Type Default Description
controller TreeViewController required Manages the tree data and operations.
itemBuilder Widget Function(BuildContext, NodeData) required Builds the widget for each visible node.
onTap Function(NodeData)? null Called when a row is tapped.
onLongPress Function(NodeData)? null Called when a row is long-pressed.
toggleNodeOnTap bool true Auto expand/collapse a node on tap. Set false to control it yourself.
shrinkWrap bool false Forwarded to the underlying ListView.
reverse bool false Forwarded to the underlying ListView.
padding EdgeInsetsGeometry EdgeInsets.all(0) Padding around the list.
removeTop bool true Remove the top MediaQuery padding.
removeBottom bool true Remove the bottom MediaQuery padding.
TreeViewController
Method Returns Description
treeData(List? data) void Sets the root-level nodes.
insertAtFront(parent, node, {closeCanInsert}) void Inserts node as the first child of parent. Pass null for root level.
insertAllAtFront(parent, nodes, {closeCanInsert}) void Inserts multiple nodes at the front. Pass null for root level.
insertAtRear(parent, node, {closeCanInsert}) void Appends node as the last child. Pass null for root level.
insertAtIndex(index, parent, node, {closeCanInsert}) void Inserts node at index. Pass null for root level.
removeItem(item) void Removes item from the tree.
expandOrCollapse(index) TreeNode Toggles the node at the visible index.
expandItem(treeNode) / collapseItem(treeNode) void Expands / collapses a node.
expandAll() void Expands every (loaded) node in the tree.
collapseAll() void Collapses every node in the tree.
isExpanded(item) bool Whether item is expanded.
selectItem(item) void Toggles the selection of item.
selectAllChild(item) void Toggles the selection of item and all descendants.
indexOfItem(item) int Visible index of item.
levelOfNode(item) int Depth level of item.
parentOfItem(item) NodeData? Parent of item (null for root-level nodes).
itemChildrenLength(item) int Number of direct children.
numberOfVisibleChild() int Total number of currently visible rows.
rebuild() void Forces the tree to rebuild.
NodeData

Extend this class for your own model. The tree keeps the following fields up to date, so you can read them inside itemBuilder:

Property Type Description
children List<NodeData> Direct child nodes. Use addChild() to append.
level int Depth of the node (root level is 0). Use for indenting.
index int Index among all currently visible nodes.
indexInParent int Index within the parent's children.
isExpand bool Whether the node is currently expanded.
isSelected bool Whether the node is selected.
addChild(NodeData child) void Appends a child node.

Example

The example directory is a gallery of focused, runnable demos, each on its own detail page:

  • Basic & Expand All — a nested tree with expand-all / collapse-all toolbar actions.
  • Insert & Remove — add child nodes from any row and remove subtrees.
  • Selection — select a node together with all of its descendants.
  • Async Lazy Load — fetch a branch's children on first tap.

Run it with:

cd example
flutter run

License

Released under the MIT License.

카테고리

소스 저장소

이 패키지를 사용하는 프로젝트

아직 데이터가 없습니다.