Coder Social home page Coder Social logo

flutter_section_table_view's Introduction

flutter_section_table_view

  • A iOS like table view including section, row, section header and divider
  • Support both Android and iOS
  • Support drop-down refresh and pull-up load (based on pull_to_refresh)
  • you can animate/jump to specific index path
  • you can know which index path it scrolled to, when scrolling

Usage

minimal

class MinList extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Min List'),
      ),
      body: SafeArea(
        child: SectionTableView(
          sectionCount: 7,
          numOfRowInSection: (section) {
            return section == 0 ? 3 : 4;
          },
          cellAtIndexPath: (section, row) {
            return Container(
              height: 44.0,
              child: Center(
                child: Text('Cell $section $row'),
              ),
            );
          },
          headerInSection: (section) {
            return Container(
              height: 25.0,
              color: Colors.grey,
              child: Text('Header $section'),
            );
          },
          divider: Container(
            color: Colors.green,
            height: 1.0,
          ),
        ),
      ),
    );
  }
}

Section List which can scroll to specific index path

class SectionList extends StatelessWidget {
  final controller = SectionTableController(sectionTableViewScrollTo: (section, row, isScrollDown) {
    print('received scroll to $section $row scrollDown:$isScrollDown');
  });

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Section List'),
      ),
      floatingActionButton: FloatingActionButton(
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: <Widget>[Text('Scroll'), Icon(Icons.keyboard_arrow_down)],
          ),
          onPressed: () {
            controller.animateTo(2, -1).then((complete) {
              print('animated $complete');
            });
          }),
      body: SafeArea(
        child: SectionTableView(
          sectionCount: 7,
          numOfRowInSection: (section) {
            return section == 0 ? 3 : 4;
          },
          cellAtIndexPath: (section, row) {
            return Container(
              height: 44.0,
              child: Center(
                child: Text('Cell $section $row'),
              ),
            );
          },
          headerInSection: (section) {
            return Container(
              height: 25.0,
              color: Colors.grey,
              child: Text('Header $section'),
            );
          },
          divider: Container(
            color: Colors.green,
            height: 1.0,
          ),
          controller: controller, //SectionTableController
          sectionHeaderHeight: (section) => 25.0,
          dividerHeight: () => 1.0,
          cellHeightAtIndexPath: (section, row) => 44.0,
        ),
      ),
    );
  }
}

Full function list which can pull up/down refresh

class FullList extends StatefulWidget {
  @override
  _FullListState createState() => _FullListState();
}

class _FullListState extends State<FullList> {
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
  }

  @override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
  }

  int sectionCount = 9;
  final controller = SectionTableController(sectionTableViewScrollTo: (section, row, isScrollDown) {
    print('received scroll to $section $row scrollDown:$isScrollDown');
  });
  final refreshController = RefreshController();

  Indicator refreshHeaderBuilder(BuildContext context, int mode) {
    return ClassicIndicator(
      mode: mode,
      releaseText: '释放以刷新',
      refreshingText: '刷新中...',
      completeText: '完成',
      failedText: '失败',
      idleText: '下拉以刷新',
      noDataText: '',
    );
  }

  Indicator refreshFooterBuilder(BuildContext context, int mode) {
    return ClassicIndicator(
      mode: mode,
      releaseText: '释放以加载',
      refreshingText: '加载中...',
      completeText: '加载完成',
      failedText: '加载失败',
      idleText: '上拉以加载',
      noDataText: '',
      idleIcon: const Icon(Icons.arrow_upward, color: Colors.grey),
      releaseIcon: const Icon(Icons.arrow_downward, color: Colors.grey),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Full List'),
      ),
      floatingActionButton: FloatingActionButton(
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: <Widget>[Text('Scroll'), Icon(Icons.keyboard_arrow_down)],
          ),
          onPressed: () {
            controller.animateTo(2, -1).then((complete) {
              print('animated $complete');
            });
          }),
      body: SafeArea(
        child: SectionTableView(
          refreshHeaderBuilder: refreshHeaderBuilder,
          refreshFooterBuilder: refreshFooterBuilder,
          enablePullDown: true,
          enablePullUp: true,
          onRefresh: (up) {
            print('on refresh $up');

            Future.delayed(const Duration(milliseconds: 2009)).then((val) {
              refreshController.sendBack(up, RefreshStatus.completed);
              setState(() {
                if (up) {
                  sectionCount = 5;
                } else {
                  sectionCount++;
                }
              });
            });
          },
          refreshController: refreshController,
          sectionCount: sectionCount,
          numOfRowInSection: (section) {
            return section == 0 ? 3 : 4;
          },
          cellAtIndexPath: (section, row) {
            return Container(
              height: 44.0,
              child: Center(
                child: Text('Cell $section $row'),
              ),
            );
          },
          headerInSection: (section) {
            return Container(
              height: 25.0,
              color: Colors.grey,
              child: Text('Header $section'),
            );
          },
          divider: Container(
            color: Colors.green,
            height: 1.0,
          ),
          controller: controller, //SectionTableController
          sectionHeaderHeight: (section) => 25.0,
          dividerHeight: () => 1.0,
          cellHeightAtIndexPath: (section, row) => 44.0,
        ),
      ),
    );
  }
}

iOS android

Getting Started

For help getting started with Flutter, view our online documentation.

For help on editing package code, view the documentation.

flutter_section_table_view's People

Contributors

numen31337 avatar realank avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

flutter_section_table_view's Issues

Question: Many cell in same Row it's possible?

Congratulations on your package. I needed a package with this one to rewrite a native app.

In one of my app I need to have several Widgets per line in each session, like the IOS UICollection.

See the image below. I can do this with your package. Do you have any suggestions?

image

配置了ScrollController之后滚动触发报错

原因是preIndexOffset的默认值是null,不能用于在package:flutter_section_table_view/flutter_section_table_view.dart:294:27 这个地方进行比较。

下面是日志
`flutter: The following NoSuchMethodError was thrown while dispatching notifications for ScrollController:
flutter: The method '>' was called on null.
flutter: Receiver: null
flutter: Tried calling: >(271.3333435058594)
flutter:
flutter: When the exception was thrown, this was the stack:
flutter: #0 Object.noSuchMethod (dart:core-patch/object_patch.dart:50:5)
flutter: #1 double.< (dart:core-patch/double.dart:82:18)
flutter: #2 _SectionTableViewState.calculateIndexPathAndOffset. (package:flutter_section_table_view/flutter_section_table_view.dart:294:27)
flutter: #3 ChangeNotifier.notifyListeners (package:flutter/src/foundation/change_notifier.dart:206:21)
flutter: #4 ChangeNotifier.notifyListeners (package:flutter/src/foundation/change_notifier.dart:206:21)
flutter: #5 ScrollPosition.notifyListeners (package:flutter/src/widgets/scroll_position.dart:701:11)
flutter: #6 ScrollPosition.setPixels (package:flutter/src/widgets/scroll_position.dart:218:9)
flutter: #7 ScrollPositionWithSingleContext.setPixels (package:flutter/src/widgets/scroll_position_with_single_context.dart:83:18)
flutter: #8 ScrollPositionWithSingleContext.applyUserOffset (package:flutter/src/widgets/scroll_position_with_single_context.dart:126:5)
flutter: #9 ScrollDragController.update (package:flutter/src/widgets/scroll_activity.dart:372:14)
flutter: #10 ScrollableState._handleDragUpdate (package:flutter/src/widgets/scrollable.dart:498:12)
flutter: #11 DragGestureRecognizer._checkUpdate. (package:flutter/src/gestures/monodrag.dart:383:46)
flutter: #12 GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:182:24)
flutter: #13 DragGestureRecognizer._checkUpdate (package:flutter/src/gestures/monodrag.dart:383:7)
flutter: #14 DragGestureRecognizer.handleEvent (package:flutter/src/gestures/monodrag.dart:253:9)
flutter: #15 PointerRouter._dispatch (package:flutter/src/gestures/pointer_router.dart:75:13)
flutter: #16 PointerRouter.route (package:flutter/src/gestures/pointer_router.dart:102:11)
flutter: #17 _WidgetsFlutterBinding&BindingBase&GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:218:19)
flutter: #18 _WidgetsFlutterBinding&BindingBase&GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:198:22)
flutter: #19 _WidgetsFlutterBinding&BindingBase&GestureBinding._handlePointerEvent (package:flutter/src/gestures/binding.dart:156:7)
flutter: #20 _WidgetsFlutterBinding&BindingBase&GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:102:7)
flutter: #21 _WidgetsFlutterBinding&BindingBase&GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:86:7)
flutter: #25 _invoke1 (dart:ui/hooks.dart:250:10)
flutter: #26 _dispatchPointerDataPacket (dart:ui/hooks.dart:159:5)
flutter: (elided 3 frames from package dart:async)
flutter:
flutter: The ScrollController sending notification was:
flutter: ScrollController#a8730(one client, offset 271.3)
flutter: ════════════════════════════════════════════════════════════════════════════════════════════════════
flutter: Another exception was thrown: NoSuchMethodError: The method '>' was called on null.

flutter: Another exception was thrown: NoSuchMethodError: The method '>' was called on null.

flutter: Another exception was thrown: NoSuchMethodError: The method '>' was called on null.

flutter: Another exception was thrown: NoSuchMethodError: The method '>' was called on null.
`

How to use onTap of ListView?

Thanks for creating flutter_section_table_view.
But I want to know how to use onTap of ListView in flutter_section_table_view?

Getting the index of the first visible section

I don't know if I can relate to this as an issue, but I really need to have this feature as I tried many solutions, I have a list and need to scroll to a specific section when I navigate to the list page, I got this done using this package which was so easy and amazing, but now I need to change the app bar title as I scroll down or up to match the first visible section title in my list! I tried to wrap my section table view inside a NotificationListener, and measured the offsets of scrolling manually, which is not only great cause my list items aren't same height... but I get a value, when I write setState() to update the appbarIndex value so it renders the title in my appbar it breaks! I can't scroll anymore until I remove setState(), do you have any solution for this?

thanks in advance!

有留白怎么隐藏呢

隐藏appBar的情况下 ,SectionTableView作为子widget,SectionTableView的头部一直有留白,要怎么隐藏掉呢

能和和tab联动呢

就是每个section滚动到顶的时候,tab选中的相应的标签,类似于淘宝的商品详情页效果

Issue with the scrolling performance

In case of using animateTo or even jumpTo function to scroll the table to some target area, every single cell on the way will be rendered.
This feature is completely unusable when using for jumping to some area of a long list (500 items and more) as it will render every single cell on the way to the target. I would expect at least jumpTo function to avoid rendering every single cell on the way.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.