Ошибка: у SliverGeometry есть paintOffset, который превышает оставшеесяPaintExtent из ограничений - PullRequest
1 голос
/ 05 августа 2020

Я получаю эту ошибку:

════════ Exception caught by rendering library ═════════════════════════════════
SliverGeometry has a paintOffset that exceeds the remainingPaintExtent from the constraints.
The relevant error-causing widget was
    SliverAppBarLayer

Это происходит каждый раз, когда я прокручиваю его вверх. Ошибка не отображается на экране, только в консоли, что также мешает мне выполнить горячий перезапуск / горячую перезагрузку. Что это означает? Почему это происходит? Как исправить, пожалуйста?

скриншот

enter image description here

my SliverWidget: sliver_app_bar_layer.dart

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';

class SliverAppBarLayer extends SingleChildRenderObjectWidget {
  SliverAppBarLayer({Widget child, Key key}) : super(child: child, key: key);
  @override
  RenderObject createRenderObject(BuildContext context) {
    return RenderSliverAppBarLayer();
  }
}

class RenderSliverAppBarLayer extends RenderSliverToBoxAdapter {
  RenderSliverAppBarLayer({
    RenderBox child,
  }) : super(child: child);

  @override
  void performResize() {}

  @override
  void performLayout() {
    if (child == null) {
      geometry = SliverGeometry.zero;
      return;
    }
    final SliverConstraints constraints = this.constraints;
    child.layout(constraints.asBoxConstraints(/* crossAxisExtent: double.infinity */), parentUsesSize: true);
    double childExtent;
    switch (constraints.axis) {
      case Axis.horizontal:
        childExtent = child.size.width;
        break;
      case Axis.vertical:
        childExtent = child.size.height;
        break;
    }
    assert(childExtent != null);
    final double paintedChildSize = calculatePaintOffset(constraints, from: 0.0, to: childExtent);
    final double cacheExtent = calculateCacheOffset(constraints, from: 0.0, to: childExtent);

    assert(paintedChildSize.isFinite);
    assert(paintedChildSize >= 0.0);
    geometry = SliverGeometry(
      scrollExtent: 0,
      paintExtent: childExtent,
      paintOrigin: constraints.scrollOffset,
      cacheExtent: cacheExtent,
      maxPaintExtent: childExtent,
      hitTestExtent: paintedChildSize,
    );
    setChildParentData(child, constraints, geometry);
  }
}

main.dart

import 'package:flutter/material.dart';
import 'theme/style_constants.dart';
import 'widgets/sliver_app_bar_layer.dart';

void main() {
 runApp(MyApp());
}

class MyApp extends StatelessWidget {
 @override
 Widget build(BuildContext context) {
   return MaterialApp(
     theme: ThemeData(
       primarySwatch: Colors.teal,
       canvasColor: Colors.transparent,
     ),
     home: DemoScreen(),
   );
 }
}

class DemoScreen extends StatelessWidget {
 static String id = '/demo';

 int numberOfColumns(dynamic context) => ((MediaQuery.of(context).size.width - (2 * kBigBoxPadding)) / kMaxCrossAxisExtent).floor();

 // Widget _buildGrid() => GridView.extent(
 //     maxCrossAxisExtent: kMaxCrossAxisExtent,
 //     padding: const EdgeInsets.all(4),
 //     mainAxisSpacing: 4,
 //     crossAxisSpacing: 4,
 //     children: _buildGridTileList(500));

 List<Container> _buildGridTileList(dynamic context, int count) => List.generate(
     count,
     (i) => Container(
           //NOTE: workaround according to: https://github.com/flutter/flutter/issues/25009
           decoration: BoxDecoration(
             color: colorBackground, //the color of the main container
             border: Border.all(
               //apply border to only that side where the line is appearing i.e. top | bottom | right | left.
               width: 4, //depends on the width of the unintended line
               color: colorBackground,
             ),
           ),
           child: Container(
             decoration: BoxDecoration(
               color: colorBackground,
             ),

             child: Center(
               child: Text(
                 '$i / ${numberOfColumns(context)}',
                 style: TextStyle(color: Colors.grey),
                 //textAlign: TextAlign.center,
               ),
             ),
             //margin: EdgeInsets.all(0),
           ),
         ));

 // List<Widget> tabbarViewItems() {
 //   List<Widget> items = [];
 //   for (int i = 0; i < 25; i++) {
 //     Widget listView = _buildGrid();
 //     items.add(listView);
 //   }
 //   return items;
 // }

 List<Widget> listViewItems() {
   List<Widget> items = [];

   for (int i = 0; i < 500; i++) {
     Widget widgetItem = Text(
       'item $i',
       textAlign: TextAlign.center,
       style: TextStyle(color: Colors.white),
     );
     items.add(widgetItem);
   }
   return items;
 }

 @override
 Widget build(BuildContext context) {
   return DefaultTabController(
     length: 25,
     child: Scaffold(
       backgroundColor: colorBackground,
       //floatingActionButton: MyTabBar(),
       floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
       body: Stack(
         children: [
           Container(
             width: double.infinity,
             color: Colors.amber,
             child: Image.network(
               'https://images.unsplash.com/photo-1517248135467-4c7edcad34c4?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2700&q=80',
               fit: BoxFit.cover,
               height: MediaQuery.of(context).size.height * kCoverHeightProportion,
             ),
             //color: Colors.green,
           ),
           Align(
             alignment: Alignment.bottomCenter,
             child: Container(
               height: 40,
               width: 300,
               color: Colors.red,
             ),
           ),
           Align(
             alignment: Alignment.bottomCenter,
             child: Container(
               margin: EdgeInsets.only(left: kBigBoxPadding, right: kBigBoxPadding, top: kBigBoxPadding, bottom: kBottomBigBoxPadding),

               //width: MediaQuery.of(context).size.width * 0.9,
               //margin: EdgeInsets.symmetric(horizontal: kBigBoxPadding),
               decoration: BoxDecoration(
                 //color: Colors.pink,
                 borderRadius: BorderRadius.all(Radius.circular(30)),
               ),
               child: ClipRRect(
                 borderRadius: BorderRadius.all(Radius.circular(30)),
                 child: CustomScrollView(
                   //physics: FixedExtentScrollPhysics(),
                   anchor: kCoverHeightProportion *
                       kCoverHeightProportion *
                       MediaQuery.of(context).size.height /
                       (kCoverHeightProportion * (MediaQuery.of(context).size.height - kBigBoxPadding - kBottomBigBoxPadding)),
                   slivers: [
                     SliverAppBarLayer(
                       child: Container(
                         width: double.infinity,
                         height: 100,
                         decoration: BoxDecoration(
                             color: colorBackground, borderRadius: BorderRadius.only(topLeft: Radius.circular(30), topRight: Radius.circular(30))),
                         child: Center(
                           child: Text(
                             'La casa de don Juan',
                             style: TextStyle(color: colorPrimary1, fontSize: 32, fontWeight: FontWeight.w800),
                           ),
                         ),
                       ),
                     ),
                     SliverGrid.extent(
                       maxCrossAxisExtent: kMaxCrossAxisExtent,
                       childAspectRatio: 1,
                       mainAxisSpacing: 0,
                       crossAxisSpacing: 0,
                       children: _buildGridTileList(context, 250),
                     ),
                   ],
                 ),
               ),
             ),
           ),
         ],
       ),
     ),
   );
 }
}

style_constants.dart

import 'package:flutter/material.dart';

const Color colorShade1 = Color(0xFFEFF0F2);
const Color colorShade2 = Color(0xFF777777);
const Color colorShade3 = Color(0xFF424242);
const Color colorShade4 = Color(0xFF4B4935);
const Color colorShade5 = Color(0xFF3D2916);
const Color colorShade6 = Color(0xFF1D1C0A);

const Color colorBackground = Color(0xFF101A24);
const Color colorPrimary1 = Color(0xFFCC9757);

const double kTabIconHeight = 28;
const double kCoverHeightProportion = 0.35;
const double kBigBoxPadding = 8;
const double kBottomBigBoxPadding = 60;
const double kMaxCrossAxisExtent = 150;

1 Ответ

1 голос
/ 10 августа 2020

Просто используйте подготовленный SliverPersistentHeaderDelegate, он работает из коробки ...

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        primarySwatch: Colors.teal,
        canvasColor: Colors.transparent,
      ),
      home: DemoScreen(),
    );
  }
}

class DemoScreen extends StatelessWidget {
  static String id = '/demo';

  int numberOfColumns(dynamic context) =>
      ((MediaQuery.of(context).size.width - (2 * kBigBoxPadding)) /
              kMaxCrossAxisExtent)
          .floor();

  // Widget _buildGrid() => GridView.extent(
  //     maxCrossAxisExtent: kMaxCrossAxisExtent,
  //     padding: const EdgeInsets.all(4),
  //     mainAxisSpacing: 4,
  //     crossAxisSpacing: 4,
  //     children: _buildGridTileList(500));

  List<Container> _buildGridTileList(dynamic context, int count) =>
      List.generate(
          count,
          (i) => Container(
                //NOTE: workaround according to: https://github.com/flutter/flutter/issues/25009
                decoration: BoxDecoration(
                  color: colorBackground, //the color of the main container
                  border: Border.all(
                    //apply border to only that side where the line is appearing i.e. top | bottom | right | left.
                    width: 4, //depends on the width of the unintended line
                    color: colorBackground,
                  ),
                ),
                child: Container(
                  decoration: BoxDecoration(
                    color: colorBackground,
                  ),

                  child: Center(
                    child: Text(
                      '$i / ${numberOfColumns(context)}',
                      style: TextStyle(color: Colors.grey),
                      //textAlign: TextAlign.center,
                    ),
                  ),
                  //margin: EdgeInsets.all(0),
                ),
              ));

  // List<Widget> tabbarViewItems() {
  //   List<Widget> items = [];
  //   for (int i = 0; i < 25; i++) {
  //     Widget listView = _buildGrid();
  //     items.add(listView);
  //   }
  //   return items;
  // }

  List<Widget> listViewItems() {
    List<Widget> items = [];

    for (int i = 0; i < 500; i++) {
      Widget widgetItem = Text(
        'item $i',
        textAlign: TextAlign.center,
        style: TextStyle(color: Colors.white),
      );
      items.add(widgetItem);
    }
    return items;
  }

  @override
  Widget build(BuildContext context) {
    var topPadding = kCoverHeightProportion *
        kCoverHeightProportion *
        MediaQuery.of(context).size.height /
        (kCoverHeightProportion *
            (MediaQuery.of(context).size.height -
                kBigBoxPadding -
                kBottomBigBoxPadding));
    return DefaultTabController(
      length: 25,
      child: Scaffold(
        backgroundColor: colorBackground,
        //floatingActionButton: MyTabBar(),
        floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
        body: Stack(
          children: [
            Container(
              width: double.infinity,
              color: Colors.amber,
              child: Image.network(
                'https://images.unsplash.com/photo-1517248135467-4c7edcad34c4?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2700&q=80',
                fit: BoxFit.cover,
                height:
                    MediaQuery.of(context).size.height * kCoverHeightProportion,
              ),
              //color: Colors.green,
            ),
            Align(
              alignment: Alignment.bottomCenter,
              child: Container(
                height: 40,
                width: 300,
                color: Colors.red,
              ),
            ),
            Align(
              alignment: Alignment.bottomCenter,
              child: Container(
                margin: EdgeInsets.only(
                    left: kBigBoxPadding,
                    right: kBigBoxPadding,
                    top: kBigBoxPadding,
                    bottom: kBottomBigBoxPadding),

                //width: MediaQuery.of(context).size.width * 0.9,
                //margin: EdgeInsets.symmetric(horizontal: kBigBoxPadding),
                decoration: BoxDecoration(
                  //color: Colors.pink,
                  borderRadius: BorderRadius.all(Radius.circular(30)),
                ),
                child: ClipRRect(
                  borderRadius: BorderRadius.all(Radius.circular(30)),
                  child: CustomScrollView(
                    //physics: FixedExtentScrollPhysics(),
                    anchor: topPadding,
                    slivers: [
                      SliverPadding(
                        padding: EdgeInsets.only(
                          top: topPadding,
                        ),
                        sliver: SliverPersistentHeader(
                          pinned: true,
                          floating: false,
                          delegate: _SliverPersistentHeaderDelegate(
                            Container(
                              width: double.infinity,
                              height: 100,
                              decoration: BoxDecoration(
                                  color: colorBackground,
                                  borderRadius: BorderRadius.only(
                                      topLeft: Radius.circular(30),
                                      topRight: Radius.circular(30))),
                              child: Center(
                                child: Text(
                                  'La casa de don Juan',
                                  style: TextStyle(
                                      color: colorPrimary1,
                                      fontSize: 32,
                                      fontWeight: FontWeight.w800),
                                ),
                              ),
                            ),
                          ),
                        ),
                      ),
                      SliverGrid.extent(
                        maxCrossAxisExtent: kMaxCrossAxisExtent,
                        childAspectRatio: 1,
                        mainAxisSpacing: 0,
                        crossAxisSpacing: 0,
                        children: _buildGridTileList(context, 250),
                      ),
                    ],
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

const Color colorShade1 = Color(0xFFEFF0F2);
const Color colorShade2 = Color(0xFF777777);
const Color colorShade3 = Color(0xFF424242);
const Color colorShade4 = Color(0xFF4B4935);
const Color colorShade5 = Color(0xFF3D2916);
const Color colorShade6 = Color(0xFF1D1C0A);

const Color colorBackground = Color(0xFF101A24);
const Color colorPrimary1 = Color(0xFFCC9757);

const double kTabIconHeight = 28;
const double kCoverHeightProportion = 0.35;
const double kBigBoxPadding = 8;
const double kBottomBigBoxPadding = 60;
const double kMaxCrossAxisExtent = 150;

class _SliverPersistentHeaderDelegate extends SliverPersistentHeaderDelegate {
  _SliverPersistentHeaderDelegate(this.child);

  final Widget child;

  @override
  Widget build(
      BuildContext context, double shrinkOffset, bool overlapsContent) {
    return child;
  }

  @override
  double get maxExtent => 100;

  @override
  double get minExtent => 100;

  @override
  bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) => false;
}
...