A Flutter grid view which supports waterfall flow layout.

Overview

waterfall_flow

pub package GitHub stars GitHub forks GitHub license GitHub issues flutter-candies

A Flutter grid view easy to build waterfall flow layout quickly.

Web demo for WaterfallFlow

Language: English | 中文简体

Use

  • add library to your pubspec.yaml
dependencies:
  waterfall_flow: any
  • import library in dart file
  import 'package:waterfall_flow/waterfall_flow.dart';

Easy to use

img img
img img

you can define waterfall flow layout within SliverWaterfallFlowDelegate.

  • SliverWaterfallFlowDelegateWithFixedCrossAxisCount
parameter description default
crossAxisCount The number of children in the cross axis. required
  • SliverWaterfallFlowDelegateWithMaxCrossAxisExtent
parameter description default
maxCrossAxisExtent The maximum extent of tiles in the cross axis. required
  • SliverWaterfallFlowDelegate
parameter description default
mainAxisSpacing The number of logical pixels between each child along the main axis. 0.0
crossAxisSpacing The number of logical pixels between each child along the cross axis. 0.0
collectGarbage Call when collect garbage, return indexs to collect -
lastChildLayoutTypeBuilder The builder to get layout type of last child ,Notice: it should only for last child -
viewportBuilder The builder to get indexs in viewport -
closeToTrailing Whether make layout close to trailing false
            WaterfallFlow.builder(
              //cacheExtent: 0.0,
              padding: EdgeInsets.all(5.0),
              gridDelegate: SliverWaterfallFlowDelegateWithFixedCrossAxisCount(
                  crossAxisCount: 2,
                  crossAxisSpacing: 5.0,
                  mainAxisSpacing: 5.0,
                  /// follow max child trailing layout offset and layout with full cross axis extend
                  /// last child as loadmore item/no more item in [GridView] and [WaterfallFlow]
                  /// with full cross axis extend
                  //  LastChildLayoutType.fullCrossAxisExtend,

                  /// as foot at trailing and layout with full cross axis extend
                  /// show no more item at trailing when children are not full of viewport
                  /// if children is full of viewport, it's the same as fullCrossAxisExtend
                  //  LastChildLayoutType.foot,
                  lastChildLayoutTypeBuilder: (index) => index == _list.length
                      ? LastChildLayoutType.foot
                      : LastChildLayoutType.none,
                  ),

CollectGarbage

track the indexes are collect, you can collect garbage at that monment(for example Image cache)

more detail

        WaterfallFlow.builder(
            gridDelegate: SliverWaterfallFlowDelegateWithFixedCrossAxisCount(
                collectGarbage: (List<int> garbages) {
                  ///collectGarbage
                  garbages.forEach((index) {
                    final provider = ExtendedNetworkImageProvider(
                      _list[index].imageUrl,
                    );
                    provider.evict();
                  });
                },
              ),

ViewportBuilder

track the indexes go into the viewport, it's not include cache extent.

        WaterfallFlow.builder(
            gridDelegate: SliverWaterfallFlowDelegateWithFixedCrossAxisCount(
                viewportBuilder: (int firstIndex, int lastIndex) {
                print("viewport : [$firstIndex,$lastIndex]");
                }),

LastChildLayoutTypeBuilder

build lastChild as special child in the case that it is loadmore/no more item.

        enum LastChildLayoutType {
        /// as default child
        none,

        /// follow max child trailing layout offset and layout with full cross axis extend
        /// last child as loadmore item/no more item in [ExtendedGridView] and [WaterfallFlow]
        /// with full cross axis extend
        fullCrossAxisExtend,

        /// as foot at trailing and layout with full cross axis extend
        /// show no more item at trailing when children are not full of viewport
        /// if children is full of viewport, it's the same as fullCrossAxisExtend
        foot,
        }

      WaterfallFlow.builder(
        gridDelegate: SliverWaterfallFlowDelegateWithFixedCrossAxisCount(
            lastChildLayoutTypeBuilder: (index) => index == length
                ? LastChildLayoutType.foot
                : LastChildLayoutType.none,
            ),

CloseToTrailing

when reverse property of List is true, layout is as following. it likes chat list, and new session will insert to zero index. but it's not right when items are not full of viewport.

     trailing
-----------------
|               |
|               |
|     item2     |
|     item1     |
|     item0     |
-----------------
     leading

to solve it, you could set closeToTrailing to true, layout is as following. support [ExtendedGridView],[ExtendedList],[WaterfallFlow]. and it also works when reverse is flase, layout will close to trailing.

     trailing
-----------------
|     item2     |
|     item1     |
|     item0     |
|               |
|               |
-----------------
     leading
      WaterfallFlow.builder(
        reverse: true,
        gridDelegate: SliverWaterfallFlowDelegateWithFixedCrossAxisCount(closeToTrailing: true),
Comments
  • 报错The getter 'parentData' was called on null

    报错The getter 'parentData' was called on null

    不知道什么原因引起的 image

    导致第一行最后一个item下陷一个位置 IMG_20200602_072748

    日志:

    The following NoSuchMethodError was thrown during performLayout():
    The getter 'parentData' was called on null.
    Receiver: null
    Tried calling: parentData
    
    The relevant error-causing widget was: 
      LoadingMoreSliverList<GoodsItem> file:///C:/Users/lvccz/AndroidStudioProjects/demo1/lib/pages/index_page/index_home.dart:149:12
    When the exception was thrown, this was the stack: 
    #0      Object.noSuchMethod (dart:core-patch/object_patch.dart:53:5)
    #1      CrossAxisItems.insertLeading (package:waterfall_flow/src/rendering/sliver_waterfall_flow.dart:569:48)
    #2      RenderSliverWaterfallFlow.performLayout (package:waterfall_flow/src/rendering/sliver_waterfall_flow.dart:199:28)
    #3      RenderObject.layout (package:flutter/src/rendering/object.dart:1724:7)
    #4      RenderSliverEdgeInsetsPadding.performLayout (package:flutter/src/rendering/sliver_padding.dart:134:11)
    ...
    The following RenderObject was being processed when the exception was fired: RenderSliverWaterfallFlow#aacb0 relayoutBoundary=up2 NEEDS-LAYOUT NEEDS-COMPOSITING-BITS-UPDATE
    ...  needs compositing
    ...  parentData: paintOffset=Offset(13.6, 0.0) (can use size)
    ...  constraints: SliverConstraints(AxisDirection.down, GrowthDirection.forward, ScrollDirection.forward, scrollOffset: 522.5, remainingPaintExtent: 768.9, crossAxisExtent: 365.5, crossAxisDirection: AxisDirection.right, viewportMainAxisExtent: 768.9, remainingCacheExtent: 1268.9 cacheOrigin: -250.0 )
    ...  geometry: SliverGeometry(scrollExtent: 8346.8, paintExtent: 768.9, maxPaintExtent: 8346.8, hasVisualOverflow: true, cacheExtent: 1268.9)
    ...    scrollExtent: 8346.8
    ...    paintExtent: 768.9
    ...    maxPaintExtent: 8346.8
    ...    hasVisualOverflow: true
    ...    cacheExtent: 1268.9
    ...  currently live children: 0 to 9
    RenderObject: RenderSliverWaterfallFlow#aacb0 relayoutBoundary=up2 NEEDS-LAYOUT NEEDS-COMPOSITING-BITS-UPDATE
      needs compositing
      parentData: paintOffset=Offset(13.6, 0.0) (can use size)
      constraints: SliverConstraints(AxisDirection.down, GrowthDirection.forward, ScrollDirection.forward, scrollOffset: 522.5, remainingPaintExtent: 768.9, crossAxisExtent: 365.5, crossAxisDirection: AxisDirection.right, viewportMainAxisExtent: 768.9, remainingCacheExtent: 1268.9 cacheOrigin: -250.0 )
      geometry: SliverGeometry(scrollExtent: 8346.8, paintExtent: 768.9, maxPaintExtent: 8346.8, hasVisualOverflow: true, cacheExtent: 1268.9)
        scrollExtent: 8346.8
        paintExtent: 768.9
        maxPaintExtent: 8346.8
        hasVisualOverflow: true
        cacheExtent: 1268.9
      currently live children: 0 to 9
    ...  child with index 0: RenderIndexedSemantics#51a2e relayoutBoundary=up3 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
    ...    parentData: crossAxisIndex=0;crossAxisOffset=0.0;trailingLayoutOffset=316.77886977886976; index=0; layoutOffset=-16.9 (can use size)
    ...    constraints: BoxConstraints(w=175.7, 0.0<=h<=Infinity)
    ...    semantic boundary
    ...    size: Size(175.7, 333.7)
    ...    index: 0
    ...    child: RenderRepaintBoundary#ab28e relayoutBoundary=up4 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
    ...      needs compositing
    ...      parentData: <none> (can use size)
    ...      constraints: BoxConstraints(w=175.7, 0.0<=h<=Infinity)
    ...      size: Size(175.7, 333.7)
    ...      usefulness ratio: no metrics collected yet (never painted)
    ...      child: RenderSemanticsAnnotations#b7eb5 relayoutBoundary=up5 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
    ...        parentData: <none> (can use size)
    ...        constraints: BoxConstraints(w=175.7, 0.0<=h<=Infinity)
    ...        size: Size(175.7, 333.7)
    ...        child: RenderMouseRegion#9e5e6 relayoutBoundary=up6 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
    ...          parentData: <none> (can use size)
    ...          constraints: BoxConstraints(w=175.7, 0.0<=h<=Infinity)
    ...          size: Size(175.7, 333.7)
    ...          listeners: enter, exit
    ...  child with index 1: RenderIndexedSemantics#ef0b5 relayoutBoundary=up3 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
    ...    parentData: crossAxisIndex=1;crossAxisOffset=189.77886977886982;trailingLayoutOffset=315.8550368550368; index=1; layoutOffset=-16.9 (can use size)
    ...    constraints: BoxConstraints(w=175.7, 0.0<=h<=Infinity)
    ...    semantic boundary
    ...    size: Size(175.7, 332.8)
    ...    index: 1
    ...    child: RenderRepaintBoundary#fefb4 relayoutBoundary=up4 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
    ...      needs compositing
    ...      parentData: <none> (can use size)
    ...      constraints: BoxConstraints(w=175.7, 0.0<=h<=Infinity)
    ...      size: Size(175.7, 332.8)
    ...      usefulness ratio: no metrics collected yet (never painted)
    ...      child: RenderSemanticsAnnotations#b7613 relayoutBoundary=up5 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
    ...        parentData: <none> (can use size)
    ...        constraints: BoxConstraints(w=175.7, 0.0<=h<=Infinity)
    ...        size: Size(175.7, 332.8)
    ...        child: RenderMouseRegion#93d8d relayoutBoundary=up6 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
    ...          parentData: <none> (can use size)
    ...          constraints: BoxConstraints(w=175.7, 0.0<=h<=Infinity)
    ...          size: Size(175.7, 332.8)
    ...          listeners: enter, exit
    ...  child with index 2: RenderIndexedSemantics#6341c relayoutBoundary=up3
    ...    needs compositing
    ...    parentData: crossAxisIndex=1;crossAxisOffset=189.77886977886982;trailingLayoutOffset=646.2702702702702; index=2; layoutOffset=329.5 (can use size)
    ...    constraints: BoxConstraints(w=175.7, 0.0<=h<=Infinity)
    ...    semantic boundary
    ...    size: Size(175.7, 316.8)
    ...    index: 2
    ...    child: RenderRepaintBoundary#4ffd8 relayoutBoundary=up4
    ...      needs compositing
    ...      parentData: <none> (can use size)
    ...      constraints: BoxConstraints(w=175.7, 0.0<=h<=Infinity)
    ...      layer: OffsetLayer#efcd0
    ...        offset: Offset(203.4, -284.6)
    ...      size: Size(175.7, 316.8)
    ...      metrics: 99.6% useful (2 bad vs 475 good)
    ...      diagnosis: this is an outstandingly useful repaint boundary and should definitely be kept
    ...      child: RenderSemanticsAnnotations#ff3d2 relayoutBoundary=up5
    ...        parentData: <none> (can use size)
    ...        constraints: BoxConstraints(w=175.7, 0.0<=h<=Infinity)
    ...        size: Size(175.7, 316.8)
    ...        child: RenderMouseRegion#6c37d relayoutBoundary=up6
    ...          parentData: <none> (can use size)
    ...          constraints: BoxConstraints(w=175.7, 0.0<=h<=Infinity)
    ...          size: Size(175.7, 316.8)
    ...          listeners: enter, exit
    ...  child with index 3: RenderIndexedSemantics#00e2f relayoutBoundary=up3
    ...    needs compositing
    ...    parentData: crossAxisIndex=0;crossAxisOffset=0.0;trailingLayoutOffset=647.1941031941031; index=3; layoutOffset=330.4 (can use size)
    ...    constraints: BoxConstraints(w=175.7, 0.0<=h<=Infinity)
    ...    semantic boundary
    ...    size: Size(175.7, 316.8)
    ...    index: 3
    ...    child: RenderRepaintBoundary#dd151 relayoutBoundary=up4
    ...      needs compositing
    ...      parentData: <none> (can use size)
    ...      constraints: BoxConstraints(w=175.7, 0.0<=h<=Infinity)
    ...      layer: OffsetLayer#18673
    ...        offset: Offset(13.6, -283.7)
    ...      size: Size(175.7, 316.8)
    ...      metrics: 99.6% useful (2 bad vs 474 good)
    ...      diagnosis: this is an outstandingly useful repaint boundary and should definitely be kept
    ...      child: RenderSemanticsAnnotations#03a6d relayoutBoundary=up5
    ...        parentData: <none> (can use size)
    ...        constraints: BoxConstraints(w=175.7, 0.0<=h<=Infinity)
    ...        size: Size(175.7, 316.8)
    ...        child: RenderMouseRegion#694cc relayoutBoundary=up6
    ...          parentData: <none> (can use size)
    ...          constraints: BoxConstraints(w=175.7, 0.0<=h<=Infinity)
    ...          size: Size(175.7, 316.8)
    ...          listeners: enter, exit
    ...  child with index 4: RenderIndexedSemantics#e61b8 relayoutBoundary=up3
    ...    needs compositing
    ...    parentData: crossAxisIndex=1;crossAxisOffset=189.77886977886982;trailingLayoutOffset=976.6855036855036; index=4; layoutOffset=659.9 (can use size)
    ...    constraints: BoxConstraints(w=175.7, 0.0<=h<=Infinity)
    ...    semantic boundary
    ...    size: Size(175.7, 316.8)
    ...    index: 4
    ...    child: RenderRepaintBoundary#680a7 relayoutBoundary=up4
    ...      needs compositing
    ...      parentData: <none> (can use size)
    ...      constraints: BoxConstraints(w=175.7, 0.0<=h<=Infinity)
    ...      layer: OffsetLayer#acd76
    ...        offset: Offset(203.4, 45.8)
    ...      size: Size(175.7, 316.8)
    ...      metrics: 98.3% useful (3 bad vs 177 good)
    ...      diagnosis: this is an outstandingly useful repaint boundary and should definitely be kept
    ...      child: RenderSemanticsAnnotations#38e2f relayoutBoundary=up5
    ...        parentData: <none> (can use size)
    ...        constraints: BoxConstraints(w=175.7, 0.0<=h<=Infinity)
    ...        size: Size(175.7, 316.8)
    ...        child: RenderMouseRegion#2fe33 relayoutBoundary=up6
    ...          parentData: <none> (can use size)
    ...          constraints: BoxConstraints(w=175.7, 0.0<=h<=Infinity)
    ...          size: Size(175.7, 316.8)
    ...          listeners: enter, exit
    ...  child with index 5: RenderIndexedSemantics#51375 relayoutBoundary=up3
    ...    needs compositing
    ...    parentData: crossAxisIndex=0;crossAxisOffset=0.0;trailingLayoutOffset=977.6093366093365; index=5; layoutOffset=660.8 (can use size)
    ...    constraints: BoxConstraints(w=175.7, 0.0<=h<=Infinity)
    ...    semantic boundary
    ...    size: Size(175.7, 316.8)
    ...    index: 5
    ...    child: RenderRepaintBoundary#56717 relayoutBoundary=up4
    ...      needs compositing
    ...      parentData: <none> (can use size)
    ...      constraints: BoxConstraints(w=175.7, 0.0<=h<=Infinity)
    ...      layer: OffsetLayer#3c9b2
    ...        offset: Offset(13.6, 46.7)
    ...      size: Size(175.7, 316.8)
    ...      metrics: 98.3% useful (3 bad vs 175 good)
    ...      diagnosis: this is an outstandingly useful repaint boundary and should definitely be kept
    ...      child: RenderSemanticsAnnotations#28fa0 relayoutBoundary=up5
    ...        parentData: <none> (can use size)
    ...        constraints: BoxConstraints(w=175.7, 0.0<=h<=Infinity)
    ...        size: Size(175.7, 316.8)
    ...        child: RenderMouseRegion#bf370 relayoutBoundary=up6
    ...          parentData: <none> (can use size)
    ...          constraints: BoxConstraints(w=175.7, 0.0<=h<=Infinity)
    ...          size: Size(175.7, 316.8)
    ...          listeners: enter, exit
    ...  child with index 6: RenderIndexedSemantics#aa09b relayoutBoundary=up3
    ...    needs compositing
    ...    parentData: crossAxisIndex=1;crossAxisOffset=189.77886977886982;trailingLayoutOffset=1307.100737100737; index=6; layoutOffset=990.3 (can use size)
    ...    constraints: BoxConstraints(w=175.7, 0.0<=h<=Infinity)
    ...    semantic boundary
    ...    size: Size(175.7, 316.8)
    ...    index: 6
    ...    child: RenderRepaintBoundary#d6555 relayoutBoundary=up4
    ...      needs compositing
    ...      parentData: <none> (can use size)
    ...      constraints: BoxConstraints(w=175.7, 0.0<=h<=Infinity)
    ...      layer: OffsetLayer#8273a
    ...        offset: Offset(203.4, 376.2)
    ...      size: Size(175.7, 316.8)
    ...      metrics: 98.7% useful (1 bad vs 75 good)
    ...      diagnosis: this is an outstandingly useful repaint boundary and should definitely be kept
    ...      child: RenderSemanticsAnnotations#fb511 relayoutBoundary=up5
    ...        parentData: <none> (can use size)
    ...        constraints: BoxConstraints(w=175.7, 0.0<=h<=Infinity)
    ...        size: Size(175.7, 316.8)
    ...        child: RenderMouseRegion#85d40 relayoutBoundary=up6
    ...          parentData: <none> (can use size)
    ...          constraints: BoxConstraints(w=175.7, 0.0<=h<=Infinity)
    ...          size: Size(175.7, 316.8)
    ...          listeners: enter, exit
    ...  child with index 7: RenderIndexedSemantics#4c1ee relayoutBoundary=up3
    ...    needs compositing
    ...    parentData: crossAxisIndex=0;crossAxisOffset=0.0;trailingLayoutOffset=1308.02457002457; index=7; layoutOffset=991.2 (can use size)
    ...    constraints: BoxConstraints(w=175.7, 0.0<=h<=Infinity)
    ...    semantic boundary
    ...    size: Size(175.7, 316.8)
    ...    index: 7
    ...    child: RenderRepaintBoundary#6734c relayoutBoundary=up4
    ...      needs compositing
    ...      parentData: <none> (can use size)
    ...      constraints: BoxConstraints(w=175.7, 0.0<=h<=Infinity)
    ...      layer: OffsetLayer#a8f86
    ...        offset: Offset(13.6, 377.1)
    ...      size: Size(175.7, 316.8)
    ...      metrics: 98.7% useful (1 bad vs 75 good)
    ...      diagnosis: this is an outstandingly useful repaint boundary and should definitely be kept
    ...      child: RenderSemanticsAnnotations#a757a relayoutBoundary=up5
    ...        parentData: <none> (can use size)
    ...        constraints: BoxConstraints(w=175.7, 0.0<=h<=Infinity)
    ...        size: Size(175.7, 316.8)
    ...        child: RenderMouseRegion#6b9e8 relayoutBoundary=up6
    ...          parentData: <none> (can use size)
    ...          constraints: BoxConstraints(w=175.7, 0.0<=h<=Infinity)
    ...          size: Size(175.7, 316.8)
    ...          listeners: enter, exit
    ...  child with index 8: RenderIndexedSemantics#10f69 relayoutBoundary=up3
    ...    needs compositing
    ...    parentData: crossAxisIndex=1;crossAxisOffset=189.77886977886982;trailingLayoutOffset=1636.5921375921375; index=8; layoutOffset=1320.7 (can use size)
    ...    constraints: BoxConstraints(w=175.7, 0.0<=h<=Infinity)
    ...    semantic boundary
    ...    size: Size(175.7, 315.9)
    ...    index: 8
    ...    child: RenderRepaintBoundary#a713a relayoutBoundary=up4
    ...      needs compositing
    ...      parentData: <none> (can use size)
    ...      constraints: BoxConstraints(w=175.7, 0.0<=h<=Infinity)
    ...      layer: OffsetLayer#ac017
    ...        offset: Offset(203.4, 706.6)
    ...      size: Size(175.7, 315.9)
    ...      metrics: 80.0% useful (1 bad vs 4 good)
    ...      diagnosis: this is a useful repaint boundary and should be kept
    ...      child: RenderSemanticsAnnotations#d0c4e relayoutBoundary=up5
    ...        parentData: <none> (can use size)
    ...        constraints: BoxConstraints(w=175.7, 0.0<=h<=Infinity)
    ...        size: Size(175.7, 315.9)
    ...        child: RenderMouseRegion#a5fb3 relayoutBoundary=up6
    ...          parentData: <none> (can use size)
    ...          constraints: BoxConstraints(w=175.7, 0.0<=h<=Infinity)
    ...          size: Size(175.7, 315.9)
    ...          listeners: enter, exit
    ...  child with index 9: RenderIndexedSemantics#27f00 relayoutBoundary=up3
    ...    needs compositing
    ...    parentData: crossAxisIndex=0;crossAxisOffset=0.0;trailingLayoutOffset=1638.4398034398037; index=9; layoutOffset=1321.7 (can use size)
    ...    constraints: BoxConstraints(w=175.7, 0.0<=h<=Infinity)
    ...    semantic boundary
    ...    size: Size(175.7, 316.8)
    ...    index: 9
    ...    child: RenderRepaintBoundary#de1e4 relayoutBoundary=up4
    ...      needs compositing
    ...      parentData: <none> (can use size)
    ...      constraints: BoxConstraints(w=175.7, 0.0<=h<=Infinity)
    ...      layer: OffsetLayer#b5394
    ...        offset: Offset(13.6, 707.6)
    ...      size: Size(175.7, 316.8)
    ...      metrics: 80.0% useful (1 bad vs 4 good)
    ...      diagnosis: this is a useful repaint boundary and should be kept
    ...      child: RenderSemanticsAnnotations#8b50f relayoutBoundary=up5
    ...        parentData: <none> (can use size)
    ...        constraints: BoxConstraints(w=175.7, 0.0<=h<=Infinity)
    ...        size: Size(175.7, 316.8)
    ...        child: RenderMouseRegion#d3951 relayoutBoundary=up6
    ...          parentData: <none> (can use size)
    ...          constraints: BoxConstraints(w=175.7, 0.0<=h<=Infinity)
    ...          size: Size(175.7, 316.8)
    ...          listeners: enter, exit
    ════════════════════════════════════════════════════════════════════════════════════════════════════
    

    这是我的瀑布流wiget

    首页商品列表
      Widget _buildGoodsList() {
        return LoadingMoreSliverList(SliverListConfig<GoodsItem>(
          waterfallFlowDelegate: WaterfallFlowDelegate(
              crossAxisCount: 2, crossAxisSpacing: ScreenUtil().setHeight(50), mainAxisSpacing: ScreenUtil().setWidth(50)),
          itemBuilder: (context, item, index) {
            return WaterfallGoodsCard(item);
          },
          sourceList: indexGoodsRepository,
          padding: EdgeInsets.only(left: ScreenUtil().setWidth(50),right: ScreenUtil().setWidth(50)),
          lastChildLayoutType: LastChildLayoutType.foot,
          indicatorBuilder: (context, state) {
            return LoadingMoreListCostumIndicator(state, isSliver: true);
          },
    //      collectGarbage: (List<int> indexes) {
    //        indexes.forEach((index) {
    //          final item = indexGoodsRepository[index];
    //          final provider = ExtendedNetworkImageProvider(
    //            item.mainPic,
    //          );
    //          provider.evict();
    //        });
    //      },
        ));
      }
    
    opened by mdddj 16
  • 滚动冲突问题

    滚动冲突问题

    https://user-images.githubusercontent.com/19726808/125303985-cadfe080-e35f-11eb-94ce-f619168154c2.mp4

    大佬又遇到这个问题吗? 就是waterfall_flow和extended_nested_scroll_view一起使用再往上滚动的时候可能会出现无法滚上去(或者不流畅)的BUG

    stack overflow 
    opened by a27919478 12
  • scrolling a grid causes items to jump/re-shuffle

    scrolling a grid causes items to jump/re-shuffle

    Hi and thanks for this useful plugin.

    I am using the latest version as of 1st Nov 2020.,

    I notice that when I show a mixture of TEXT and images approx 60 cells (30 text cells and 30 image cells of different sizes) and scroll through - the cells appear to jump from 1 side to the next - I am testing this on a live device and get this issue on ANDROID and iOS. Its as if each scroll gesture forces the rebuild of the grid and then the cells get re-shuffled.

    I have tested using a normal gridView and do not get this behaviour.

    When the grid cells are the same size - the issue does not appear . When we have different sized IMAGES - we get the issue.

    The code I use is :

    
    WaterfallFlow.custom(
            padding: EdgeInsets.all(10),
            gridDelegate: SliverWaterfallFlowDelegateWithFixedCrossAxisCount(
                crossAxisCount: crossAxis, crossAxisSpacing: 5, mainAxisSpacing: 5),
            childrenDelegate: SliverChildBuilderDelegate((context, index) {
              var model = items[index].item2;
              var comp = items[index].item1;
    
              if (model.pictureUrl == null) {
               /// Display a TEXT widget
                return Container(height: 100, width: 100, child: comp);
              } else {
              /// Display an Image widget
                return comp;
              }
            }, childCount: items.length),
          );
    
    wontfix 
    opened by alexda12 11
  • 会偶现某一个item为空白的情况

    会偶现某一个item为空白的情况

    Flutter doctor info: [✓] Flutter (Channel unknown, v1.14.6, on Mac OS X 10.14.6 18G84, locale zh-Hans-CN) • Flutter version 1.14.6 at /Users/huangyumeng/flutter/sdk/flutter • Framework revision fabeb2a16f (4 months ago), 2020-01-28 07:56:51 -0800 • Engine revision c4229bfbba • Dart version 2.8.0 (build 2.8.0-dev.5.0 fc3af737c7)

    [!] Android toolchain - develop for Android devices (Android SDK version 29.0.0) • Android SDK at /Users/huangyumeng/Library/Android/sdk • Android NDK location not configured (optional; useful for native profiling support) • Platform android-29, build-tools 29.0.0 • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java • Java version OpenJDK Runtime Environment (build 1.8.0_212-release-1586-b4-5784211) ! Some Android licenses not accepted. To resolve this, run: flutter doctor --android-licenses

    [✓] Xcode - develop for iOS and macOS (Xcode 11.3.1) • Xcode at /Applications/Xcode.app/Contents/Developer • Xcode 11.3.1, Build version 11C504 • CocoaPods version 1.7.4

    [✓] Android Studio (version 3.6) • Android Studio at /Applications/Android Studio.app/Contents • Flutter plugin version 45.1.1 • Dart plugin version 192.8052 • Java version OpenJDK Runtime Environment (build 1.8.0_212-release-1586-b4-5784211)

    [✓] Connected device (1 available) • Redmi Note 8 Pro • 192.168.1.53:5555 • android-arm64 • Android 9 (API 28)

    ! Doctor found issues in 1 category.

    问题描述: 产品瀑布流默认为两列,会偶现第二列某一个区域为空白的情况,滑动后第二列整个消失,第一列的布局会挤在一起。布局代码:

    SliverPadding(
              padding: EdgeInsets.all(kMomentWaterfallCrossAxisSpacing),
              sliver: SliverWaterfallFlow(
                gridDelegate: SliverWaterfallFlowDelegate(
                    crossAxisCount: kMomentWaterfallCrossAxisCount,
                    mainAxisSpacing: kMomentWaterfallMainAxisSpacing,
                    crossAxisSpacing: kMomentWaterfallCrossAxisSpacing,
                    lastChildLayoutTypeBuilder: (idx) {
                      return idx == _model.momentList.length
                          ? LastChildLayoutType.foot
                          : LastChildLayoutType.none;
                    },
                    viewportBuilder: (firstIdx, lastIdx) {},
                    collectGarbage: (List<int> collectIdxList) {
                      for (int idx in collectIdxList) {
                        dataList[idx].evictImageInfo();
                      }
                    }),
                delegate: SliverChildBuilderDelegate((context, idx) {
                  return ItemTile();
                }, childCount: dataList.length),
              ),
            )
    

    Bugly报错: NoSuchMethodError: The getter 'parentData' was called on null. Receiver: null Tried calling: parentData

    #0 CrossAxisItems.insertLeading (package:waterfall_flow/src/rendering/sliver_waterfall_flow.dart:569)

    2 #1 RenderSliverWaterfallFlow.performLayout (package:waterfall_flow/src/rendering/sliver_waterfall_flow.dart:199) 3 #2 RenderObject.layout (package:flutter/src/rendering/object.dart:1767) 4 #3 RenderSliverEdgeInsetsPadding.performLayout (package:flutter/src/rendering/sliver_padding.dart:134) 5 #4 RenderSliverPadding.performLayout (package:flutter/src/rendering/sliver_padding.dart:373) 6 #5 RenderObject.layout (package:flutter/src/rendering/object.dart:1767) 7 #6 RenderViewportBase.layoutChildSequence (package:flutter/src/rendering/viewport.dart:452) 8 #7 RenderViewport._attemptLayout (package:flutter/src/rendering/viewport.dart:1444) 9 #8 RenderViewport.performLayout (package:flutter/src/rendering/viewport.dart:1353) 10 #9 RenderObject._layoutWithoutResize (package:flutter/src/rendering/object.dart:1628) 11 #10 PipelineOwner.flushLayout (package:flutter/src/rendering/object.dart:888) 12 #11 RendererBinding.drawFrame (package:flutter/src/rendering/binding.dart:401) 13 #12 WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:797) 14 #13 RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:283) 15 #14 SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1109) 16 #15 SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1048) 17 #16 SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:964) 18 #17 _rootRun (dart:async/zone.dart:1126) 19 #18 _CustomZone.run (dart:async/zone.dart:1023) 20 #19 _CustomZone.runGuarded (dart:async/zone.dart:925) 21 #20 _invoke (dart:ui/hooks.dart:260) 22 #21 _drawFrame (dart:ui/hooks.dart:218)

    opened by jaysonss 6
  • Getter 'minTrailingIndex' was called on null

    Getter 'minTrailingIndex' was called on null

    I have a SliverWaterfallFlowDelegateWithMaxCrossAxisExtent that creates a Waterfall grid of elements.

    When the device is rotated from a longer list (portrait) to a shorter list (landscape), the bottom of the list goes empty and you have to scroll up to reach to latest items.

    Reproduction:

    1. When the device starts is portrait, the list is rendered as a 1 item list in the cross axis
    2. Scroll to the bottom of list.
    3. Turn the device to landscape.

    Expected:

    • The list rebuilds having 2 items in the cross axis and showing the latest 2 or 1 items

    Happening:

    • The list rebuilds but the latest items are way up high in the list. You have to scroll up to get to the latest items.

    Also, this error is thrown:

    ════════ Exception caught by rendering library ═════════════════════════════════
    The following NoSuchMethodError was thrown during performLayout():
    The getter 'minTrailingIndex' was called on null.
    Receiver: null
    Tried calling: minTrailingIndex
    
    The relevant error-causing widget was
    SliverWaterfallFlow
     lib/…/components/flageventlistscaffold.dart
    When the exception was thrown, this was the stack
    #0      Object.noSuchMethod (dart:core-patch/object_patch.dart:51:5)
    #1      RenderSliverWaterfallFlow.performLayout
     package:waterfall_flow/…/rendering/sliver_waterfall_flow.dart
    #2      RenderObject.layout
     package:flutter/…/rendering/object.dart
    #3      RenderSliverEdgeInsetsPadding.performLayout
     package:flutter/…/rendering/sliver_padding.dart
    #4      RenderSliverPadding.performLayout
     package:flutter/…/rendering/sliver_padding.dart
    ...
    The following RenderObject was being processed when the exception was fired: RenderSliverWaterfallFlow#aa835 relayoutBoundary=up3 NEEDS-LAYOUT NEEDS-COMPOSITING-BITS-UPDATE
    RenderObject: RenderSliverWaterfallFlow#aa835 relayoutBoundary=up3 NEEDS-LAYOUT NEEDS-COMPOSITING-BITS-UPDATE
        needs compositing
        parentData: paintOffset=Offset(4.0, 0.0) (can use size)
        constraints: SliverConstraints(AxisDirection.down, GrowthDirection.forward, ScrollDirection.idle, scrollOffset: 6661.4, remainingPaintExtent: 334.0, crossAxisExtent: 742.0, crossAxisDirection: AxisDirection.right, viewportMainAxisExtent: 334.0, remainingCacheExtent: 834.0, cacheOrigin: -246.0)
        geometry: SliverGeometry(scrollExtent: 7229.4, paintExtent: 568.0, maxPaintExtent: 7229.4, hasVisualOverflow: true, cacheExtent: 814.0)
            scrollExtent: 7229.4
            paintExtent: 568.0
            maxPaintExtent: 7229.4
            hasVisualOverflow: true
            cacheExtent: 814.0
        currently live children: 0 to 17
        child with index 0: RenderIndexedSemantics#f7bcb relayoutBoundary=up4 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
            parentData: crossAxisIndex=0;crossAxisOffset=0.0;trailingLayoutOffset=407.9;indexes[0, 2, 4, 6, 8, 10, 12, 14]; index=0; layoutOffset=0.0 (can use size)
            constraints: BoxConstraints(w=368.5, 0.0<=h<=Infinity)
            semantic boundary
            size: Size(368.5, 407.9)
            index: 0
            child: RenderRepaintBoundary#69a4b relayoutBoundary=up5 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
                needs compositing
                parentData: <none> (can use size)
                constraints: BoxConstraints(w=368.5, 0.0<=h<=Infinity)
                size: Size(368.5, 407.9)
                usefulness ratio: no metrics collected yet (never painted)
                child: RenderPadding#8344e relayoutBoundary=up6 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
                    parentData: <none> (can use size)
                    constraints: BoxConstraints(w=368.5, 0.0<=h<=Infinity)
                    size: Size(368.5, 407.9)
                    padding: EdgeInsets.zero
                    textDirection: ltr
                    child: RenderSemanticsGestureHandler#2854f relayoutBoundary=up7 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
                        parentData: offset=Offset(0.0, 0.0) (can use size)
                        constraints: BoxConstraints(w=368.5, 0.0<=h<=Infinity)
                        size: Size(368.5, 407.9)
                        gestures: tap
    ...
    ════════════════════════════════════════════════════════════════════════════════
    
    
    bug 
    opened by jagomf 5
  • 关于列表 > TabBarView > WaterfallFlow的滚动异常

    关于列表 > TabBarView > WaterfallFlow的滚动异常

    • 表现一:TabBarView滚动时无法整体滚动
    • 表现二:如果把TabBarView的physics改为Never,则loadmore失效

    请问这种带TabBarView的瀑布流如何做到整体滚动并刷新正常啊?

    ###6# 录屏

    https://user-images.githubusercontent.com/20849786/171082914-9accec76-4b56-480b-ad72-a19f26e93bd2.mov

    最简实现

    import 'package:app/business/tuchong_item.dart';
    import 'package:extended_image/extended_image.dart';
    import 'package:flutter/material.dart';
    import 'package:loading_more_list/loading_more_list.dart';
    import 'dart:async';
    import 'dart:convert';
    import 'package:http/http.dart';
    import 'package:http_client_helper/http_client_helper.dart';
    import 'package:loading_more_list_library/loading_more_list_library.dart';
    
    class ListWithTab extends StatefulWidget {
      const ListWithTab({Key? key}) : super(key: key);
    
      @override
      _ListWithTabState createState() => _ListWithTabState();
    }
    
    class _ListWithTabState extends State<ListWithTab> with SingleTickerProviderStateMixin {
      final List<Widget> myTabs = [
        Tab(text: 'tab1'),
        Tab(text: 'tab2'),
        Tab(text: 'tab3'),
      ];
      TabController? _tabController;
      List<int> dataSource = List.generate(100, (index) => index);
      int pageNumber = 1;
    
      @override
      void initState() {
        _tabController = TabController(length: 3, vsync: this);
        super.initState();
      }
    
      @override
      void dispose() {
        _tabController?.dispose();
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: LoadingMoreCustomScrollView(
            slivers: [
              SliverToBoxAdapter(child: Container(height: 300, color: Colors.red)),
              buildTabs(context),
              buildTabBarView(),
            ],
          ),
        );
      }
    
      SliverFillRemaining buildTabBarView() {
        return SliverFillRemaining(
          child: TabBarView(
            controller: _tabController,
            children: myTabs
                .map((e) => LoadingMoreList<TuChongItem>(
                      ListConfig<TuChongItem>(
                        itemBuilder: buildWaterfallFlowItem,
                        sourceList: TuChongRepository(),
                        padding: const EdgeInsets.all(5.0),
                        primary: false,
                        extendedListDelegate: const SliverWaterfallFlowDelegateWithMaxCrossAxisExtent(
                          maxCrossAxisExtent: 300,
                          crossAxisSpacing: 5,
                          mainAxisSpacing: 5,
                        ),
                        lastChildLayoutType: LastChildLayoutType.foot,
                      ),
                    ))
                .toList(),
          ),
        );
      }
    
      SliverToBoxAdapter buildTabs(BuildContext context) {
        return SliverToBoxAdapter(
          child: Container(
            padding: EdgeInsets.symmetric(vertical: 20),
            child: Align(
              alignment: Alignment.centerLeft,
              child: TabBar(
                isScrollable: true,
                padding: EdgeInsets.zero,
                controller: _tabController,
                tabs: myTabs,
                indicatorWeight: 3,
                indicatorColor: Theme.of(context).primaryColor,
                indicatorSize: TabBarIndicatorSize.label,
                labelColor: Theme.of(context).primaryColor,
                overlayColor: MaterialStateProperty.all(Colors.transparent),
              ),
            ),
          ),
        );
      }
    
      Widget buildWaterfallFlowItem(BuildContext c, TuChongItem item, int index) {
        return AspectRatio(
          aspectRatio: item.imageSize.width / item.imageSize.height,
          child: ExtendedImage.network(
            item.imageUrl,
            shape: BoxShape.rectangle,
            //clearMemoryCacheWhenDispose: true,
            border: Border.all(color: Colors.grey.withOpacity(0.4), width: 1.0),
            borderRadius: const BorderRadius.all(
              Radius.circular(10.0),
            ),
            loadStateChanged: (ExtendedImageState value) {
              if (value.extendedImageLoadState == LoadState.loading) {
                Widget loadingWidget = Container(
                  alignment: Alignment.center,
                  color: Colors.grey.withOpacity(0.8),
                  child: CircularProgressIndicator(
                    strokeWidth: 2.0,
                    valueColor: AlwaysStoppedAnimation<Color>(Theme.of(c).primaryColor),
                  ),
                );
                return loadingWidget;
              } else if (value.extendedImageLoadState == LoadState.completed) {
                item.imageRawSize = Size(value.extendedImageInfo!.image.width.toDouble(), value.extendedImageInfo!.image.height.toDouble());
              }
              return null;
            },
          ),
        );
      }
    }
    
    class TuChongRepository extends LoadingMoreBase<TuChongItem> {
      TuChongRepository({this.maxLength = 40});
    
      int _pageIndex = 1;
      bool _hasMore = true;
      bool forceRefresh = false;
    
      @override
      bool get hasMore => (_hasMore && length < maxLength) || forceRefresh;
      final int maxLength;
    
      @override
      Future<bool> refresh([bool notifyStateChanged = false]) async {
        _hasMore = true;
        _pageIndex = 1;
        //force to refresh list when you don't want clear list before request
        //for the case, if your list already has 20 items.
        forceRefresh = !notifyStateChanged;
        final bool result = await super.refresh(notifyStateChanged);
        forceRefresh = false;
        return result;
      }
    
      @override
      Future<bool> loadData([bool isloadMoreAction = false]) async {
        String url = '';
        if (isEmpty) {
          url = 'https://api.tuchong.com/feed-app';
        } else {
          final int? lastPostId = this[length - 1].postId;
          url = 'https://api.tuchong.com/feed-app?post_id=$lastPostId&page=$_pageIndex&type=loadmore';
        }
        bool isSuccess = false;
        try {
          //to show loading more clearly, in your app,remove this
          // await Future.delayed(const Duration(milliseconds: 500));
          List<TuChongItem>? feedList;
          final Response result = await HttpClientHelper.get(Uri.parse(url)) as Response;
          feedList = TuChongSource.fromJson(json.decode(result.body) as Map<String, dynamic>).feedList;
    
          if (_pageIndex == 1) {
            clear();
          }
    
          for (final TuChongItem item in feedList!) {
            if (item.hasImage && !contains(item) && hasMore) {
              add(item);
            }
          }
          _hasMore = feedList.isNotEmpty;
          _pageIndex++;
          isSuccess = true;
        } catch (exception, stack) {
          isSuccess = false;
          print(exception);
          print(stack);
        }
        return isSuccess;
      }
    }
    
    stack overflow 
    opened by zmm2tysu 4
  • Extend LastChildLayoutType.fullCrossAxisExtent to leading item

    Extend LastChildLayoutType.fullCrossAxisExtent to leading item

    Hi, is there a way to extend fullCrossAxisExtent to the first item? Imagine a loader on the top of the grid or a button to reload content in case of errors ...

          lastChildLayoutTypeBuilder: (index) {
            if ((index == 0 && reloadRequired) ||
                ((index == 0 && isLoadingAll) ||
                    (index == dataLength - 1 && isLoadingMore)) ||
                (index == dataLength - 1 && !isLoadingAll)) {
              return LastChildLayoutType.fullCrossAxisExtent;
            }
    
            return LastChildLayoutType.none;
          },
    

    Thanks, Andrea

    opened by dna-f 4
  • No such method error

    No such method error

    I am getting a noSuchMethod error when running on a Simulator (iOS).

    The issue seems similar to what has been raised here :

    https://github.com/fluttercandies/waterfall_flow/issues/16

    because I dont always get this error. It happens on scrolling (when there is more than 1 page of images).

    image

    When I look at the line 479 in sliver_waterfall_flow it shows :

    if (data.layoutOffset < -precisionErrorTolerance) {

    If I scroll very fast up and down I get the error and my list of (say) 20 items either gets cleared or goes down to 1 or two items (Only 1 or 2 items are shown).

    My images were small (20k) apart from a few that were very large (5mb). When I remove the large images from the list - I dont get the issue at all.

    Additionally - I am also experiencing jumping of images within the Masonary view.

    opened by sallypeters 3
  • flutter version >=1.17.0

    flutter version >=1.17.0

    Why flutter version must be >= 1.17.0 environment: sdk: ">=2.6.0 <3.0.0" flutter: ">=1.17.0"

    log: depends on flutter_staggered_grid_view >=0.3.2 which requires Flutter SDK version >=1.17.0, version solving failed. pub upgrade failed (1; Because flutter_demo depends on flutter_staggered_grid_view >=0.3.2 which requires Flutter SDK version >=1.17.0, version solving failed.)

    opened by yuhaocan 3
  • using WaterfallFlow with expanded and False shrinkWrap

    using WaterfallFlow with expanded and False shrinkWrap

    in this code i get visible error and how can i have WaterfallFlow into ListView?

    The getter 'visible' was called on null. Receiver: null Tried calling: visible

    class SampleCode extends StatelessWidget {
      List<Color> colors = <Color>[];
    
      @override
      Widget build(BuildContext context) {
        final double screenWidthSize = MediaQuery.of(context).size.width;
    
        return Scaffold(
          appBar: AppBar(
            title: const Text('RandomSized'),
          ),
          body: ListView(
            children: <Widget>[
              Container(
                height: 100.0,
                child: Text('TEST'),
              ),
              LayoutBuilder(
                  builder: (BuildContext context, BoxConstraints constraints){
                    int _crossAxisCount = 0;
                    if (screenWidthSize > 720) {
                      _crossAxisCount = 3;
                    } else if (screenWidthSize > 520) {
                      _crossAxisCount = 2;
                    } else {
                      _crossAxisCount = 1;
                    }
                    return Expanded(
                      child: WaterfallFlow.builder(
                        padding: const EdgeInsets.all(5.0),
                        shrinkWrap: false,
                        gridDelegate: SliverWaterfallFlowDelegateWithFixedCrossAxisCount(
                          crossAxisCount: _crossAxisCount,
                          crossAxisSpacing: 4,
                          mainAxisSpacing: 4,
                        ),
                        itemBuilder: (BuildContext c, int index) {
                          final Color color = getRandomColor(index);
                          return Container(
                            decoration: BoxDecoration(
                                border: Border.all(color: Colors.black),
                                color: getRandomColor(index)),
                            alignment: Alignment.center,
                            child: Text(
                              '$index ' + 'TestString' * 10 * (index % 3 + 1),
                              style: TextStyle(
                                  color: color.computeLuminance() < 0.5
                                      ? Colors.white
                                      : Colors.black),
                            ),
                            //height: ((index % 3) + 1) * 100.0,
                          );
                        },
                        itemCount: 22,
                      ),
                    );
                  }
              )
            ],
          ),
        );
      }
    
      Color getRandomColor(int index) {
        if (index >= colors.length) {
          colors.add(Color.fromARGB(255, Random.secure().nextInt(255),
              Random.secure().nextInt(255), Random.secure().nextInt(255)));
        }
    
        return colors[index];
      }
    }
    
    stack overflow 
    opened by pishguy 3
  • Exception has occurred. StateError (Bad state: No element)

    Exception has occurred. StateError (Bad state: No element)

    I have All exceptions turned on and it always crashes.

    double get maxLeadingLayoutOffset { try { return leadingItems .reduce( // <=================== here (WaterfallFlowParentData curr, WaterfallFlowParentData next) => curr.layoutOffset >= next.layoutOffset ? curr : next) .layoutOffset; } catch (e) { return 0.0; } }

    opened by sgehrman 3
  • 窗口大小改变时的性能问题

    窗口大小改变时的性能问题

    越滚到底部性能越差,似乎窗口大小改变会重建当前位置之前所有的组件 ListView 和 GridView 无此问题

    以下演示运行于 Release 模式

    https://user-images.githubusercontent.com/181192/186556514-6382ecde-30d6-47e7-a939-d56c3a0fad82.mp4

    opened by DemoJameson 1
  • Bad state: No element

    Bad state: No element

    线上出现几百个异常日志,本地测试无法复现。

    872行代码片段截图 image

    堆栈信息: #0 ListMixin.reduce (dart:collection/list.dart:222) #1 _CrossAxisChildrenData.insert (package:waterfall_flow/src/rendering/sliver_waterfall_flow.dart:872) #2 RenderSliverWaterfallFlow.performLayout (package:waterfall_flow/src/rendering/sliver_waterfall_flow.dart:537) #3 RenderObject.layout (package:flutter/src/rendering/object.dart:1915) #4 RenderSliverEdgeInsetsPadding.performLayout (package:flutter/src/rendering/sliver_padding.dart:137) #5 RenderSliverPadding.performLayout (package:flutter/src/rendering/sliver_padding.dart:371) #6 RenderObject.layout (package:flutter/src/rendering/object.dart:1915) #7 RenderViewportBase.layoutChildSequence (package:flutter/src/rendering/viewport.dart:510) #8 RenderViewport._attemptLayout (package:flutter/src/rendering/viewport.dart:1580) #9 RenderViewport.performLayout (package:flutter/src/rendering/viewport.dart:1489) #10 RenderObject._layoutWithoutResize (package:flutter/src/rendering/object.dart:1757) #11 PipelineOwner.flushLayout (package:flutter/src/rendering/object.dart:887) #12 RendererBinding.drawFrame (package:flutter/src/rendering/binding.dart:504) #13 WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:892) #14 RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:370) #15 SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1146) #16 SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1083) #17 SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:997) #18 _rootRun (dart:async/zone.dart:1426) #19 _CustomZone.run (dart:async/zone.dart:1328) #20 _CustomZone.runGuarded (dart:async/zone.dart:1236) #21 _invoke (dart:ui/hooks.dart:151) #22 PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:308) #23 _drawFrame (dart:ui/hooks.dart:115)

    opened by LGang 1
Owner
FlutterCandies
Custom Flutter candies (packages) for you to build your Flutter app easily. Enjoy it!
FlutterCandies
Responsive Sizer helps implement are responsive layout by providing helper widgets and extensions

Responsive Sizer Responsive Sizer helps implement a responsive layout by providing helper widgets and extensions Content Installation Parameters Take

CoderUni 71 Jan 3, 2023
Fluid layouts allows you to create responsive layout for mobile, web and desktop from a single codebase.

Fluid layout aims to help building a responsive experience through all the different screen sizes. Based in the boostrap approach, FluidLayout calculates a padding content (fluid_padding) that changes depending on the parent size. The Fluid widget uses that padding to set its size

Jaime Blasco 3 Jan 10, 2022
A Horizontal List view With Lots of modification including a scaled current item.

Pub.dev Scaled List A Horizontal List view With Lots of modification including a scaled current item. Provided with curved custom painting and Dots in

Hosain Mohamed 35 Nov 5, 2022
A flutter package which makes it easier to display the difference between two images.

?? Before After A flutter package which makes it easier to display the differences between two images.. The source code is 100% Dart, and everything r

Sahil Kumar 741 Dec 30, 2022
An app built using Flutter that holds buttons in form of xylophone which plays as instrument when clicked.

xylophone_flutter A new Flutter application. Getting Started This project is a starting point for a Flutter application. A few resources to get you st

dev_allauddin 3 Feb 3, 2022
Project Flutter which discusses how to create a movie dashboard UI

MOvApps (Flutter Project) Hi everybody. How are you guys? May you always be in good health and of course always be blessed by God! I want to showcase

Aqshal Rizqullah 1 Nov 30, 2021
Find out under which card the Flutter logo is hiding.

Flutter Card Flip Game Find out under which card the Flutter logo is hiding. Game Rules The purpose of this game is for the player to find out under w

Nickolas Chong 0 Dec 30, 2021
An app which has only UI of a multimedia app. Designed with Flutter.

multimedia_app ---ScreenShots--- | | | | Getting Started This project is a starting point for a Flutter application. A few resources to get you starte

Resül Çay 3 Jul 14, 2022
Scratch card widget which temporarily hides content from user.

scratcher Scratch card widget which temporarily hides content from user. Features Android and iOS support Cover content with full color or custom imag

Kamil Rykowski 405 Dec 27, 2022
Allows widgets to be zoomed in and out by inserting a OverlayEntry which allows the widget to be on the front at all times.

zoom_pinch_overlay An instagram style pinch and zoom widget for all platform completely written in pure dart! All other "zoom_pinch" package doesnt di

Samuel 18 Nov 29, 2022
A simple package that provides you with some widgets and cutom clippers which implements the shape of a coupon card.

Coupon UI Kit A simple package that provides you with some widgets and cutom clippers which implements the shape of a coupon card. The example contain

AbdulMuaz Aqeel 15 Dec 20, 2022
Movies App UI in Flutter using Simple Widgets without Using API's in Flutter.

Movies App UI in Flutter using Simple Widgets without Using API's in Flutter.

Habib ullah 3 May 15, 2022
A flutter plugin for Easily make Flutter apps responsive. Automatically adapt UI to different screen sizes. Responsiveness made simple.

A flutter plugin for Easily make Flutter apps responsive. Automatically adapt UI to different screen sizes. Responsiveness made simple.

Urmish Patel 191 Dec 29, 2022
The Coolicons icon pack for Flutter with over 400 icons available for your flutter project.

coolicons This flutter package allows you to use the Coolicons icon pack. Made from Coolicons. ?? Installation In the dependencies: section of your pu

Stephen Joel 1 May 24, 2022
Foody - Flutter project to display foods to clients and display charts and has a lot of features , two flutter apps : Android and Web

Foody Flutter project to display foods to the clients and use charts and use a lot of features to complete the process (HUGE APP) There two apps: Andr

ABDULKARIMALBAIK 1 Feb 7, 2022
Flutter-business-card-app - Flutter + Dart business card mobile app

Dart + Flutter Business Card Mobile Application

Mark Hellner 1 Nov 8, 2022
A Flutter project that gives basic flutter design to implement a login UI

Login UI Design A Flutter project that gives basic flutter design to implement a

CABREX 9 Nov 8, 2022
Flutter Complete E-Commerce app (UI by - 'The Flutter Way')

NOT COMPLETED YET! e_commerce A new Flutter project. Getting Started This project is a starting point for a Flutter application. A few resources to ge

null 1 Mar 8, 2022
Flutter Shop UI - an e-commerce app using Flutter

If you are planning to create an e-commerce app using Flutter then this Shop UI Kit would be the perfect choice for you to make a gorgeous app for both Android & iOS.

Trần Văn Nguyên 21 Nov 21, 2022