搜索插件、代码仓与 APP 分类

flutter_advanced_table 封面
插件详情v1.1.5

flutter_advanced_table

轻松在 Flutter 中构建美观、交互式且功能丰富的数据表格。

AndroidiOSWebmacOSWindowsLinux
近 30 天下载
68
喜欢数
26
Pub 分数
160

安装插件

flutter pub add flutter_advanced_table

插件介绍

基于插件公开信息、社区数据与项目使用情况整理的选型参考。

Flutter Advanced Table 是一个功能强大的包,用于在 Flutter 应用中创建视觉上吸引人、交互性强且功能丰富的数据表格。它开箱即用地支持排序、过滤、分页和自定义样式,使开发者能够轻松显示结构化数据。该包以性能和灵活性为核心设计,可在 Android、iOS、Web、macOS、Windows 和 Linux 等所有主要平台上无缝运行。通过提供响应式布局和流畅的交互体验,该包提升了用户体验,非常适合仪表板、管理面板和数据密集型应用。

适合场景

  • 构建管理仪表板
  • 显示大型数据集
  • 创建交互式报告
  • 实现可搜索的表格
  • 设计响应式数据网格

主要特点

  • 内置排序和筛选
  • 分页支持
  • 可自定义的列渲染
  • 跨平台的响应式设计
  • 高性能处理大型数据集
  • 可扩展的部件结构

适合对象

  • 开发数据密集型应用程序的开发者
  • 需要可重用表格组件的团队
  • 需要跨平台表格一致性的项目
  • 希望获得精美表格界面的UI设计师
  • 具有动态或实时数据的应用程序

使用建议

  • 需要了解 Flutter widget
  • 可能需要额外的状态管理来处理复杂逻辑
  • 性能取决于数据大小和复杂度
  • 有限的内置导出功能
  • 自定义样式可能需要高级的 Dart 知识

原始 README

以下为关联源码仓库的 README 原文快照,最新内容请访问源码仓库。

Advanced Table Widget for Flutter 🚀📊

pub.dev GitHub

Tired of boring, basic tables in your Flutter apps? Want something that sparkles ✨, sizzles 🔥, and makes your data sing 🎤? Well, buckle up, buttercup, because the Advanced Table Widget is here to revolutionize your data presentation!

This isn't your grandma's table (unless your grandma is a seriously cool Flutter developer 😎). This widget gives you superpowers over your tabular data, letting you customize everything from headers to rows to actions with the finesse of a master chef crafting a gourmet meal.

Features

  • Headers that POP! 💥: Define custom header widgets with a builder. No more dull, default text headers. Go wild! Use icons! Use colors! Use... anything! (Within reason, of course. We don't want to break Flutter.)
  • Rows that ROCK! 🎸: Build row elements dynamically with a builder. Each row is a blank canvas for your creativity.
  • Actions, Actions, Actions! 🎬: Add action buttons to each row. Think "Edit", "Delete", "Send Pigeon" (okay, maybe not that last one, but you get the idea).
  • Loading States? We Got You Covered. ⏳: Built-in loading indicators for both the entire table and individual "load more" scenarios. No more awkward blank spaces while your data fetches from the digital ether.
  • Empty State? No Problem! 🤷‍♀️: Display a custom widget when there's no data to show. Tell your users "Hey, there's nothing here... yet!" in style.
  • Decoration Extravaganza! 🎨: Customize the look and feel of your table with decorations for headers, rows, and even individual cells. Rounded corners? Gradients? Shadows? You got it!
  • Padding Paradise! 🏝️: Control the padding everywhere. Inner, outer, header, row... you're the padding master.
  • Hover Effects? Oh Yeah! ✨: Make your rows react to user interaction with hover effects. It's like magic, but it's just Flutter.
  • Row Taps? We Listen. 👂: Handle row taps with a callback. Take your users on a journey when they click!
  • Lazy Loading? Of course! 🦥: Implement lazy loading for large datasets, like a coding ninja.
  • Animations?! YES!!! 💫: Use the rowBuilder to add any animation you want.
  • Fully Customizable: we added builders everywhere, if you want to change something you can 🛠️
  • Sliver Support 📜: Seamlessly integrate with scrollable layouts using sliver support for better performance and flexibility!!

Demo

Getting Started

  1. Add it to your pubspec.yaml:

        flutter pub add flutter_advanced_table
    
  2. Import it:

    import 'package:advanced_table_widget/advanced_table_widget.dart'; // Or your package name
  1. Start building awesome tables!

Usage

Constructor Arguments

Here's a detailed explanation of all the constructor arguments for AdvancedTableWidget:

  • headerBuilder: (required) Function to build custom header widgets for each column
  • rowElementsBuilder: (required) Function to build the cells within each row
  • items: (required) Your data list - each item becomes a row
  • isLoadingAll: (required) ValueNotifier to control full table loading state
  • headerItems: (required) List of items to be displayed in the header
  • fullLoadingPlaceHolder: (required) Widget shown during full table loading

Optional arguments:

  • actions: List of actions for each row (used for width calculations)
  • actionBuilder: Function to build action buttons for each row
  • isLoadingMore: ValueNotifier for pagination loading state
  • onEmptyState: Widget to show when table has no data
  • headerDecoration: BoxDecoration for the header row
  • innerHeaderPadding: Padding inside header cells
  • elementsPadding: Padding around table content
  • loadingMorePlaceHolder: Widget shown during pagination loading
  • rowElementsDecoration: BoxDecoration for data rows
  • innerRowElementsPadding: Padding inside row cells
  • headerTextStyle: TextStyle for header text
  • outterRowsPadding: Padding around all rows
  • rowDecorationBuilder: Function to build dynamic row decorations
  • outterHeaderPadding: Padding around header row
  • addSpacerToActions: Add space before action buttons (default: true)
  • onRowTap: Callback function when row is tapped
  • rowBuilder: Custom row builder for animations/effects

Full Example

Here's a taste of what you can do:

import 'package:flutter/material.dart';
import 'package:flutter_animate/flutter_animate.dart'; // Import the library

// ... (Your Order class and _generateFakeOrders function from the previous examples)

class OrdersTableExample extends StatefulWidget {
  const OrdersTableExample({super.key});

  @override
  State<OrdersTableExample> createState() => _OrdersTableExampleState();
}

class _OrdersTableExampleState extends State<OrdersTableExample> {
      final ValueNotifier<bool> _isLoadingAll = ValueNotifier(false);
    final ValueNotifier<bool> _isLoadingMore = ValueNotifier(false);
    late List<Order> _orders;
    final int _initialLoad = 10;
    final int _loadMoreCount = 5;

    @override
    void initState() {
      super.initState();
      _orders = _generateFakeOrders(_initialLoad);
    }
  Future<void> _loadMore(int index) async {
      if (index < _orders.length - 2) return; // Only load if near the end.

      if (_isLoadingMore.value) return;
      _isLoadingMore.value = true;
      await Future.delayed(const Duration(seconds: 1));
      final newOrders = _generateFakeOrders(_loadMoreCount); // Get next batch
      setState(() {
          _orders.addAll(newOrders);
      });
    _isLoadingMore.value = false;
  }

    Widget rowBuilder(
    BuildContext context, int rowIndex, Widget row, bool isHover, int length) {
      _loadMore(rowIndex); // For lazy loading
       return AnimatedScale(
      duration: const Duration(milliseconds: 300),
      scale: isHover ? 1.02 : 1,
      child: row.animate(
          delay: length < 10 ? (rowIndex.milliseconds * 300) : null,
          effects: [
            SlideEffect(
              duration: 500.milliseconds,
              curve: Curves.easeInOut,
              begin: const Offset(0, -0.1),
            ),
            FadeEffect()
          ]),
    );
  }

   BoxDecoration rowDecorationBuilder(
    BuildContext context, int index, bool isHover) {
  final isOdd = index % 2 == 0;
  return BoxDecoration(
    borderRadius: const BorderRadius.all(Radius.circular(7.0)), // Consistent rounding
    color: isHover
        ? Theme.of(context).primaryColor.withAlpha(100)
        : isOdd
            ? Colors.transparent
            : Theme.of(context).primaryColor.withOpacity(0.1),
  );
}



  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Advanced Table Example'),
      ),
      body: AdvancedTableWidget(
        isLoadingAll: _isLoadingAll,
        isLoadingMore: _isLoadingMore,
        items: _orders,
        headerItems: const ['Order #', 'Local', 'Customer', 'Price', 'Payment', 'Date', 'Status'],
        onEmptyState: const Center(child: Text('No orders yet! 😢')),
         fullLoadingPlaceHolder:
                const Center(child: CircularProgressIndicator()),
        loadingMorePlaceHolder: const LinearProgressIndicator(),
        headerBuilder: (context, header) => Container(
           width: header.defualtWidth, // Use provided width
          padding: const EdgeInsets.all(8.0),
          alignment: header.index == 0 ? Alignment.centerLeft : Alignment.center, // Example alignment
          child: Text(
            header.value.toString(),
            style: const TextStyle(fontWeight: FontWeight.bold),
          ),
        ),
        rowElementsBuilder: (context, rowParams) {
          final order = _orders[rowParams.index];
          return [
                SizedBox(
                width: rowParams.defualtWidth,
                child:   Text(order.orderNumber)),
            SizedBox(
                width: rowParams.defualtWidth,
                child:  Center(child: Text(order.localName))),
            SizedBox(
                width: rowParams.defualtWidth,
                child: Center(child:Text(order.userFullName))),
            SizedBox(
                width: rowParams.defualtWidth,
                child:  Center(child:Text('\$${order.toBePaidPrice.toStringAsFixed(2)}'))),
            SizedBox(
                width: rowParams.defualtWidth,
                child: Center(child: Text(order.paymentStatus))),
            SizedBox(
                width: rowParams.defualtWidth,
                child: Center(
                  child: Text(order.createdDate.toIso8601String().substring(0, 10)),
                ),),
            SizedBox(
                width: rowParams.defualtWidth,
                child:Center(child: Text(order.orderStatus))),
          ];
        },
          actionBuilder: (context, actionParams) {
          return IconButton(
            icon: const Icon(Icons.more_vert),
            onPressed: () {
              // Do something exciting!
              print('Action on row ${actionParams.rowIndex}, item ${actionParams.index}');
            },
          );
        },
        actions: [
          {"label": "view"}
        ],
        rowDecorationBuilder: (index, isHovered) => rowDecorationBuilder(context, index, isHovered),
         rowBuilder: (context, index, row, isHover) => rowBuilder(context, index, row, isHover,_orders.length),
        onRowTap: (index) {
          print('Row $index tapped!');
        },
        // Add more customizations here!
      ),
    );
  }
}
This example shows you how to:
  1. Define your data model (Order).
  2. Generate fake data (_generateFakeOrders).
  3. Use ValueNotifier for loading states.
  4. Configure:
    • headerBuilder
    • rowElementsBuilder
    • actionBuilder
    • rowDecorationBuilder
  5. Handle row taps with onRowTap.
  6. Display an empty state with onEmptyState.
  7. Add animation using rowBuilder

Additional Information

Where to find more information: Check out the /example folder for more comprehensive examples, including how to handle different data types, implement sorting, and more!

Contribute to the package: We welcome contributions! Fork the repo, make your changes, and submit a pull request. Bonus points for adding tests! 🧪

File issues: Found a bug? Have a feature request? File an issue on GitHub. We'll do our best to respond promptly (unless we're busy building more awesome widgets).

Package Authors: This package was lovingly crafted by [NIMR SAWAFTA] with the help of many cups of coffee ☕ and late-night coding sessions.

License: MIT - do what you want! (But attribution is appreciated 😉)

So, what are you waiting for? Go forth and create amazing tables! 🎉

所属分类

源码仓库

使用此插件的项目

暂无相关数据。